diff --git a/.gitattributes b/.gitattributes index db32d91e5..347831875 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,7 @@ *.bin filter=lfs diff=lfs merge=lfs -text *.gif filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text +*.ktx2 filter=lfs diff=lfs merge=lfs -text +*.ktx filter=lfs diff=lfs merge=lfs -text +*.bytes filter=lfs diff=lfs merge=lfs -text +*.webp filter=lfs diff=lfs merge=lfs -text diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5de3b5b05..38c2041a3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -16,7 +16,8 @@ Attach or link to *.gltf/*.glb files that trigger the bug. In addition, make sure to run those files through the [glTF Validator](https://github.khronos.org/glTF-Validator) first. If you encounter errors or warnings, try to make sure they are not responsible for the issue and file a bug report with the software that generated the glTF file as well. -> Note: You have to ZIP archive them first in order for GitHub to accept the upload. +> [!TIP] +> You have to ZIP archive them first in order for GitHub to accept the upload. If your files are confidential: diff --git a/.github/codecov.yml b/.github/codecov.yml deleted file mode 100644 index 9d0b09f70..000000000 --- a/.github/codecov.yml +++ /dev/null @@ -1,36 +0,0 @@ -codecov: - require_ci_to_pass: false - notify: - wait_for_ci: true - -coverage: - precision: 2 - round: down - range: "50...70" - status: - patch: true - default_rules: - flag_coverage_not_uploaded_behavior: exclude - project: - default: - target: auto - # Threshold used for the PR Check - threshold: 0.5% - base: auto - if_ci_failed: success - informational: false - only_pulls: true - -# PR Comment configuration -comment: - layout: "reach,diff,flags,files" - behavior: default - require_changes: false - require_base: false - require_head: false - # Set this to the number of coverage jobs run in the PR - after_n_builds: 4 - -flag_management: - default_rules: - carryforward: true \ No newline at end of file diff --git a/.github/contributing.md b/.github/contributing.md new file mode 100644 index 000000000..3933b6b78 --- /dev/null +++ b/.github/contributing.md @@ -0,0 +1,3 @@ +# Contributing + +This repository is a mirror/read-only. Please contribute to Unity's fork at diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..1a2fc4a9e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,2 @@ +> [!IMPORTANT] +> Please submit contributions to instead. This repository is a mirror/read-only. diff --git a/.github/workflows/close-pull-request.yml b/.github/workflows/close-pull-request.yml new file mode 100644 index 000000000..fcdf6e8e9 --- /dev/null +++ b/.github/workflows/close-pull-request.yml @@ -0,0 +1,25 @@ +name: Close pull request +on: + pull_request_target: + types: [opened] + +jobs: + close: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + 👋 Thanks for opening a pull request! + + Unfortunately contributions are only accepted on Unity's fork. + + Please resubmit your changes here instead: + 👉 + + > [!NOTE] + > Unity's fork is structured as a [monorepo](https://en.wikipedia.org/wiki/Monorepo), so you need to move your changes into the appropriate subfolder (`Packages/com.unity.cloud.gltfast`). + + Thank you! 🙏 diff --git a/.gitignore b/.gitignore index 27e6f29b2..d5feb5030 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ Assets/AssetStoreTools* .DS_Store +# GitHub Action artifacts +.tmp-* + # Visual Studio cache directory /.vs/ /.vscode/ @@ -14,9 +17,9 @@ Assets/AssetStoreTools* # Autogenerated VS/MD/Consulo solution and project files ExportedObj/ .consulo/ -*.csproj +Projects/**/*.csproj *.unityproj -*.sln +Projects/**/*.sln *.suo *.tmp *.user @@ -39,3 +42,34 @@ sysinfo.txt # Rider **/.idea + +# Unity tooling +/upm-ci~ +/test-results~ +/pvp-results + +# glTFast test projects +/Projects/*/ProjectSettings/* +!Projects/*/ProjectSettings/ProjectSettings.asset +!Projects/*/ProjectSettings/ProjectVersion.txt +!Projects/*/ProjectSettings/GraphicsSettings.asset +!Projects/*/ProjectSettings/HDRPProjectSettings.asset +/Projects/*/UserSettings +/Projects/*/Assets/Resources* +/Projects/*/Assets/StreamingAssets* +/Projects/*/Packages/packages-lock.json +/Projects/*/Logs + +# CI Tools +Tools/CI/bin + +# Graphify +graphify-out/.graphify_* +graphify-out/cache +graphify-out/cost.json +graphify-out/graph.html +graphify-out/manifest.json + +# Claude Code +.claude/worktrees +.claude/settings.local.json diff --git a/.yamato/code-format-check.yml b/.yamato/code-format-check.yml deleted file mode 100644 index 977bed579..000000000 --- a/.yamato/code-format-check.yml +++ /dev/null @@ -1,15 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- -code_format_check: - name : Code Format check - agent: -{% assign agent = agents.ubuntu-small -%} - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - commands: - - > - GIT_CLONE_PROTECTION_ACTIVE=false - git clone --depth 1 --branch stable https://github.cds.internal.unity3d.com/unity/unity-meta.git - - mv unity-meta ~ - - perl ~/unity-meta/Tools/Format/format.pl --showfiles --dry-run . diff --git a/.yamato/package-pack.yml b/.yamato/package-pack.yml deleted file mode 100644 index 5b276a6c1..000000000 --- a/.yamato/package-pack.yml +++ /dev/null @@ -1,26 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- -pack: - name: Pack - agent: -{% assign agent = agents.ubuntu -%} - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - commands: - - | - mkdir Packages - pushd Packages - git clone {% if agent.os == "win" %}"%GIT_REPOSITORY_URL%"{% else %}"$GIT_REPOSITORY_URL"{% endif %} --no-checkout gltfast - cd gltfast - git fetch origin {% if agent.os == "win" %}"%GIT_REVISION%"{% else %}"$GIT_REVISION"{% endif %} - git checkout -f --detach {% if agent.os == "win" %}"%GIT_REVISION%"{% else %}"$GIT_REVISION"{% endif %} - popd - - npm install upm-ci-utils@stable -g --registry {{ registry.npm }} - - upm-ci package pack --package-path Packages/gltfast - artifacts: - packages: - paths: - - "upm-ci~/packages/**/*" diff --git a/.yamato/package-player-test.yml b/.yamato/package-player-test.yml deleted file mode 100644 index 062f8adbe..000000000 --- a/.yamato/package-player-test.yml +++ /dev/null @@ -1,187 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- -{% for editor in player_test_editors -%} -{% for platform in player_test_platforms -%} -{% if platform.build -%} -{% assign agent = agents[platform.build] -%} -{% if agent.os == "win" -%}{% assign os = os_variables.win -%}{% else -%}{% assign os = os_variables.unix -%}{% endif -%} -build_{{ platform.name }}_{{ editor.version }}: - name : Build {{ editor.version }} {{ platform.name }} Player - agent: - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - - npm install upm-ci-utils@stable -g --registry {{ registry.npm }} - - | -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" -{% endif -%} - upm-ci package test -u {{ editor.version }} --platform {{ platform.id }} {% if platform.upm_ci_params %}{{ platform.upm_ci_params }}{% endif %} --package-path Packages/gltfast --extra-create-project-arg=-upmNoDefaultPackages --player-build-path upm-ci~/player/{{ platform.id }} --build-only - artifacts: - logs: - paths: - - "**/*.log" - player: - paths: - - "upm-ci~/player/{{ platform.id }}/**" - test-results: - paths: - - "**/test-results/**" - dependencies: - - .yamato/package-pack.yml#pack -{% endif -%} - -{% if platform.run -%} -{% assign agent = agents[platform.run] -%} -{% if agent.os == "win" -%}{% assign os = os_variables.win -%}{% else -%}{% assign os = os_variables.unix -%}{% endif -%} -run_{{ platform.name }}_{{ editor.version }}: - name : Run {{ editor.version }} {{ platform.name }} Player Tests - agent: - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - npm install upm-ci-utils@stable -g --registry {{ registry.npm }} - - | -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" -{% endif -%} - upm-ci package test -u {{ editor.version }} --platform {{ platform.id }} --player-build-path upm-ci~/player/{{ platform.id }} --package-path Packages/gltfast --extra-create-project-arg=-upmNoDefaultPackages - artifacts: - logs: - paths: - - "**/*.log" - test-results: - paths: - - "**/test-results/**" - dependencies: - - .yamato/package-pack.yml#pack - - .yamato/package-player-test.yml#build_{{ platform.name }}_{{ editor.version }} -{% endif -%} - -{% if platform.build_and_run -%} -{% assign agent = agents[platform.build_and_run] -%} -{% if agent.os == "win" -%}{% assign os = os_variables.win -%}{% else -%}{% assign os = os_variables.unix -%}{% endif -%} -build_and_run_{{ platform.name }}_{{ editor.version }}: - name : Build and run {{ editor.version }} {{ platform.name }} Player Tests - agent: - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - - npm install upm-ci-utils@stable -g --registry {{ registry.npm }} - - | -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" -{% endif -%} - upm-ci package test -u {{ editor.version }} --platform {{ platform.id }} --package-path Packages/gltfast --extra-create-project-arg=-upmNoDefaultPackages - artifacts: - logs: - paths: - - "**/*.log" - test-results: - paths: - - "**/test-results/**" - dependencies: - - .yamato/package-pack.yml#pack -{% endif -%} -{% endfor -%} -{% endfor -%} - -player_test_all: - name: _Player Tests All - dependencies: -{% for editor in player_test_editors -%} -{% for platform in player_test_platforms -%} -{% if platform.run -%} - - .yamato/package-player-test.yml#run_{{ platform.name }}_{{ editor.version }} -{% elsif platform.build_and_run -%} - - .yamato/package-player-test.yml#build_and_run_{{ platform.name }}_{{ editor.version }} -{% endif -%} -{% endfor -%} -{% endfor -%} - -player_test_pr: - name: _Player Test subset for PRs - dependencies: -{% for platform in player_test_platforms -%} -{% assign editor_index = forloop.index0 | modulo: player_test_editors.size -%} -{% assign editor = player_test_editors[editor_index] -%} -{% if platform.run -%} - - .yamato/package-player-test.yml#run_{{ platform.name }}_{{ editor.version }} -{% elsif platform.build_and_run -%} - - .yamato/package-player-test.yml#build_and_run_{{ platform.name }}_{{ editor.version }} -{% endif -%} -{% endfor -%} diff --git a/.yamato/package-publish.yml b/.yamato/package-publish.yml deleted file mode 100644 index d89c45df0..000000000 --- a/.yamato/package-publish.yml +++ /dev/null @@ -1,74 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- -{% assign os = os_variables.unix -%} -{% assign agent = agents.ubuntu-small -%} - -publish_dry_run: - name: Dry Run Publish to Internal Registry - agent: - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - npm install upm-ci-utils@stable -g --registry {{ registry.npm }} - - upm-ci package publish --package-path Packages/gltfast --dry-run - triggers: - tags: - only: - - /^[Rr][Cc]-(0\.\d+\.\d+|[1-9]\d*\.\d+\.\d+(-preview(\.\d+)?|-exp(\.\d+|-\w+\.\d+)|-pre\.\d+)?)$/ - artifacts: - artifacts: - paths: - - "upm-ci~/packages/*.tgz" - logs: - paths: - - "upm-ci~/upm-ci.log" - dependencies: - - .yamato/package-pack.yml#pack - - .yamato/package-test.yml#tests_all - - -publish: - name: Publish to Internal Registry - agent: -{% assign agent = agents.ubuntu-small -%} - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - npm install upm-ci-utils@stable -g --registry {{ registry.npm }} - - upm-ci package publish --package-path Packages/gltfast - triggers: - tags: - only: - - /^[Rr][Cc]-(0\.\d+\.\d+|[1-9]\d*\.\d+\.\d+(-preview(\.\d+)?|-exp(\.\d+|-\w+\.\d+)|-pre\.\d+)?)$/ - artifacts: - artifacts: - paths: - - "upm-ci~/packages/*.tgz" - logs: - paths: - - "upm-ci~/upm-ci.log" - dependencies: - - .yamato/package-pack.yml#pack - - .yamato/package-test.yml#tests_all diff --git a/.yamato/package-test.yml b/.yamato/package-test.yml deleted file mode 100644 index da7f94230..000000000 --- a/.yamato/package-test.yml +++ /dev/null @@ -1,160 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- - -{% for editor in editor_versions -%} -{% for platform in test_platforms -%} -{% assign agent = agents[platform.agent] -%} -{% if agent.os == "win" -%}{% assign os = os_variables.win -%}{% else -%}{% assign os = os_variables.unix -%}{% endif -%} -test_{{ platform.name }}_{{ editor }}: - name : Test {{ editor }} on {{ platform.name }} - agent: - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - variables: - UPMCI_PKG: "upm-ci-utils@stable" - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - - npm install {% if agent.os == "win" %}"%UPMCI_PKG%"{% else %}"$UPMCI_PKG"{% endif %} -g --registry {{ registry.npm }} - - > -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" -{% endif -%} - - upm-ci package test - -u {{ editor }} - --package-path Packages/gltfast - --type package-tests - --extra-create-project-arg=-upmNoDefaultPackages - --extra-utr-arg='--category="{{ test_categories }}"' - - artifacts: - logs: - paths: - - "upm-ci~/test-results/**/*" - - "upm-ci~/upm-ci.log" - dependencies: - - .yamato/package-pack.yml#pack - -{% endfor -%} -{% endfor -%} - -# Validate the package on each editor version and each platform -# Validation only occurs in editmode. -{% for editor in editor_versions -%} -{% for platform in test_platforms -%} -{% assign agent = agents[platform.agent] -%} -{% if agent.os == "win" -%}{% assign os = os_variables.win -%}{% else -%}{% assign os = os_variables.unix -%}{% endif -%} -validate_{{ platform.name }}_{{ editor }}: - name : Validate {{ editor }} on {{ platform.name }} - agent: - type: {{ agent.type }} - image: {{ agent.image }} - flavor: {{ agent.flavor}} - source: - skip_checkout: true - variables: - UPMCI_PKG: "upm-ci-utils@stable" - commands: - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - - npm install {% if agent.os == "win" %}"%UPMCI_PKG%"{% else %}"$UPMCI_PKG"{% endif %} -g --registry {{ registry.npm }} - - > -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" -{% endif -%} - - upm-ci package test - -u {{ editor }} - --package-path Packages/gltfast - --type vetting-tests - --platform editmode - --extra-create-project-arg=-upmNoDefaultPackages - --extra-utr-arg='--category="{{ test_categories }}"' - - artifacts: - logs: - paths: - - "upm-ci~/test-results/**/*" - - "upm-ci~/upm-ci.log" - dependencies: - - .yamato/package-pack.yml#pack -{% endfor -%} -{% endfor -%} - - -tests_all: - name: _Test All - dependencies: -{% for editor in editor_versions -%} -{% for platform in test_platforms -%} - - .yamato/package-test.yml#test_{{platform.name}}_{{editor}} - - .yamato/package-test.yml#validate_{{platform.name}}_{{editor}} -{% endfor -%} -{% endfor -%} - -tests_pr: - name: _Test subset for PRs - dependencies: -{% for editor in editor_versions limit: 1 -%} -{% for platform in test_platforms limit: 1 -%} - # First(oldest) editor, first(most important) platform - - .yamato/package-test.yml#test_{{platform.name}}_{{editor}} - - .yamato/package-test.yml#validate_{{platform.name}}_{{editor}} -{% endfor -%} -{% endfor -%} -{% for platform in test_platforms limit: 1 offset: continue -%} - # Newest editor, next(second) platform - - .yamato/package-test.yml#test_{{platform.name}}_{{editor_versions[-1]}} - - .yamato/package-test.yml#validate_{{platform.name}}_{{editor_versions[-1]}} -{% endfor -%} -{% for editor in editor_versions limit: 1 offset: continue -%} -{% for platform in test_platforms limit: 1 offset: continue -%} - # Next(second) editor, next(third) platform - - .yamato/package-test.yml#test_{{platform.name}}_{{editor}} - - .yamato/package-test.yml#validate_{{platform.name}}_{{editor}} -{% endfor -%} -{% endfor -%} diff --git a/.yamato/package.metafile b/.yamato/package.metafile deleted file mode 100644 index 310038f62..000000000 --- a/.yamato/package.metafile +++ /dev/null @@ -1,228 +0,0 @@ -test_setups: - # Project profile name - # see GLTFast.Editor.Tests.SetupProject.ApplySetup (Tests/Editor/SetupProject.cs) for details - - project_setup: default - # # Use to limit versions - # editor_versions: [2020,2021,2022,6000] - # # Use to limit to platforms - # platforms: [win,mac,ubuntu] - pr_test_subset: - - platform: win - editor: 2020 - - platform: mac - editor: 6000 - - platform: win - editor: 2022 - pr_build_subset: - - platform: mac - editor: 2022 - coverage_subset: - # default for coverage: windows + current LTS - - platform: win - editor: 2022 - - project_setup: minimalistic - editor_versions: [2020,2022,6000] - platforms: [win] - pr_test_subset: - - platform: win - editor: 2022 - pr_build_subset: - - platform: win - editor: 2022 - coverage_subset: - # default for coverage: windows + current LTS - - platform: win - editor: 2022 - - project_setup: all_defines - render_pipeline: URP-Forward - utr_timeout: 1200 - editor_versions: [2020,2021,2022,6000] - platforms: [win] - pr_test_subset: - - platform: win - editor: 2022 - # TODO: Move those to `urp` and `hdrp` test setup at some point - # For URP/shader graph test all versions - - platform: win - editor: 2020 - - platform: win - editor: 2021 - - platform: win - editor: 6000 - pr_build_subset: - - platform: win - editor: 6000 - coverage_subset: - # default for coverage: windows + current LTS - - platform: win - editor: 2022 - - project_setup: hdrp - render_pipeline: HDRP-Deferred - utr_timeout: 3600 - agent_xlarge_required: !!bool true - gpu_required: !!bool true - editor_versions: [2022,6000] - platforms: [win] - pr_test_subset: - - platform: win - editor: 2022 - coverage_subset: - # default for coverage: windows + current LTS - - platform: win - editor: 2022 - -editor_versions: - - 2020 - - 2021 - - 2022 - - 6000 - # - trunk - -platforms: - win: - test: win - build_and_run: win - platform: StandaloneWindows64 - component: il2cpp - mac: - test: mac - build_and_run: mac - platform: StandaloneOSX - component: il2cpp - ubuntu: - test: ubuntu - platform: StandaloneLinux64 - component: il2cpp - android: - build: win - run: samsung - component: Android - -test_platforms: - - name: win - agent: win - - name: mac - agent: mac - - name: ubuntu - agent: ubuntu - -player_test_editors: - - version: 2020.3 - - version: 6000 - -player_test_platforms: - - name: win - id: standalone - build_and_run: win - - name: mac - id: standalone - build_and_run: mac - - name: android - id: android - upm_ci_params: --backend=Il2Cpp - build: win - run: shield - # - name: ios - # id: ios - # build: mac-intel - # run: mac-iphone - -asset_sets: - - name: glTF-test-models - git_uri: https://github.com/atteneder/glTF-test-models.git - git_revision: fee92e61a93546e48a34773cc8d2f20db7e22873 - - name: glTF-Sample-Assets - git_uri: https://github.com/KhronosGroup/glTF-Sample-Assets.git - git_revision: cfbe2f9ac259490855940ff85feb5b4b02386046 - -agents: - win: - os: win - type: Unity::VM - gpu_type: Unity::VM::GPU - image: package-ci/win10:v4 - flavor: b1.large - flavor_xlarge: b1.xlarge - mac: - os: mac - type: Unity::VM::osx - image: package-ci/macos-13:v4 - flavor: m1.mac - flavor_xlarge: m1.mac - ubuntu: - os: linux - type: Unity::VM - gpu_type: Unity::VM::GPU - image: package-ci/ubuntu-22.04:v4 - flavor: b1.large - flavor_xlarge: b1.xlarge - samsung: - os: win - type: Unity::mobile::samsung - image: package-ci/win10:v4 - flavor: b1.large - flavor_xlarge: b1.xlarge - shield: - os: win - type: Unity::mobile::shield - image: package-ci/win10:v4 - flavor: b1.large - flavor_xlarge: b1.xlarge - mac-intel: - os: mac - type: Unity::VM::osx - image: package-ci/macos-13:v4 - flavor: b1.large - flavor_xlarge: b1.xlarge - mac-iphone: - os: mac - type: Unity::mobile::iPhone - image: package-ci/macos-13:v4 - flavor: b1.large - flavor_xlarge: b1.xlarge - ubuntu-small: - os: linux - type: Unity::VM - image: package-ci/ubuntu-22.04:v4 - flavor: b1.small - flavor_xlarge: b1.xlarge - -test_framework: com.unity.test-framework@1.4.3 - -# Note: Newtonsoft JSON and UnityWebRequestTexture are dependencies of the package tests (not the package itself) -# TODO: Auto-add test dependencies (Tests/.tests.json) in project setups for tests -test_dependencies: - - id: com.unity.nuget.newtonsoft-json - version: 3.2.1 - - id: com.unity.modules.unitywebrequesttexture - version: 1.0.0 - -registry: - npm: https://artifactory.prd.it.unity3d.com/artifactory/api/npm/upm-npm - homebrew: "git@github.cds.internal.unity3d.com:unity/homebrew-unity.git" - artifactory: https://artifactory.prd.cds.internal.unity3d.com/artifactory - -generic_project_path: Projects/TestProject -test_categories: "!Performance" - -# Operating system specific variables -os_variables: - # Unix (macOS and Ubuntu) - unix: - yamato_source_dir: ${YAMATO_SOURCE_DIR} - git_url: ${GIT_REPOSITORY_URL} - git_revision: ${GIT_REVISION} - tool_utr: "./utr" - bokken_host_ip: ${BOKKEN_HOST_IP} - # Windows specific - win: - yamato_source_dir: "%YAMATO_SOURCE_DIR%" - git_url: "%GIT_REPOSITORY_URL%" - git_revision: "%GIT_REVISION%" - tool_utr: "utr.bat" - bokken_host_ip: "%BOKKEN_HOST_IP%" - -editor_location: - win: "\\.Editor\\Unity.exe" - mac: "/.Editor/Unity.app/Contents/MacOS/Unity" - ubuntu: "/.Editor/Unity" diff --git a/.yamato/project-test.yml b/.yamato/project-test.yml deleted file mode 100644 index d7baf6bce..000000000 --- a/.yamato/project-test.yml +++ /dev/null @@ -1,697 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- -{% assign job_project_path = generic_project_path -%} - -{% for test_setup in test_setups -%} -{% if test_setup.editor_versions -%} - {% assign editor_versions = test_setup.editor_versions -%} -{% endif -%} - -{% if test_setup.platforms -%} - {% assign platform_ids = test_setup.platforms -%} -{% else -%} - {% assign platform_ids = '' -%} - {% for p in platforms -%} - {% assign platform_ids = platform_ids | append: p[0] | append: ',' -%} - {% endfor -%} - {% assign platform_ids = platform_ids | split: ',' -%} -{% endif -%} - -{% for editor in editor_versions -%} -{% for platform_id in platform_ids -%} -{% assign platform = platforms[platform_id] -%} - -{% assign is_coverage_set = false -%} -{% for coverage_set in test_setup.coverage_subset -%} - {% if coverage_set.platform == platform_id and coverage_set.editor == editor -%} - {% assign is_coverage_set = true -%} - {% break -%} - {% endif -%} -{% endfor -%} - -{% capture job_artifacts -%} - artifacts: - logs: - paths: - - "test-results~/**/*" - Project: - paths: - - "{{ job_project_path }}/Packages/*.json" - - "{{ job_project_path }}/ProjectSettings/*.asset" - - "{{ job_project_path }}/Logs/*"{% endcapture -%} - -{% if platform.test -%} -{% assign agent = agents[platform.test] -%} -{% case agent.os -%} - {% when "win" -%} - {% assign os = os_variables.win -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.win -%} - {% when "mac" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.mac -%} - {% when "linux" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.ubuntu -%} - {% else -%} - Platform {{ platform.test }} has unknown OS! -{% endcase -%} - -test_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }}: - name : Test {{ test_setup.project_setup }} with {{ editor }} on {{ platform_id }} - agent: - type: {% if test_setup.gpu_required %}{{ agent.gpu_type}}{% else %}{{ agent.type}}{% endif %} - image: {{ agent.image }} - flavor: {% if test_setup.agent_xlarge_required %}{{ agent.flavor_xlarge}}{% else %}{{ agent.flavor}}{% endif %} - source: - skip_checkout: true - commands: - # Clone package into sub-folder `Packages/gltf` - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - # Clone all test asset repositories into `Assets` - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - # Install unity-downloader-cli and unity-config -{% if agent.os == "win" -%} - - | - where /q gsudo.exe && set CMD_ADMIN=gsudo.exe - %CMD_ADMIN% choco source add --priority 1 -n Unity -s {{ registry.artifactory }}/api/nuget/unity-choco-local - %CMD_ADMIN% choco install unity-config -y - %CMD_ADMIN% choco install unity-downloader-cli -y -{% elsif agent.os == "mac" -%} - - brew tap --force-auto-update unity/unity git@github.cds.internal.unity3d.com:unity/homebrew-unity.git - - brew install unity-config -{% endif -%} - - # Install UnifiedTestRunner -{% if agent.os == "win" -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr.bat --output {{ os.tool_utr }} -{% else -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr --output {{ os.tool_utr }} - - chmod +x {{ os.tool_utr }} -{% endif -%} - - # Install Unity Editor and required components - - unity-downloader-cli -u {{ editor }} -c Editor -c {{ platform.component }} -w --fast - - # Create test project - - | - unity-config project create {{ job_project_path }} - unity-config project add testable com.unity.cloud.gltfast - unity-config project add dependency com.unity.cloud.gltfast@file:./../../../Packages/gltfast - unity-config project add dependency {{ test_framework }} -p {{ job_project_path }} -{% for dep in test_dependencies -%} - unity-config project add dependency {{ dep.id }}@{{ dep.version }} -p {{ job_project_path }} -{% endfor -%} - -{% capture results_path -%}{{ os.yamato_source_dir }}/test-results~/com.unity.cloud.gltfast/{{ platform_id }}/{{ editor }}/{{ test_setup.project_setup }}{% endcapture -%} - - # Apply project setup - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.ApplySetup glTFastSetup:{{ test_setup.project_setup }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log - -{% if test_setup.render_pipeline -%} - # Apply render pipeline asset - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.SetRenderPipeline SRP:{{ test_setup.render_pipeline }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log -{% endif -%} - - # Run Tests - # TODO: upm-ci rocks UPM and other cache directories. Maybe we can speed things up this way as well. - # TODO: DISABLE_SUB_PACKAGE_LOAD is required for 2020 only. Eventually remove all occurrences. - - > -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets - - set DISABLE_SUB_PACKAGE_LOAD=TRUE -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" - - export DISABLE_SUB_PACKAGE_LOAD=TRUE -{% endif -%} - - {{ os.tool_utr }} - --testproject={{ job_project_path }} - --editor-location=.Editor - --artifacts_path={{ results_path }} - --reruncount=2 -{% if test_setup.utr_timeout -%} - --timeout={{ test_setup.utr_timeout }} -{% endif -%} - --verbose - --extra-editor-arg="-enablePackageManagerTraces -upmNoDefaultPackages" - --suite=editor - --suite=playmode - --category="{{ test_categories }}" -{% if is_coverage_set -%} - --enable-code-coverage - --coverage-results-path={{ results_path }}/CoverageResults - --coverage-options='generateAdditionalMetrics;generateHtmlReport;assemblyFilters:+glTFast*,-glTFast*Tests*;pathReplacePatterns:**/PackageCache/com.unity.cloud.gltfast@*/,;sourcePaths:{{ os.yamato_source_dir }}/Packages/gltfast' - --coverage-upload-options="reportsDir:{{ results_path }}/CoverageResults;reports:*.xml;sourceDir:Packages/gltfast;repo:unity/com.unity.cloud.gltfast.src;changeset:{{ os.git_revision }};name:{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }};flags:{{ test_setup.project_setup }};verbose" -{% endif -%} -{{ job_artifacts }} -{% endif -%} - -{% if platform.build_and_run -%} -{% assign agent = agents[platform.build_and_run] -%} -{% case agent.os -%} - {% when "win" -%} - {% assign os = os_variables.win -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.win -%} - {% when "mac" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.mac -%} - {% when "linux" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.ubuntu -%} - {% else -%} - Platform {{ platform.test }} has unknown OS! -{% endcase -%} - -build_and_run_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }}: - name : Build and run {{ test_setup.project_setup }} with {{ editor }} on {{ platform_id }} - agent: -{% assign agent = agents[platform.build_and_run] -%} - type: {% if test_setup.gpu_required %}{{ agent.gpu_type}}{% else %}{{ agent.type}}{% endif %} - image: {{ agent.image }} - flavor: {% if test_setup.agent_xlarge_required %}{{ agent.flavor_xlarge}}{% else %}{{ agent.flavor}}{% endif %} - source: - skip_checkout: true - commands: - # Clone package into sub-folder `Packages/gltf` - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - # Clone all test asset repositories into `Assets` - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - # Install unity-downloader-cli and unity-config -{% if agent.os == "win" -%} - - | - where /q gsudo.exe && set CMD_ADMIN=gsudo.exe - %CMD_ADMIN% choco source add --priority 1 -n Unity -s {{ registry.artifactory }}/api/nuget/unity-choco-local - %CMD_ADMIN% choco install unity-config -y - %CMD_ADMIN% choco install unity-downloader-cli -y -{% elsif agent.os == "mac" -%} - - brew tap --force-auto-update unity/unity git@github.cds.internal.unity3d.com:unity/homebrew-unity.git - - brew install unity-config -{% endif -%} - - # Install UnifiedTestRunner -{% if agent.os == "win" -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr.bat --output {{ os.tool_utr }} -{% else -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr --output {{ os.tool_utr }} - - chmod +x {{ os.tool_utr }} -{% endif -%} - - # Install Unity Editor and required components - - unity-downloader-cli -u {{ editor }} -c Editor -c {{ platform.component }} -w --fast - - # Create test project - - | - unity-config project create {{ job_project_path }} - unity-config project add testable com.unity.cloud.gltfast - unity-config project add dependency com.unity.cloud.gltfast@file:./../../../Packages/gltfast - unity-config project add dependency {{ test_framework }} -p {{ job_project_path }} -{% for dep in test_dependencies -%} - unity-config project add dependency {{ dep.id }}@{{ dep.version }} -p {{ job_project_path }} -{% endfor -%} - -{% capture results_path -%}{{ os.yamato_source_dir }}/test-results~/com.unity.cloud.gltfast/{{ platform_id }}/{{ editor }}/{{ test_setup.project_setup }}{% endcapture -%} - - # Apply project setup - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.ApplySetup glTFastSetup:{{ test_setup.project_setup }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log - -{% if test_setup.render_pipeline -%} - # Apply render pipeline asset - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.SetRenderPipeline SRP:{{ test_setup.render_pipeline }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log -{% endif -%} - - # Run Tests - # TODO: upm-ci rocks UPM and other cache directories. Maybe we can speed things up this way as well. - # TODO: DISABLE_SUB_PACKAGE_LOAD is required for 2020 only. Eventually remove all occurrences. - - > -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets - - set DISABLE_SUB_PACKAGE_LOAD=TRUE -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" - - export DISABLE_SUB_PACKAGE_LOAD=TRUE -{% endif -%} - - {{ os.tool_utr }} - --testproject={{ job_project_path }} - --editor-location=.Editor - --artifacts_path={{ results_path }} - --reruncount=2 -{% if test_setup.utr_timeout -%} - --timeout={{ test_setup.utr_timeout }} -{% endif -%} - --verbose - --extra-editor-arg="-enablePackageManagerTraces -upmNoDefaultPackages" - --suite=playmode - --category="{{ test_categories }}" - --scripting-backend=Il2Cpp - --platform={% if platform.platform -%}{{ platform.platform }}{% else -%}{{ platform_id }}{% endif %} -{{ job_artifacts }} -{% endif -%} - -{% if platform.build -%} -{% assign agent = agents[platform.build] -%} -{% case agent.os -%} - {% when "win" -%} - {% assign os = os_variables.win -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.win -%} - {% when "mac" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.mac -%} - {% when "linux" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.ubuntu -%} - {% else -%} - Platform {{ platform.test }} has unknown OS! -{% endcase -%} - -build_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }}: - name : Build {{ test_setup.project_setup }} with {{ editor }} on {{ platform_id }} - agent: -{% assign agent = agents[platform.build] -%} - type: {% if test_setup.gpu_required %}{{ agent.gpu_type}}{% else %}{{ agent.type}}{% endif %} - image: {{ agent.image }} - flavor: {% if test_setup.agent_xlarge_required %}{{ agent.flavor_xlarge}}{% else %}{{ agent.flavor}}{% endif %} - source: - skip_checkout: true - commands: - # Clone package into sub-folder `Packages/gltf` - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - # Clone all test asset repositories into `Assets` - - mkdir Assets -{% for asset_set in asset_sets -%} - - | - pushd Assets - git clone {{ asset_set.git_uri }} --no-checkout {{ asset_set.name }} - cd {{ asset_set.name }} - git fetch origin {{ asset_set.git_revision }} - git checkout -f --detach {{ asset_set.git_revision }} - popd -{% endfor -%} - - # Install unity-downloader-cli and unity-config -{% if agent.os == "win" -%} - - | - where /q gsudo.exe && set CMD_ADMIN=gsudo.exe - %CMD_ADMIN% choco source add --priority 1 -n Unity -s {{ registry.artifactory }}/api/nuget/unity-choco-local - %CMD_ADMIN% choco install unity-config -y - %CMD_ADMIN% choco install unity-downloader-cli -y -{% elsif agent.os == "mac" -%} - - brew tap --force-auto-update unity/unity git@github.cds.internal.unity3d.com:unity/homebrew-unity.git - - brew install unity-config -{% endif -%} - - # Install UnifiedTestRunner -{% if agent.os == "win" -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr.bat --output {{ os.tool_utr }} -{% else -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr --output {{ os.tool_utr }} - - chmod +x {{ os.tool_utr }} -{% endif -%} - - # Install Unity Editor and required components - - unity-downloader-cli -u {{ editor }} -c Editor -c {{ platform.component }} -w --fast - - # Create test project - - | - unity-config project create {{ job_project_path }} - unity-config project add testable com.unity.cloud.gltfast - unity-config project add dependency com.unity.cloud.gltfast@file:./../../../Packages/gltfast - unity-config project add dependency {{ test_framework }} -p {{ job_project_path }} -{% for dep in test_dependencies -%} - unity-config project add dependency {{ dep.id }}@{{ dep.version }} -p {{ job_project_path }} -{% endfor -%} - -{% capture results_path -%}{{ os.yamato_source_dir }}/test-results~/com.unity.cloud.gltfast/{{ platform_id }}/{{ editor }}/{{ test_setup.project_setup }}{% endcapture -%} - - # Apply project setup - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.ApplySetup glTFastSetup:{{ test_setup.project_setup }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log - -{% if test_setup.render_pipeline -%} - # Apply render pipeline asset - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.SetRenderPipeline SRP:{{ test_setup.render_pipeline }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log -{% endif -%} - - # Run Tests - # TODO: upm-ci rocks UPM and other cache directories. Maybe we can speed things up this way as well. - # TODO: DISABLE_SUB_PACKAGE_LOAD is required for 2020 only. Eventually remove all occurrences. - - > -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets - - set DISABLE_SUB_PACKAGE_LOAD=TRUE -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" - - export DISABLE_SUB_PACKAGE_LOAD=TRUE -{% endif -%} - - {{ os.tool_utr }} - --testproject={{ job_project_path }} - --editor-location=.Editor - --artifacts_path={{ results_path }} - --reruncount=2 -{% if test_setup.utr_timeout -%} - --timeout={{ test_setup.utr_timeout }} -{% endif -%} - --verbose - --extra-editor-arg="-enablePackageManagerTraces -upmNoDefaultPackages" - --suite=playmode - --category="{{ test_categories }}" - --scripting-backend=Il2Cpp - --platform={% if platform.platform -%}{{ platform.platform }}{% else -%}{{ platform_id }}{% endif %} - --build-only - --player-save-path={{ results_path }}/player - artifacts: - logs: - paths: - - "test-results~/**/*" -{% endif -%} - -{% if platform.run -%} -{% assign agent = agents[platform.run] -%} -{% case agent.os -%} - {% when "win" -%} - {% assign os = os_variables.win -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.win -%} - {% when "mac" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.mac -%} - {% when "linux" -%} - {% assign os = os_variables.unix -%} - {% assign editor_exe = os.yamato_source_dir | append: editor_location.ubuntu -%} - {% else -%} - Platform {{ platform.test }} has unknown OS! -{% endcase -%} - -run_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }}: - name : Run {{ test_setup.project_setup }} with {{ editor }} on {{ platform_id }} - agent: -{% assign agent = agents[platform.run] -%} - type: {% if test_setup.gpu_required %}{{ agent.gpu_type}}{% else %}{{ agent.type}}{% endif %} - image: {{ agent.image }} - flavor: {% if test_setup.agent_xlarge_required %}{{ agent.flavor_xlarge}}{% else %}{{ agent.flavor}}{% endif %} - source: - skip_checkout: true - commands: - # Clone package into sub-folder `Packages/gltf` - - | - mkdir Packages - pushd Packages - git clone {{ os.git_url }} --no-checkout gltfast - cd gltfast - git fetch origin {{ os.git_revision }} - git checkout -f --detach {{ os.git_revision }} - popd - - # Install unity-downloader-cli and unity-config -{% if agent.os == "win" -%} - - | - where /q gsudo.exe && set CMD_ADMIN=gsudo.exe - %CMD_ADMIN% choco source add --priority 1 -n Unity -s {{ registry.artifactory }}/api/nuget/unity-choco-local - %CMD_ADMIN% choco install unity-config -y - %CMD_ADMIN% choco install unity-downloader-cli -y -{% elsif agent.os == "mac" -%} - - brew tap --force-auto-update unity/unity git@github.cds.internal.unity3d.com:unity/homebrew-unity.git - - brew install unity-config -{% endif -%} - - # Install UnifiedTestRunner -{% if agent.os == "win" -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr.bat --output {{ os.tool_utr }} -{% else -%} - - curl -s --show-error --retry 15 {{ registry.artifactory }}/unity-tools-local/utr-standalone/utr --output {{ os.tool_utr }} - - chmod +x {{ os.tool_utr }} -{% endif -%} - - # Install Unity Editor and required components - - unity-downloader-cli -u {{ editor }} -c Editor -c {{ platform.component }} -w --fast - - # Create test project - - | - unity-config project create {{ job_project_path }} - unity-config project add testable com.unity.cloud.gltfast - unity-config project add dependency com.unity.cloud.gltfast@file:./../../../Packages/gltfast - unity-config project add dependency {{ test_framework }} -p {{ job_project_path }} -{% for dep in test_dependencies -%} - unity-config project add dependency {{ dep.id }}@{{ dep.version }} -p {{ job_project_path }} -{% endfor -%} - -{% capture results_path -%}{{ os.yamato_source_dir }}/test-results~/com.unity.cloud.gltfast/{{ platform_id }}/{{ editor }}/{{ test_setup.project_setup }}{% endcapture -%} - - # Apply project setup - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.ApplySetup glTFastSetup:{{ test_setup.project_setup }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log - -{% if test_setup.render_pipeline -%} - # Apply render pipeline asset - - > - {{ editor_exe }} - -projectPath {{ job_project_path }} - -executeMethod GLTFast.Editor.Tests.SetupProject.SetRenderPipeline SRP:{{ test_setup.render_pipeline }} - -upmNoDefaultPackages - -enablePackageManagerTraces - -batchmode - -quit - -logFile {{ results_path }}/UnityProjectSetup.log -{% endif -%} - -{% if platform_id == "android" and platform.run == "shield" -%} -{% assign androidUrlPrefix = "https://artifactory-slo.bf.unity3d.com/artifactory/mobile-generic/android/ADBKeys.zip!" -%} - - | - set ANDROID_DEVICE_CONNECTION={{ os.bokken_host_ip }}; - wget {{ androidUrlPrefix }}/adbkey.pub -O %USERPROFILE%/.android/adbkey.pub - wget {{ androidUrlPrefix }}/adbkey -O %USERPROFILE%/.android/adbkey - gsudo NetSh Advfirewall set allprofiles state off - "%ANDROID_SDK_ROOT%\platform-tools\adb.exe" connect {{ os.bokken_host_ip }} -{% endif -%} - - # Run Tests - # TODO: upm-ci rocks UPM and other cache directories. Maybe we can speed things up this way as well. - # TODO: DISABLE_SUB_PACKAGE_LOAD is required for 2020 only. Eventually remove all occurrences. - - > -{% if agent.os == "win" -%} - set GLTF_TEST_ASSET_DIR={{ os.yamato_source_dir }}\Assets - - set DISABLE_SUB_PACKAGE_LOAD=TRUE -{% else -%} - export GLTF_TEST_ASSET_DIR="{{ os.yamato_source_dir }}/Assets" - - export DISABLE_SUB_PACKAGE_LOAD=TRUE -{% endif -%} - - {{ os.tool_utr }} - --testproject={{ job_project_path }} - --editor-location=.Editor - --artifacts_path={{ results_path }} - --reruncount=2 -{% if test_setup.utr_timeout -%} - --timeout={{ test_setup.utr_timeout }} -{% endif -%} - --verbose - --extra-editor-arg="-enablePackageManagerTraces -upmNoDefaultPackages" - --suite=playmode - --category="{{ test_categories }}" - --scripting-backend=Il2Cpp - --platform={% if platform.platform -%}{{ platform.platform }}{% else -%}{{ platform_id }}{% endif %} - --player-load-path={{ results_path }}/player -{% if platform_id == "android" and platform.run == "shield" -%} - --player-connection-ip={{ os.bokken_host_ip }} -{% endif -%} -{% if platform.build -%} - dependencies: - - .yamato/project-test.yml#build_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }} -{% endif -%} -{{ job_artifacts }} -{% endif -%} - - -{% endfor -%} -{% endfor -%} - -tests_{{ test_setup.project_setup }}_all: - name: Test all {{ test_setup.project_setup }} - dependencies: -{% for editor in editor_versions -%} -{% for platform_id in platform_ids -%} -{% if platforms[platform_id].test -%} - - .yamato/project-test.yml#test_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }} -{% endif -%} -{% endfor -%} -{% endfor -%} - -tests_{{ test_setup.project_setup }}_pr: - name: Test PR subset {{ test_setup.project_setup }} - dependencies: -{% for pr_set in test_setup.pr_test_subset -%} - - .yamato/project-test.yml#test_{{ test_setup.project_setup }}_{{ pr_set.platform }}_{{ pr_set.editor }} -{% endfor -%} - -build_and_run_{{ test_setup.project_setup }}_all: - name: Build and run all {{ test_setup.project_setup }} - dependencies: -{% for editor in editor_versions -%} -{% for platform_id in platform_ids -%} -{% if platforms[platform_id].build_and_run -%} - - .yamato/project-test.yml#build_and_run_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }} -{% elsif platforms[platform_id].run -%} - - .yamato/project-test.yml#run_{{ test_setup.project_setup }}_{{ platform_id }}_{{ editor }} -{% endif -%} -{% endfor -%} -{% endfor -%} - -{% if test_setup.pr_build_subset -%} -build_and_run_{{ test_setup.project_setup }}_pr: - name: Build and run PR subset {{ test_setup.project_setup }} - dependencies: -{% for pr_set in test_setup.pr_build_subset -%} -{% if platforms[pr_set.platform].build_and_run -%} - - .yamato/project-test.yml#build_and_run_{{ test_setup.project_setup }}_{{ pr_set.platform }}_{{ pr_set.editor }} -{% elsif platforms[pr_set.platform].run -%} - - .yamato/project-test.yml#run_{{ test_setup.project_setup }}_{{ pr_set.platform }}_{{ pr_set.editor }} -{% endif -%} -{% endfor -%} -{% endif -%} - -{% endfor -%} # for test_setup in test_setups - -tests_all: - name: Test all - dependencies: -{% for test_setup in test_setups -%} - - .yamato/project-test.yml#tests_{{ test_setup.project_setup }}_all -{% endfor -%} - -tests_pr: - name: Test PR subsets - dependencies: -{% for test_setup in test_setups -%} - - .yamato/project-test.yml#tests_{{ test_setup.project_setup }}_pr -{% endfor -%} - -build_and_run_all: - name: Build and run all - dependencies: -{% for test_setup in test_setups -%} - - .yamato/project-test.yml#build_and_run_{{ test_setup.project_setup }}_all -{% endfor -%} - -build_and_run_pr: - name: Build and run PR subsets - dependencies: -{% for test_setup in test_setups -%} -{% if test_setup.pr_build_subset -%} - - .yamato/project-test.yml#build_and_run_{{ test_setup.project_setup }}_pr -{% endif -%} -{% endfor -%} - -coverage_all: - name: Coverage All - dependencies: -{% for test_setup in test_setups -%} -{% for coverage_set in test_setup.coverage_subset -%} - - .yamato/project-test.yml#test_{{ test_setup.project_setup }}_{{ coverage_set.platform }}_{{ coverage_set.editor }} -{% endfor -%} -{% endfor -%} diff --git a/.yamato/triggers.yml b/.yamato/triggers.yml deleted file mode 100644 index 34064ff02..000000000 --- a/.yamato/triggers.yml +++ /dev/null @@ -1,45 +0,0 @@ -{% metadata_file .yamato/package.metafile -%} ---- - -pr_trigger: - name: PR Trigger - triggers: - expression: | - (pull_request.target eq "main" OR pull_request.target eq "develop") AND - NOT pull_request.push.changes.all match "**/*.md" - dependencies: - - .yamato/code-format-check.yml#code_format_check - - .yamato/package-test.yml#tests_pr - - .yamato/project-test.yml#tests_pr - - .yamato/project-test.yml#build_and_run_pr - -tests_all_trigger: - name: _Tests All - triggers: - expression: | - push.branch eq "main" OR - pull_request.comment eq "all" - dependencies: - - .yamato/package-test.yml#tests_all - - .yamato/project-test.yml#tests_all - - .yamato/project-test.yml#build_and_run_all - -tests_all_weekly: - name: _Tests All [Weekly] - triggers: - recurring: - - branch: develop - frequency: weekly - rerun: always - dependencies: - - .yamato/triggers.yml#tests_all_trigger - - -# Runs code coverage on any change on the develop branch -# in order to create a reference for pull requests. -post_merge_trigger: - name: Post Merge Trigger - triggers: - expression: push.branch eq "develop" - dependencies: - - .yamato/project-test.yml#coverage_all diff --git a/CHANGELOG.md b/CHANGELOG.md index f71decb48..4d42f80da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,435 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [6.19.0] - 2026-05-19 + +### Added +- (Add-Ons) Import glTF animations to custom animation systems. + - [IAnimationProcessor](xref:GLTFast.Animations.IAnimationProcessor) — animation clips conversion + - [IAnimationProcessorFactory](xref:GLTFast.Animations.IAnimationProcessorFactory) — add-ons need to implement this +- (Add-Ons) Lifetime management of converted glTF data and application during scene instantiation. Is used for custom animation import only for now. + - [IDataInstanceApplierFactory](xref:GLTFast.Addons.IDataInstanceApplierFactory) — owns converted data and forwards it to scene instantiation + - [IDataCache](xref:GLTFast.Addons.IDataCache) + - [IInstanceApplierFactory](xref:GLTFast.Addons.IInstanceApplierFactory) + - [IInstanceApplier](xref:GLTFast.Addons.IInstanceApplier) — applies data on scene instance +- [IGltfAccessors](xref:GLTFast.IGltfAccessors) provides read-only access to typed glTF accessor data. +- [INodeHierarchyInfo](xref:GLTFast.INodeHierarchyInfo) provides glTF node hierarchy information. +- (Test) Inspector materials variant selection for `OpenGltfDialog`. +- Instructions/guidelines for coding agents (`AGENTS.md`/`CLAUDE.md`) + +### Changed +- Increased minimum required Unity version to 6.0 LTS. +- Bumped dependency versions + - com.unity.burst to 1.8.29 + - com.unity.collections to 2.6.6 + - com.unity.mathematics to 1.3.3 +- GameObjectSceneInstance's [AddCamera](xref:GLTFast.GameObjectSceneInstance.AddCamera), [AddLight](xref:GLTFast.GameObjectSceneInstance.AddLight) and [SetLegacyAnimation](xref:GLTFast.GameObjectSceneInstance.SetLegacyAnimation) are now public, so custom [IInstantiators](xref:GLTFast.IInstantiator) can utilize it. +- Refactored [ImportAddonInstanceCollection](xref:GLTFast.Addons.ImportAddonInstanceCollection) to derive directly from `List`/[QueryableList](xref:GLTFast.Addons.QueryableList). +- (Performance) Importing animation curves got much faster and requires less managed memory. Keyframes are prepared in native arrays and set en bloc via [SetKeys(ReadOnlySpan<Keyframe>)](xref:UnityEngine.AnimationCurve.SetKeys(System.ReadOnlySpan`1)) instead of being slowly added individually (thanks [jverral](https://github.com/jverral) for initiating this via [#44](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/44)). +- (Performance) Reduced memory waste by using cached, static identifiers instead of inner-loop format strings for [AnimationClip.SetCurve](xref:UnityEngine.AnimationClip.SetCurve(System.String,System.Type,System.String,UnityEngine.AnimationCurve))'s `propertyName` parameter (thanks [jverral](https://github.com/jverral) for [#44](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/44)). +- Enabled Render Graph in graphics settings by default on all projects (not using compatibility mode anymore). + - (Test) Compatibility mode is still enabled for Unity 6.0 tests. + +### Fixed +- Improved comma placement in export summary (thanks anonymous for [#46](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/46)). +- [Materials variants](xref:GLTFast.MaterialsVariantsComponent)' inspector shows correct variant when regaining focus (thanks [anonymous2585](https://github.com/anonymous2585) for [#48](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/48)). +- (Import) Fixed merging of mesh primitives with shared vertex buffer, but different indices type. + +## [6.18.0] - 2026-04-01 + +### Added +- (Add-Ons) [IPostJsonDeserialization](xref:GLTFast.Addons.IPostJsonDeserialization) for intercepting the loading process right after glTF JSON deserialization. +- (Test) Model *SubMeshIncompatible*, which features animated morph targets and primitives of incompatible vertex buffer structures. + +### Fixed +- (Shader) Back-face normals are now correctly flipped in URP (fixes [#38](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/issues/38)). +- (Import) Textures are named after the corresponding glTF image again to ensure consistency with previous imports (reverts a change introduced in 6.17.0). +- (Import) Log error instead of throwing exception when failing to download a texture with a relative URI when a base URI is not provided. + +## [6.17.0] - 2026-03-17 + +### Added +- Texture loading is fully customizable via Add-Ons. + - Inject support for glTF texture extensions (see [ITextureImageLoader](xref:GLTFast.ITextureImageLoader)). + - Customize PNG and Jpeg loading (see [IDefaultImageFormatLoader](xref:GLTFast.IDefaultImageFormatLoader)). + - See *ImageAddonTest* scene in the tests package which use the *AddOnsImage* samples from the `DocExamples` directory. +- Explicit error message when unsupported image format WebP is detected ([LogCode.ImageFormatUnsupported](xref:GLTFast.Logging.LogCode.ImageFormatUnsupported)). +- [ImageResult](xref:GLTFast.ImageResult) which depicts an imported glTF image. +- (Test) TextureVariants test glTFs with WebP image format. +- [Extension.TextureWebP](xref:GLTFast.Extension.TextureWebP) (no general WebP support, just for handling WebP cases). + +### Changed +- (Add-Ons) GltfImport now accepts multiple import add-on instances of the same type. + - [GetImportAddonInstance](xref:GLTFast.GltfImportBase.GetImportAddonInstance*) returns the first instance that matches the type. +- Ensured compatibility with [Fast Enter Play Mode](https://unity.com/blog/engine-platform/enter-play-mode-faster-in-unity-2019-3). +- Image type detection is based on content (instead of mime-type depicted in glTF JSON, data URI mediatype or file extension). +- Improved error message when image format is detected, but not supported (e.g. WebP). + +### Fixed +- (Import) [AnisotropicFilterLevel setting](xref:GLTFast.ImportSettings.AnisotropicFilterLevel) is applied to KTX textures as well. +- (Import) Leak of textures in case of loading errors. +- (Export) Meshes with zero vertices or indices will now be skipped and an error will be logged instead of an exception being thrown (fixes [#806](https://github.com/atteneder/glTFast/issues/806)). + +## [6.16.1] - 2026-02-19 + +### Added +- (Test) *Empty Scene* test asset. +- (Import) Support for 16-bit mesh indices reduces memory footprint for meshes with less than 65k vertices per sub-mesh. + - 16-bit indices are not converted to 32-bit anymore. + - 8-bit indices ar converted to 16-bit (instead of 32-bit). + +### Changed +- [GltfImport.Load](xref:GLTFast.GltfImportBase.Load*), [GltfImport.InstantiateSceneAsync](xref:GLTFast.GltfImportBase.InstantiateSceneAsync*) and their variants now throw an `OperationCanceledException` when cancelled before completion. +- Replaced the generic [StandardMaterialExport](xref:GLTFast.Export.StandardMaterialExport) with specializations. + - [LitMaterialExport](xref:GLTFast.Export.LitMaterialExport) for Universal Render Pipeline Lit shader material export. + - [BuiltInStandardMaterialExport](xref:GLTFast.Export.BuiltInStandardMaterialExport) for Built-in Render Pipeline Standard shader material export. +- (Performance) Improved performance of mesh indices conversion for draw modes line loop, triangle strips and triangle fan. + +### Fixed +- [GltfImport.InstantiateSceneAsync](xref:GLTFast.GltfImportBase.InstantiateSceneAsync*) properly handles an invalid scene index parameter. +- [GltfImport](xref:GLTFast.GltfImportBase) waits for downloads to complete before attempting disposal during cancellation. +- Projects depending on an outdated version of [meshoptimizer mesh compression for Unity] may suppress the corresponding compiler error by using the `GLTFAST_IGNORE_MESHOPT_OUTDATED_ERROR` scripting define symbol. +- (Shader) Incorrect alpha blending/clipping due to invalid color space conversion on the base color map alpha and vertex color alpha values (affected shader graphs only; fixes [#800](https://github.com/atteneder/glTFast/issues/800)). +- (Shader) Built-in render pipeline shaders metallic-roughness and specular-glossiness now factor in vertex color alpha values. +- (Shader) All built-in render pipeline shaders apply vertex color alpha values linearly. +- (Shader) Shader graph *glTF-pbrSpecularGlossiness* does not disregard the *Glossiness* parameter anymore. +- (Import) Cases when specular-glossiness material setup would be incomplete at runtime. +- (Import) Removed remains of incorrectly signed integer indices. +- (Export) Smoothness value property is exported correctly across more combination of settings for Universal Render Pipeline Lit shader based materials (fixes [#795](https://github.com/atteneder/glTFast/issues/795) and [796](https://github.com/atteneder/glTFast/issues/796)). +- (Export) When a Lit/Standard material has a smoothness texture, their smoothness value is baked into the resulting roughness channel (of the ORM map). This preserves the visual appearance, but is a lossy operation if the smoothness value is not `1.0` (fixes [#795](https://github.com/atteneder/glTFast/issues/795) and [796](https://github.com/atteneder/glTFast/issues/796)). +- (Export) `MetaMaterialExportBuiltIn` is used for built-in material export (unless `GLTFAST_BUILTIN_SHADER_GRAPH` is set). +- (Import) Solved exception when scenes with no nodes are loaded. +- (Import) Triangle fan meshes with the center vertex not being the first vertex import correctly now. +- (Test) Graphics tests are more stable/consistent due to dedicated scene. +- (Shader) Incorrect normal unpacking when using default normal map on Android (fixes [#791](https://github.com/atteneder/glTFast/issues/791) and [802](https://github.com/atteneder/glTFast/issues/802)). +- (Export) Texture scaling not preserved on URP/Lit export (fixes [#805](https://github.com/atteneder/glTFast/issues/805)). + +### Deprecated +- Generic built-in/Universal render pipeline [StandardMaterialExport](xref:GLTFast.Export.StandardMaterialExport). + +## [6.16.0] - 2026-01-20 + +### Added +- [GltfAsset](xref:GLTFast.GltfAsset) property setters to allow change of behavior from script. + - [PlayAutomatically](xref:GLTFast.GltfAsset.PlayAutomatically). + - [SceneId](xref:GLTFast.GltfAsset.SceneId). +- HDRP material validation (fixes [#561](https://github.com/atteneder/glTFast/issues/561)). +- Various overridable shader loading methods to [MaterialGenerator](xref:GLTFast.Materials.MaterialGenerator)-based classes so users can customize shader lookup. This is useful when working with Addressables (fixes [#715](https://github.com/atteneder/glTFast/issues/715)). + - [MaterialGenerator.FindShader](xref:GLTFast.Materials.MaterialGenerator.FindShader(System.String)) for generic, runtime shader resolution. + - [BuiltInMaterialGenerator.FindShaderMetallicRoughness](xref:GLTFast.Materials.BuiltInMaterialGenerator.FindShaderMetallicRoughness). + - [BuiltInMaterialGenerator.FindShaderSpecularGlossiness](xref:GLTFast.Materials.BuiltInMaterialGenerator.FindShaderSpecularGlossiness). + - [BuiltInMaterialGenerator.FindShaderUnlit](xref:GLTFast.Materials.BuiltInMaterialGenerator.FindShaderUnlit). + - [ShaderGraphMaterialGenerator.LoadShaderByName](xref:GLTFast.Materials.ShaderGraphMaterialGenerator.LoadShaderByName(System.String)). + +### Fixed +- Emission color (emissiveFactor) is now in correct color space for shader graphs and built-in shaders. +- Normal map scale on shader graphs. +- (Export) Avoid creating empty ORM textures if no smoothness texture is assigned (fixes [#801](https://github.com/atteneder/glTFast/issues/801)). + +### Deprecated +- Access to glTF images via [IGltfReadable.ImageCount](xref:GLTFast.IGltfReadable.ImageCount) and [IGltfReadable.GetImage](xref:GLTFast.IGltfReadable.GetImage*). This has not been used internally and was unreliable. Please access glTF textures instead (see [TextureCount](xref:GLTFast.IGltfReadable.TextureCount) and [GetTexture](xref:GLTFast.IGltfReadable.GetTexture*)). + +## [6.15.1] - 2025-12-09 + +### Added +- Assigned glTF logo to [GltfEntityAsset](xref:GLTFast.GltfEntityAsset) component. +- (Test) Test glTF asset *CylinderWithMaterial* that's procedurally generated at runtime. +- (Test) Tests for documentation examples. +- (Test) `OpenGltfScene` improvements. + - Refactored to use custom load method. + - Load method option to choose between loading from file or URI. + - Scene index option. + - Informative console logs with file path/URI and load time. + - Now works at runtime as well (without file dialog). + - Re-positions camera so that the loaded glTF scene is framed. + - Can load via [EntityInstantiator](xref:GLTFast.EntityInstantiator). + +### Changed +- (Entities) Entities of a scene are grouped via `LinkedEntityGroup`. +- (Performance) Import mesh indices as unsigned integers and don't convert to signed integers anymore. +- (Performance) Limited copy buffer size, so that garbage allocations do not scale with glTF-Binary content size anymore (when loading from file or `Stream`). +- (Performance) Large glTF-Binary content is now loaded into memory in smaller chunks, which keeps the frame rate smooth (when loading from file or `Stream`). +- (Performance) Shift loading glTF-Binary from stream to memory to a background thread, if it won't likely fit within the current update loop. +- (Performance) glTF-Binary buffers are not initialized with zeros before population. +- [meshoptimizer mesh compression for Unity] minimum required version was raised to 0.2.0-exp.1. +- (Test) Updated tests dependency Graphics Test Framework (com.unity.testframework.graphics) to 8.13.1-exp.1. + +### Fixed +- Returning a proper error for glTF-Binary with a content length shorter than what's depicted in the header. +- NotSupportedException when loading a glTF-Binary file with excess length (fixes [#786](https://github.com/atteneder/glTFast/issues/786)). +- (Documentation) Clarified how to add export shader variants. +- (Test) Fixed generated test glTFs by exporting them in synchronous mode (only available internally). +- (Importer) Synchronization Context is now properly reset after an exception (thanks [Bruno](https://github.com/bruno1308) for [#29](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/29)). +- Removed compiler warning when `GLTFAST_SAFE` scripting define is active. +- (Test) Stabilize tests by executing `LogAssert.Expect` before actual tests. +- (Entities) Sub-meshes are rendered properly. +- (Test) Tests destroy the glTF entities before disposing meshes/materials to avoid batch rendering errors. + +## [6.15.0] - 2025-11-17 + +### Added +- Loading KTX textures from data URIs. +- (Test) OpenGltfScene: Shortcut Control+X clears the previously loaded glTF. Useful for testing resource deallocation. +- (Test) Assets variants of *SubMesh* and *Rainbow Cuboid* for testing import of compressed/uncompressed multi-primitive meshes. +- (Test) glTFs with different kinds of image formats and sources. +- (Test) *No Normal* test asset. + +### Changed +- *glTFast* will return a success value of `true` even if an image fails to load (which has not been consistent across the API before). This makes it easier to display assets despite of non-critical loading errors. Users who need stricter behavior can resort to monitoring for error logs (see the runtime import manual about logging or the `logger` parameter of [GltfImport constructor](xref:GLTFast.GltfImportBase.#ctor(GLTFast.Loading.IDownloadProvider,GLTFast.IDeferAgent,GLTFast.Materials.IMaterialGenerator,GLTFast.Logging.ICodeLogger))). +- Primitives of a Draco compressed mesh will be decoded into in a single Unity mesh with multiple sub-meshes instead of multiple Unity meshes (thanks [Kibsgaard](https://github.com/Kibsgaard) for initiating this in [#33](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/33)). +- [Draco for Unity] minimum required version was raised to 5.4.0. +- (Performance) Texture data is not copied into managed memory before loading via [Texture2D.LoadImage](xref:UnityEngine.ImageConversion.LoadImage(UnityEngine.Texture2D,System.Byte[],System.Boolean)) (applies for Unity 6.0 or newer). +- (Performance) Avoid copy of entire data URI string by using `ReadOnlySpan` instead sub-stringing. +- (Performance) Base64-encoded data URIs are now decoded into [NativeArray<byte>](xref:Unity.Collections.NativeArray`1) instead of `byte[]`, reducing GC allocations. +- [KTX for Unity] minimum required version was raised to 3.6.0. +- Up-to-date versions of soft-dependencies [KTX for Unity] or [Draco for Unity] are enforced by raising a compiler error if an outdated version of either of those is installed. + +### Fixed +- Corrected test cases for `GltfTestModels` importer tests. +- Properly dispose GPU instancing buffers after Editor imports. +- Multi-primitive, skinned meshes import properly to Unity meshes with multiple sub-meshes. +- For Draco compressed meshes, it's now ensured that morph targets are retrieved to completion and resources are disposed properly. +- Sampler settings conflicts result in a proper warning message if they cannot be resolved by instantiating the Texture2D (can occur on design-time imports). +- Implicitly add normals to the vertex attribute layout if tangents are required (fixes [#41](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/issues/41)). +- Properly release native resources bound by morph targets jobs in context of decoding Draco compressed meshes. +- Avoid pointless copying of glb-embedded textures if ImageConversion module is disabled anyways. +- Avoid download of textures if ImageConversion module is disabled anyways. +- Gracefully fail when buffer data URI has incorrect media-type field or undersized content length. +- Just like PNG or Jpeg, KTX textures are now loaded readable as well if it's required by the import settings, the platform or for applying multiple sampler settings. +- Properly abort if loading of a data URI encoded image failed. +- Don't crash when a buffer failed to load when loading from `string`, `byte` arrays or `Stream`. +- Return value of [GltfImport](xref:GLTFast.GltfImportBase) loading methods ([Load](xref:GLTFast.GltfImportBase.Load*), [LoadFile](xref:GLTFast.GltfImportBase.LoadFile*), [LoadGltfBinary](xref:GLTFast.GltfImportBase.LoadGltfBinary*), [LoadGltfBinary](xref:GLTFast.GltfImportBase.LoadGltfJson*) and [LoadStream](xref:GLTFast.GltfImportBase.LoadStream*)) has been made consistent. +- (Documentation) various broken links fixed. + +### Removed +- Broken consistency check between image data URI mediatype against image's mimeType. +- Support for obsolete Hybrid Renderer (com.unity.rendering.hybrid). + +## [6.14.1] - 2025-09-30 + +### Changed +- [TryGetAllUVAccessors](xref:GLTFast.Schema.Attributes.TryGetAllUVAccessors*) only returns the first 8, actually supported UV sets (and not the ninth anymore). + +### Fixed +- Avoid crash when loading meshes with more than 8 texture coordinate sets by properly limiting them. + +## [6.14.0] - 2025-09-12 + +### Added +- Graphics Tests. +- [EditorConfig](https://editorconfig.org/) for keeping a consistent code-style. +- [IBufferView.ByteStride](xref:GLTFast.Schema.IBufferView.ByteStride). + +### Changed +- (CI) Consolidated multiple redundant packaging and vetting/API validation jobs. +- Changed internal buffer representation to custom native collection `ReadOnlyBuffer` (instead of [NativeArray<byte>.ReadOnly](xref:Unity.Collections.NativeArray`1.ReadOnly)) This enables sub-array slicing, has in-Editor safety checks and prepares for decommissioning misuse of NativeSlice. +- Bumped Burst dependency version to 1.8.24, which is the recommended version in 2021 xLTS. +- [KTX for Unity] minimum required version was raised to 3.5.0. +- [Draco for Unity] minimum required version was raised to 5.2.0. + +### Fixed +- (Export) Spotlight's inner cone angle is exported correctly on HDRP now. +- (Test) Disabled URP compatibility mode in URP presets as it's obsolete and unsupported from Unity 6.3 onward. +- (Import) Spotlight's inner cone angle is imported correctly on HDRP now. + +### Removed +- (CI) SonarQube scan job. + +### Deprecated +- `GLTFast.ManagedNativeArray`. It will be removed from public API in a future release. For internal development it's been replaced by `ReadOnlyNativeArrayFromManagedArray`. +- `GLTFast.Export.ManagedNativeArray`. It will get sealed or removed from public API in a future release. +- [IGltfReadable.GetAccessorData](xref:GLTFast.IGltfReadable.GetAccessorData(System.Int32)). Along with [IGltfReadable.GetAccessor](xref:GLTFast.IGltfReadable.GetAccessor(System.Int32)) it is going to be removed and replaced with an improved way to access accessors' data in a future release. + +## [6.13.1] - 2025-07-17 + +### Added +- (Test) Menu items that make switching test setups and render pipelines more accessible. +- (Test) JSON parsing performance tests. +- (Tools) Scripts for resetting test materials and settings. + +### Changed +- Refactored `JsonParsingTests`. +- Ensured loggers are used in all tests and examples. + +### Fixed +- (Import) Prevented `NullReferenceException` on transmissive materials with no transmissive texture. +- (Import) Potential `NullReferenceException` when clearcoat is applied without a texture. +- Incorrect version define for the Unity Collections package. glTFast now properly uses older versions (1.4.0) as well. + +### Removed +- [Playables](https://docs.unity3d.com/Manual/Playables.html) option for runtime animation imports. +- (Documentation) Use case for custom [Playables](https://docs.unity3d.com/Manual/Playables.html) animation implementation. + +## [6.13.0] - 2025-06-10 + +### Added +- (Documentation) Use case for custom [Playables](https://docs.unity3d.com/Manual/Playables.html) animation implementation. + +### Fixed +- Use XYZ-style normals in shaders even if DXT5nm-style is enabled. +- (Import) When a node has morph target weights, they are applied properly (instead of the primitive's weights; fixes [#531](https://github.com/atteneder/glTFast/issues/531)). +- (Import) Specular-Glossiness materials with alpha mode `MASK` are not blended anymore in URP/HDRP (fixes [#757](https://github.com/atteneder/glTFast/issues/757)). + +## [6.12.1] - 2025-04-08 + +### Fixed +- Incorrect using for Assert from NUnit.Framework to UnityEngine.Assertions + +## [6.12.0] - 2025-03-31 + +### Added +- [Playables](https://docs.unity3d.com/Manual/Playables.html) option for runtime animation imports. +- Support for accessors without a buffer view when importing animation clips. + +### Fixed +- (Import)`InvalidOperationException` on multi-primitive meshes with vertex colors thrown by the native container safety system (fixes [#30](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/issues/30)). +- (Export) Sub-meshes that have a base vertex other than zero are exported with correct indices now. +- Reliability issues related to lack of certain async calls in [GltfImport](xref:GLTFast.GltfImport) and [GltfWriter](xref:GLTFast.Export.GltfWriter). + +## [6.11.0] - 2025-03-13 + +### Added +- [GltfImport.Load](xref:GLTFast.GltfImportBase.Load(Unity.Collections.NativeArray{System.Byte}.ReadOnly,System.Uri,GLTFast.ImportSettings,System.Threading.CancellationToken)) overload that accept glTF data in form of [NativeArray<byte>.ReadOnly](xref:Unity.Collections.NativeArray`1.ReadOnly). +- [INativeDownload](xref:GLTFast.Loading.INativeDownload), which can be used to expand [IDownload](xref:GLTFast.Loading.IDownload) implementations to provide access to downloaded data directly without creating a copy in managed memory. +- Content-based glTF JSON vs. glTF-Binary detection (limited to Unity 2021 LTS or newer; resolves [#193](https://github.com/atteneder/glTFast/issues/193)). + +### Changed +- (Performance) By default glTF and KTX data is not copied to managed memory implicitly when loading glTFs (true for Unity 2021 LTS or newer). + +### Deprecated +- [GltfImport.LoadGltfBinary](xref:GLTFast.GltfImportBase.LoadGltfBinary*) (in favor of the generic [GltfImport.Load](xref:GLTFast.GltfImportBase.Load*)) + +## [6.10.3] - 2025-02-21 + +### Fixed +- (Import) Morph targets on multi-primitive meshes (where primitives reference identical vertex buffers; fixes [#755](https://github.com/atteneder/glTFast/issues/755)). + +## [6.10.2] - 2025-02-03 + +### Added +- (Importer) *Textures Readable* checkbox in the importer inspector (*Textures* section). +- (Export) Error message when attempting to export with unsupported meshopt compression. +- (Tests) Runtime import performance tests. +- (Tests) Procedurally generated glTFs for testing purpose. +- (Tests) Editor export tests. + +### Changed +- (Tests) Reduced jobs performance test duration by lowering buffer sizes and switching to dynamic measurement counts. +- (Tests) Performance tests are not run, unless the `RUN_PERFORMANCE_TESTS` scripting define is set. + +### Fixed +- Performance test compilation if *Collections* package >= 1.5.0 is not installed. +- Inconsistent profiler markers. +- (Export) Unity Editor not responding anymore after export glTF with non-readable meshes. +- (Export) Missing `inverseBindMatrices`/`bindPoses` on skinned meshes when exporting with Draco compression. +- (CI) Ensuring the development documentation and the `Tools` code is checked for code formatting as well. +- Compilation for `ICodeLogger` implementors by adding a default implementation for `Log` (works for Unity 2021 LTS and newer). + +## [6.10.1] - 2025-01-09 + +### Added +- Test for `ConvertBoneWeightsUInt8ToFloatInterleavedJob` +- Test for `ConvertBoneWeightsUInt16ToFloatInterleavedJob` +- *BoundsTests* which certifies correct mesh bounds. + +### Changed +- Downgraded package dependencies to version bundled with Editor. + - `com.unity.collections` to version `1.2.4` (from `1.5.1`) + - `com.unity.mathematics` to version `1.2.6` (from `1.3.1`) +- When a position accessor lacks min/max properties, the corresponding error message is communicated via the `ICodeLogger` instead of a plain console log. + +### Fixed +- Build error when used along with packages that depend on `com.unity.collections` versions older than 1.5 (e.g. Polyspatial 1.x; fixes [#730](https://github.com/atteneder/glTFast/issues/730)). +- Invalid mesh bounds on meshes with one submesh (fixes [#743](https://github.com/atteneder/glTFast/issues/743)). + +## [6.10.0] - 2024-12-16 + +### Added +- Extended access to meshes. + - `IGltfReadable.GetSourceMesh` returns source (de-serialized glTF) mesh. + - `GltfImportBase.Meshes` to retrieve all imported meshes. + - `GltfImportBase.GetMeshCount` returns the number of imported meshes per glTF mesh. + - `GltfImportBase.GetMeshes` to iterate the imported meshes of a single glTF mesh. + - `GltfImportBase.GetMesh` to access a single imported meshes. +- Test asset *SubMesh*. +- (CI) Automatically generated CI jobs (via Wrench/RecipeEngine; required for PackageWorks). +- (CI) Renovate action to auto-update dependencies in CI jobs. +- (CI) Renovate validation action. +- `JpgQuality` option in `ExportSettings` for finer control of jpg image exports. +- Project versions to test projects. + +### Changed +- Mesh primitives of equal vertex buffer layout will result in a single Unity mesh with multiple sub-meshes instead of multiple Unity meshes (fixes [#153](https://github.com/atteneder/glTFast/issues/153)). + +### Deprecated +- `IGltfReadable.GetAccessor` (replaced by `IGltfReadable.GetAccessorData`). +- `GltfImportBase.GetMeshes` (replaced by `GltfImportBase.Meshes`). + +### Fixed +- Preserve per-submesh bounding box. +- `GltfAsset` properly cleans up scene instance's `Animation` component, which fixes repeated loading of animated glTFs. + +## [6.9.1] - 2024-11-15 + +### Added +- (Test) `OpenGltfScene` with open glTF file dialog for convenient testing. +- (Test) Tests for C# jobs that calculate or re-order indices. +- Third party notices. +- `GltfImportBase.Logger` grants access to the logger in use. +- `GltfImportBase.DeferAgent` grants access to the defer agent in use. + +### Changed +- Convert one mesh's primitives of identical target vertex buffer structure into sub-meshes of one Unity mesh instead of splitting them up into multiple Unity meshes (fixes [#153](https://github.com/atteneder/glTFast/issues/153)). +- Node name is assigned earlier during instantiation, enabling easier node identification by name (partially fixes [#724](https://github.com/atteneder/glTFast/issues/724)). +- (Test) Updated test project dependencies. +- (CI) Migrated code coverage. +- Code refactoring + - Flattened `GltfImportBase.Prepare` by extracting many large code blocks into dedicated methods. + - Improved class/field naming. It's now less deceptive and more uniform. + - Using `NativeArray` directly/only instead of `AccessorData` classes/managed arrays. With this change `NativeArrays` are used for index buffers as well which reduces the amount of managed memory allocated. +- Facilitated use of safer NativeCollections in C# jobs that calculate or re-order indices instead of `unsafe` / pointers. + +### Fixed +- Made sure that mesh primitives of different drawmode (topology) are not mixed up. +- Apply morph targets/blend shapes before uploading to GPU in `GLTFAST_KEEP_MESH_DATA` mode. + +## [6.9.0] - 2024-10-30 + +### Added +- Package coherence tests that make sure package versions match across exported generator string and documentation. + +### Changed +- Moved code examples that are referenced by the documentation into a different folder (`DocExamples`). +- Renamed code example assembly/namespace to `GLTFast.Documentation.Examples` for consistency. + +### Fixed +- (Test) LoadTests on Android now succeed by using `UnityWebRequest` to retrieve data from the compressed JAR file. +- Loading glTFs from `StreamingAssets` with relative URIs containing Unicode characters on Android. UriHelper.GetBaseUri and UriHelper.GetUriString handle Android `jar:file://` schema URIs with unicode characters correctly (fixes [#667](https://github.com/atteneder/glTFast/issues/667)). +- XML documentation fixes +- Removed unnecessary "type" property from `package.json`. +- Removed warning about obsolete `GraphicsDeviceType.OpenGLES2` in Unity 2023.1 or newer. +- (Export) Missing texture transform if texture on glTFast material was scaled vertically only. +- Improved reliability by adding null checks and imprecision-aware floating-point comparisons in various places. +- Using immutable fields only in hash code calculation for `ImageExport` classes. +- Refactored `GetHashCode` implementations referencing mutable fields to avoid potential unexpected behavior. + - `TextureComparer.Equals` made `GetHashCode`/`Equals` for `TextureBase` obsolete, so they've been removed. + - `MeshPrimitiveComparer` is now used for clustering mesh primitives (instead of `GetHashCode`/`Equals` on `MeshPrimitive` and sub-types). +- Set minimum required Unity version to 2020.3.48f1 in the documentation. +- (Export) Avoid potential loss of data by allocating output streams persistently. +- (Test) Render export test inconclusive if the result has not been validated. +- (Test) More explicit error message by throwing innermost exception while preserving the stack trace during async tests. +- (Documentation) Various clarifications, improvements and fixes, based on user feedback. + +### Removed +- Outdated and unused code coverage badge. + ## [6.8.0] - 2024-09-05 ### Added - (Import) Setting to create textures readable. This allows users to access resulting textures from their scripts. - (Export) Non-readable meshes can be exported as well now. - (Export) Added support for exporting meshes with vertex compression enabled (effectively converting 16-bit float positions/normals/tangents/texture coordinates to 32-bit floats). +- (Export) Skinned meshes export support (thanks [Hugo Pereira][Hugo-Didimo] for [#512](https://github.com/atteneder/glTFast/pull/512)). - (Export) [Buffer view targets](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_bufferview_target) are set properly now. - (Import) Support for mesh primitive modes `TRIANGLE_STRIP` and `TRIANGLE_FAN` (thanks [Hexer611][Hexer611] for [#22](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/22)) @@ -106,28 +529,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - On Apple visionOS, textures are always created readable, so that [PolySpatial visionOS][PolySpatialVisionOS] is able to convert them. - Draco compressed tangents import tangents correctly now. - Removed invalid attempt to calculate normals or tangents on point or line meshes. -- Consistent log message when a glTF extension cannot be supported due to a missing Unity package depenency (e.g. [KTX for Unity][KtxForUnity]). +- Consistent log message when a glTF extension cannot be supported due to a missing Unity package depenency (e.g. [KTX for Unity]). - All missing extensions are logged (not just the first one). - There's now a single message per missing package. - Depending on whether that extension is required the message's type is warning or error. - - Added explicit message when [*meshoptimizer decompression for Unity*][meshoptUnity] is missing. + - Added explicit message when [meshoptimizer mesh compression for Unity] is missing. ## [6.3.0] - 2024-03-27 -## Added +### Added - Runtime import tests. - Runtime export tests. - (Export) Added development-time checks for valid JSON string literals. - Added Apple Privacy Manifest file to `/Plugins` directory. -## Changed +### Changed - Refactored test scripts folder layout. - (Export) Normal maps are exported in PNG format by default. - (Export) HDRP area lights are still exported as spot-lights, but their intensity is taken from `Light.intensity` (still incorrect, but more consistent). - Switched from asset-path-based to GUID-based shader loading (in the Editor 2021 and newer) in order to allow for a flexible folder layout without risking breaks/regressions should the layout change in the future. - Avoid expensive UnityEngine.Object null check when accessing cached default shaders. -## Fixed +### Fixed - Exception when required glTF shader is not included. - Compiler errors when safe mode (`GLTFAST_SAFE` scripting define) is enabled. - Compiler error with High Definition Render Pipeline version 17 (2023.3) @@ -148,7 +571,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Deprecated soft-dependency packages are detected and a warning with upgrade instructions is shown in the console. ### Changed -- Support for Draco 3D Data Compression is now provided by [*Draco for Unity* (com.unity.cloud.draco)][DracoForUnity], which is a fork of and replaces [*DracoUnity* (com.atteneder.draco)][DracoUnity]. +- Support for Draco 3D Data Compression is now provided by [*Draco for Unity* (com.unity.cloud.draco)][Draco For Unity], which is a fork of and replaces [*DracoUnity* (com.atteneder.draco)][DracoUnity]. ### Fixed - Compiler error when Newtonsoft JSON package was not installed. @@ -168,7 +591,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - CI maintenance ### Fixed -- Updated references to [KTX for Unity][KtxForUnity] +- Updated references to [KTX for Unity] ## [6.0.1] - 2023-10-11 @@ -227,6 +650,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added proper root namespace to all assembly definitions - License and copyright notices - (Export) Increased performance due to concurrent buffer conversions +- Support for KTX (Khronos Texture) is now provided by [*KTX for Unity* (com.unity.cloud.ktx)][Ktx for Unity], which is a fork of and replaces [*KtxUnity* (com.atteneder.ktx)][KtxUnity]. ## [5.0.4] - 2023-03-30 @@ -1216,18 +1640,19 @@ This release contains multiple breaking changes. Please read the [upgrade guide] [Collections]: https://docs.unity3d.com/Packages/com.unity.collections@latest/ [JobsPkg]: https://docs.unity3d.com/Packages/com.unity.jobs@latest/ [KtxUnity]: https://github.com/atteneder/KtxUnity -[KtxForUnity]: https://docs.unity3d.com/Packages/com.unity.cloud.ktx@latest/ +[Ktx for Unity]: https://docs.unity3d.com/Packages/com.unity.cloud.ktx@latest/ [DanDovi]: https://github.com/DanDovi -[DracoForUnity]: https://docs.unity3d.com/Packages/com.unity.cloud.draco@latest +[Draco for Unity]: https://docs.unity3d.com/Packages/com.unity.cloud.draco@latest [DracoUnity]: https://github.com/atteneder/DracoUnity [PolySpatialVisionOS]: https://docs.unity3d.com/Packages/com.unity.polyspatial.visionos@latest/ -[meshoptUnity]: https://docs.unity3d.com/Packages/com.unity.meshopt.decompress@latest/ +[meshoptimizer mesh compression for Unity]: https://docs.unity3d.com/Packages/com.unity.meshopt.decompress@latest/ [aurorahcx]: https://github.com/aurorahcx [Battlehub0x]: https://github.com/Battlehub0x [Bersaelor]: https://github.com/Bersaelor [EricBeetsOfficial-Opuscope]: https://github.com/EricBeetsOfficial-Opuscope [Hexer611]: https://github.com/Hexer611 [Holo-Krzysztof]: https://github.com/Holo-Krzysztof +[Hugo-Didimo]: https://github.com/Hugo-Didimo [hybridherbst]: https://github.com/hybridherbst [krisrok]: https://github.com/krisrok [Kushulain]: https://github.com/Kushulain diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 621eaf4b0..5519619b4 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,77 +1,3 @@ - # Contributor Covenant Code of Conduct -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to make participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies within all project spaces, and it also applies when -an individual is representing the project or its community in public spaces. -Examples of representing a project or community include using an official -project e-mail address, posting via an official social media account, or acting -as an appointed representative at an online or offline event. Representation of -a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team. -All complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at - -For answers to common questions about this code of conduct, see - - -[homepage]: https://www.contributor-covenant.org +See [Contributor Covenant Code of Conduct](Documentation~/code-of-conduct.md). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 20497c168..facead634 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,61 +1,3 @@ # Contributing -Thank you for your interest in contributing to glTFast! We are -incredibly excited to see how members of our community will use and extend -glTFast. To facilitate your contributions, we've outlined a brief set -of guidelines to ensure that your extensions can be easily integrated. - -## Communication - -Please read through our [code of conduct][COC], as we -expect all our contributors to follow it. - -For inquiries of all sorts, feel free to raise an issue by going to the -[issues page][issues] and click the *New issue* button. - -If you're looking for ideas on ways to contribute browse the [issues][issues], -especially ones with the `help wanted` or `good first issue` label. - -## Preparation - -Before starting to work on a contribution we recommend searching within the -existing [issues][issues] and [pull requests][pulls] for similar topics to -avoid redundant efforts and make sure you got all contextual information. - -Feel free to propose ideas upfront via an [issue][issues] that briefly outlines -your intended changes. We'll then try to give you advice and feedback on how to -optimally implement those changes or, if justifiable, reasons to abandon an -idea. This pre-evaluation can raise the chances of getting a contribution -accepted. - -## Version Control - -*glTFast* uses [Git][Git] and [GitHub][repo] for version control. - -## Submission via Pull Request - -Changes can be proposed via [pull requests (PR)][GithubDocPR] on the [pull requests][pulls] page. - -Please make sure that your PR contains the following: - -- Detailed description of the changes performed -- Corresponding changes to documentation, changelog and unit tests -- Summary of the tests performed to validate your changes -- Issue numbers that the PR resolves (if any) - -PRs will be transferred to an internal, mirrored repository to undergo review and (automated) tests that use Unity's internal tools and infrastructure. If those tests and reviews are not successful, we'll help you resolve remaining issues and merge your work, once it passes all tests. The merge will happen on the mirrored repository and the original pull requests will get closed with a proper notification about expected release version and date. - -## Contributor License Agreements - -When you open a pull request, you will be asked to acknowledge our Contributor -License Agreement. You will have to confirm that your Contributions are your -original creation and that you have complete right and authority to make your -contributions. We allow both individual contributions and contributions made on -behalf of companies. - -[COC]: CODE_OF_CONDUCT.md -[Git]: https://git-scm.com/ -[repo]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast -[issues]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast/issues -[pulls]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pulls -[GithubDocPR]: https://docs.github.com/pull-requests +See [Contributing](Documentation~/contributing.md). diff --git a/Samples.meta b/DocExamples.meta similarity index 100% rename from Samples.meta rename to DocExamples.meta diff --git a/DocExamples/AssemblyInfo.cs b/DocExamples/AssemblyInfo.cs new file mode 100644 index 000000000..bb6dd2f9a --- /dev/null +++ b/DocExamples/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("glTFast.Tests")] diff --git a/DocExamples/AssemblyInfo.cs.meta b/DocExamples/AssemblyInfo.cs.meta new file mode 100644 index 000000000..8f9ff0dd5 --- /dev/null +++ b/DocExamples/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21f888a80e8fb4054b3b6f9366cec295 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples/Documentation/Manual/CustomGltfImport.cs b/DocExamples/CustomGltfImport.cs similarity index 76% rename from Samples/Documentation/Manual/CustomGltfImport.cs rename to DocExamples/CustomGltfImport.cs index 23ea5556f..2de43d0f7 100644 --- a/Samples/Documentation/Manual/CustomGltfImport.cs +++ b/DocExamples/CustomGltfImport.cs @@ -2,28 +2,34 @@ // SPDX-License-Identifier: Apache-2.0 #if NEWTONSOFT_JSON -namespace Samples.Documentation.Manual +namespace GLTFast.Documentation.Examples { -#region CustomGltfImport - using GLTFast; - using GLTFast.Addons; + #region CustomGltfImport using System; using System.Threading.Tasks; + using Addons; + using GLTFast; + using GLTFast.Logging; using UnityEngine; using GltfImport = GLTFast.Newtonsoft.GltfImport; - public class CustomGltfImport : MonoBehaviour + class CustomGltfImport : MonoBehaviour { // Path to the gltf asset to be imported - public string Uri; + public string uri; + + async void Start() + { + await LoadGltf(); + } - async Task Start() + public async Task LoadGltf() { try { ImportAddonRegistry.RegisterImportAddon(new MyAddon()); - var gltfImport = new GltfImport(); - await gltfImport.Load(Uri); + var gltfImport = new GltfImport(logger: new ConsoleLogger()); + await gltfImport.Load(uri); await gltfImport.InstantiateMainSceneAsync(transform); } catch (Exception e) @@ -32,8 +38,9 @@ async Task Start() } } - public class MyAddon : ImportAddon { } - public class MyAddonInstance : ImportAddonInstance + class MyAddon : ImportAddon { } + + class MyAddonInstance : ImportAddonInstance { GltfImport m_GltfImport; @@ -54,7 +61,7 @@ public override void Inject(IInstantiator instantiator) var goInstantiator = instantiator as GameObjectInstantiator; if (goInstantiator == null) return; - var _ = new MyInstantiatorAddon(m_GltfImport, goInstantiator); + _ = new MyInstantiatorAddon(m_GltfImport, goInstantiator); } public override bool SupportsGltfExtension(string extensionName) @@ -64,10 +71,10 @@ public override bool SupportsGltfExtension(string extensionName) } } - public class MyInstantiatorAddon + class MyInstantiatorAddon { - GltfImport m_GltfImport; - GameObjectInstantiator m_Instantiator; + readonly GltfImport m_GltfImport; + readonly GameObjectInstantiator m_Instantiator; public MyInstantiatorAddon(GltfImport gltfImport, GameObjectInstantiator instantiator) { @@ -86,7 +93,7 @@ void OnNodeCreated(uint nodeIndex, GameObject gameObject) var gltf = m_GltfImport.GetSourceRoot(); var node = gltf.Nodes[(int)nodeIndex] as GLTFast.Newtonsoft.Schema.Node; - var extras = node.extras; + var extras = node?.extras; if (extras == null) return; @@ -99,7 +106,7 @@ void OnNodeCreated(uint nodeIndex, GameObject gameObject) } } } -#endregion + #endregion } #endif diff --git a/Samples/Documentation/Manual/CustomGltfImport.cs.meta b/DocExamples/CustomGltfImport.cs.meta similarity index 100% rename from Samples/Documentation/Manual/CustomGltfImport.cs.meta rename to DocExamples/CustomGltfImport.cs.meta diff --git a/Samples/Documentation/Manual/ExportSamples.cs b/DocExamples/ExportSamples.cs similarity index 92% rename from Samples/Documentation/Manual/ExportSamples.cs rename to DocExamples/ExportSamples.cs index 4ff59b40b..9b04263fd 100644 --- a/Samples/Documentation/Manual/ExportSamples.cs +++ b/DocExamples/ExportSamples.cs @@ -2,23 +2,19 @@ // SPDX-License-Identifier: Apache-2.0 using System.Threading.Tasks; -using UnityEngine.Serialization; -namespace Samples.Documentation.Manual +namespace GLTFast.Documentation.Examples { - using UnityEngine; + using Export; using GLTFast; - using GLTFast.Export; - using GLTFast.Logging; + using Logging; + using UnityEngine; class ExportSamples : MonoBehaviour { + public string destinationFilePath; - [FormerlySerializedAs("path")] - [SerializeField] - string destinationFilePath; - - async void AdvancedExport() + public async Task AdvancedExport() { #region AdvancedExport @@ -82,7 +78,7 @@ async void AdvancedExport() #endregion } - void ExportSettingsDraco() + public static ExportSettings ExportSettingsDraco() { #region ExportSettingsDraco // ExportSettings provides generic export settings @@ -97,6 +93,7 @@ void ExportSettingsDraco() } }; #endregion + return exportSettings; } async void Start() @@ -104,7 +101,7 @@ async void Start() await LocalTransform(); } - async Task LocalTransform() + public async Task LocalTransform() { #region LocalTransform var export = new GameObjectExport(); diff --git a/Samples/Documentation/Manual/ExportSamples.cs.meta b/DocExamples/ExportSamples.cs.meta similarity index 100% rename from Samples/Documentation/Manual/ExportSamples.cs.meta rename to DocExamples/ExportSamples.cs.meta diff --git a/Samples/Documentation/Manual/ExtraData.cs b/DocExamples/ExtraData.cs similarity index 86% rename from Samples/Documentation/Manual/ExtraData.cs rename to DocExamples/ExtraData.cs index 0f0a3496c..2ff71edf1 100644 --- a/Samples/Documentation/Manual/ExtraData.cs +++ b/DocExamples/ExtraData.cs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 -namespace Samples.Documentation.Manual +namespace GLTFast.Documentation.Examples { #region ExtraData diff --git a/Samples/Documentation/Manual/ExtraData.cs.meta b/DocExamples/ExtraData.cs.meta similarity index 100% rename from Samples/Documentation/Manual/ExtraData.cs.meta rename to DocExamples/ExtraData.cs.meta diff --git a/DocExamples/LoadGltfFromMemory.cs b/DocExamples/LoadGltfFromMemory.cs new file mode 100644 index 000000000..232a51624 --- /dev/null +++ b/DocExamples/LoadGltfFromMemory.cs @@ -0,0 +1,188 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using GLTFast.Logging; + +namespace GLTFast.Documentation.Examples +{ + + using System; + using GLTFast; + using UnityEngine; + + class LoadGltfFromMemory : MonoBehaviour + { + // Path to the gltf asset to be loaded + public string filePath; + + // ReSharper disable once Unity.IncorrectMethodSignature + // ReSharper disable once UnusedMember.Local + async Task Start() + { + await LoadGltfFile(); + } + + #region LoadGltfFromMemory + async Task LoadGltfFile() + { + var gltfDataAsByteArray = await File.ReadAllBytesAsync(filePath); + var gltf = new GltfImport(logger: new ConsoleLogger()); + var success = await gltf.Load( + gltfDataAsByteArray, + // The URI of the original data is important for resolving relative URIs within the glTF + new Uri(filePath) + ); + if (success) + { + await gltf.InstantiateMainSceneAsync(transform); + } + } + #endregion + + public void LoadViaComponent() + { + #region LoadViaComponent + var gltf = gameObject.AddComponent(); + gltf.Url = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/glTF/Duck.gltf"; + #endregion + gltf.LoadOnStartup = false; + } + + public static async Task ImportSettings(string filePath) + { + #region ImportSettings + var gltf = new GltfImport(); + + // Create a settings object and configure it accordingly + var settings = new ImportSettings + { + GenerateMipMaps = true, + AnisotropicFilterLevel = 3, + NodeNameMethod = NameImportMethod.OriginalUnique + }; + // Load the glTF and pass along the settings + var success = await gltf.Load(filePath, settings); + + if (success) + { + var gameObject = new GameObject("glTF"); + await gltf.InstantiateMainSceneAsync(gameObject.transform); + } + else + { + Debug.LogError("Loading glTF failed!"); + } + #endregion + } + + public async Task Instantiation() + { + #region Instantiation + // First step: load glTF + var gltf = new GLTFast.GltfImport(); + var success = await gltf.Load(filePath); + + if (success) + { + // Here you can customize the post-loading behavior + + // Get the first material + var material = gltf.GetMaterial(); + Debug.LogFormat("The first material is called {0}", material.name); + + // Instantiate the glTF's main scene + await gltf.InstantiateMainSceneAsync(new GameObject("Instance 1").transform); + // Instantiate the glTF's main scene + await gltf.InstantiateMainSceneAsync(new GameObject("Instance 2").transform); + + // Instantiate each of the glTF's scenes + for (var sceneId = 0; sceneId < gltf.SceneCount; sceneId++) + { + await gltf.InstantiateSceneAsync(transform, sceneId); + } + } + else + { + Debug.LogError("Loading glTF failed!"); + } + #endregion + } + +#if UNITY_ANIMATION + public async Task SceneInstanceAccess() + { + #region SceneInstanceAccess + var gltfImport = new GltfImport(); + await gltfImport.Load(filePath); + var instantiator = new GameObjectInstantiator(gltfImport, transform); + var success = await gltfImport.InstantiateMainSceneAsync(instantiator); + if (success) + { + // Get the SceneInstance to access the instance's properties + var sceneInstance = instantiator.SceneInstance; + + // Enable the first imported camera (which are disabled by default) + if (sceneInstance.Cameras is { Count: > 0 }) + { + sceneInstance.Cameras[0].enabled = true; + } + + // Decrease lights' ranges + if (sceneInstance.Lights != null) + { + foreach (var gltfLight in sceneInstance.Lights) + { + gltfLight.range *= 0.1f; + } + } + + // Play the default (i.e. the first) animation clip + var legacyAnimation = instantiator.SceneInstance.LegacyAnimation; + if (legacyAnimation is not null) + { + legacyAnimation.Play(); + } + } + #endregion + } +#endif // UNITY_ANIMATION + + public async Task CustomDeferAgent() + { + var manyUrls = new[] + { + "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/glTF/Duck.gltf" + }; + #region CustomDeferAgent + // Recommended: Use a common defer agent across multiple GltfImport instances! + // TimeBudgetPerFrameDeferAgent for a stable frame rate: + IDeferAgent deferAgent = gameObject.AddComponent(); + // Or alternatively, UninterruptedDeferAgent for low latency loading: + deferAgent = new UninterruptedDeferAgent(); + + var tasks = new List(); + + foreach (var url in manyUrls) + { + var gltf = new GltfImport(null, deferAgent); + var task = gltf.Load(url).ContinueWith( + async t => + { + if (t.Result) + { + await gltf.InstantiateMainSceneAsync(transform); + } + }, + TaskScheduler.FromCurrentSynchronizationContext() + ); + tasks.Add(task); + } + + await Task.WhenAll(tasks); + #endregion + } + } +} diff --git a/DocExamples/LoadGltfFromMemory.cs.meta b/DocExamples/LoadGltfFromMemory.cs.meta new file mode 100644 index 000000000..255a0c92a --- /dev/null +++ b/DocExamples/LoadGltfFromMemory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbdeab6fe2fc54058a70f9be966cd732 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/DocExamples/MultipleInstances.cs b/DocExamples/MultipleInstances.cs new file mode 100644 index 000000000..18ab68b68 --- /dev/null +++ b/DocExamples/MultipleInstances.cs @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2024 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +namespace GLTFast.Documentation.Examples +{ + #region MultipleInstances + using System; + using System.Threading.Tasks; + using GLTFast.Logging; + using UnityEngine; + + class MultipleInstances : MonoBehaviour + { + // Path to the gltf asset to be imported + public string uri; + + [Range(1, 10)] + public int quantity = 3; + + async void Start() + { + try + { + await LoadGltf(); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + public async Task LoadGltf() + { + var logger = new ConsoleLogger(); + var gltfImport = new GltfImport(logger: logger); + await gltfImport.Load(uri); + + for (var i = 0; i < quantity; i++) + { + var go = new GameObject($"glTF-{i}") + { + transform = + { + localPosition = new Vector3(0, 0, i * .13f) + } + }; + var instantiator = new GameObjectInstantiator(gltfImport, go.transform, logger: logger); + await gltfImport.InstantiateMainSceneAsync(instantiator); + var scene = instantiator.SceneInstance; + var materialsVariantsControl = scene.MaterialsVariantsControl; + + if (materialsVariantsControl != null) + { + var materialsVariantsComponent = go.AddComponent(); + materialsVariantsComponent.Control = materialsVariantsControl; + + await materialsVariantsControl.ApplyMaterialsVariantAsync(i % gltfImport.MaterialsVariantsCount); + } + } + } + } + #endregion +} diff --git a/Samples/Documentation/Manual/MultipleInstances.cs.meta b/DocExamples/MultipleInstances.cs.meta similarity index 100% rename from Samples/Documentation/Manual/MultipleInstances.cs.meta rename to DocExamples/MultipleInstances.cs.meta diff --git a/DocExamples/PngTextureAddon.cs b/DocExamples/PngTextureAddon.cs new file mode 100644 index 000000000..55f4adec9 --- /dev/null +++ b/DocExamples/PngTextureAddon.cs @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Threading; +using System.Threading.Tasks; +using GLTFast.Addons; +using Unity.Collections; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Profiling; + +namespace GLTFast.Documentation.Examples +{ + class PngTextureAddon : ImportAddon { } + + class PngTextureAddonInstance : ImageLoaderAddonInstance, IDefaultImageFormatLoader + { + public override void Inject(GltfImportBase gltfImport) + { + gltfImport.AddImportAddonInstance(this); + } + + public bool IsAbleToLoad(ImageFormat format) + { +#if UNITY_IMAGECONVERSION + return format == ImageFormat.Png; +#else + return false; +#endif + } + + public bool IsAbleToLoad(ReadOnlySpan data) + { + return ImageFormatDetection.IsPng(data); + } + + public Task LoadImage( + NativeArray.ReadOnly data, + bool linear, + bool readable, + bool generateMipMaps, + CancellationToken cancellationToken + ) + { +#if UNITY_IMAGECONVERSION + Profiler.BeginSample("LoadPNG"); + var texture = CreateEmptyTexture(linear, generateMipMaps); + var success = texture.LoadImage(data.AsReadOnlySpan(), !readable); + Profiler.EndSample(); + if (success) + { + return Task.FromResult(new ImageResult(texture)); + } +#endif // UNITY_IMAGECONVERSION + return Task.FromResult(ImageResult.Null); + } + + static Texture2D CreateEmptyTexture( + bool forceSampleLinear, + bool generateMipMaps + ) + { + var textureCreationFlags = TextureCreationFlags.DontUploadUponCreate | TextureCreationFlags.DontInitializePixels; + if (generateMipMaps) + { + textureCreationFlags |= TextureCreationFlags.MipChain; + } + var txt = new Texture2D( + 4, 4, + forceSampleLinear + ? GraphicsFormat.R8G8B8A8_UNorm + : GraphicsFormat.R8G8B8A8_SRGB, + textureCreationFlags + ); + return txt; + } + } +} diff --git a/DocExamples/PngTextureAddon.cs.meta b/DocExamples/PngTextureAddon.cs.meta new file mode 100644 index 000000000..facfd71f5 --- /dev/null +++ b/DocExamples/PngTextureAddon.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e77fb6b01275544b8a3e420cbb55bae5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples/Documentation/Manual/SimpleExport.cs b/DocExamples/SimpleExport.cs similarity index 93% rename from Samples/Documentation/Manual/SimpleExport.cs rename to DocExamples/SimpleExport.cs index 3ee9c5ab1..1785e9c76 100644 --- a/Samples/Documentation/Manual/SimpleExport.cs +++ b/DocExamples/SimpleExport.cs @@ -1,11 +1,11 @@ // SPDX-FileCopyrightText: 2024 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 -namespace Samples.Documentation.Manual +namespace GLTFast.Documentation.Examples { #region SimpleExport + using Export; using UnityEngine; - using GLTFast.Export; class SimpleExport : MonoBehaviour { diff --git a/Samples/Documentation/Manual/SimpleExport.cs.meta b/DocExamples/SimpleExport.cs.meta similarity index 100% rename from Samples/Documentation/Manual/SimpleExport.cs.meta rename to DocExamples/SimpleExport.cs.meta diff --git a/DocExamples/TextureAddOnExample.cs b/DocExamples/TextureAddOnExample.cs new file mode 100644 index 000000000..a441f0432 --- /dev/null +++ b/DocExamples/TextureAddOnExample.cs @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Threading.Tasks; +using GLTFast.Addons; +using GLTFast.Logging; +using UnityEditor; +using UnityEngine; + +namespace GLTFast.Documentation.Examples +{ + class TextureAddOnExample : MonoBehaviour + { + // Path to the gltf asset to be imported + public string uri; + public bool isLogicalPath; + + [Header("Add-Ons")] + public bool webP = true; + public bool png = true; + + async void Start() + { + await LoadGltf(); + } + + public async Task LoadGltf() + { + try + { + // // Global registration of the addons, they will be used for all imports + // ImportAddonRegistry.RegisterImportAddon(new WebpTextureAddon()); + // ImportAddonRegistry.RegisterImportAddon(new PngTextureAddon()); + +#if NEWTONSOFT_JSON + var gltfImport = new Newtonsoft.GltfImport(logger: new ConsoleLogger()); +#else + var gltfImport = new GltfImport(logger: new ConsoleLogger()); +#endif + + // Local registration of the addons, they will be used only for this import + if (webP) + { + gltfImport.AddImportAddonInstance(new WebpTextureAddonInstance()); + } + + if (png) + { + gltfImport.AddImportAddonInstance(new PngTextureAddonInstance()); + } + + var settings = new ImportSettings { GenerateMipMaps = true }; + string path; + if (isLogicalPath) + { +#if !UNITY_EDITOR + Debug.LogError("Loading glTFs from logical paths is only supported in the editor."); + return; +#else + path = FileUtil.GetPhysicalPath(uri); +#endif + } + else + { + path = uri; + } + await gltfImport.Load(path, settings); + await gltfImport.InstantiateMainSceneAsync(transform); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + } + + abstract class ImageLoaderAddonInstance : ImportAddonInstance + { + public override void Dispose() { } + + public override bool SupportsGltfExtension(string extensionName) + { + return false; + } + + public override void Inject(IInstantiator instantiator) { } + } +} diff --git a/DocExamples/TextureAddOnExample.cs.meta b/DocExamples/TextureAddOnExample.cs.meta new file mode 100644 index 000000000..0213e49b1 --- /dev/null +++ b/DocExamples/TextureAddOnExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b73b2898ba344e2895e5e7a2830ee31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 3b6a1cb26d29941f2a3cc902680e2e03, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/DocExamples/WebP.cs b/DocExamples/WebP.cs new file mode 100644 index 000000000..0e782bc2f --- /dev/null +++ b/DocExamples/WebP.cs @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Jobs; +using UnityEngine; +using UnityEngine.Profiling; + +namespace GLTFast.Documentation.Examples +{ + static class WebP + { + public static async Task Decode( + NativeArray.ReadOnly data, + bool linear, + bool readable, + CancellationToken cancellationToken + ) + { + if (!TryGetInfo(data, out var width, out var height)) + { + return null; + } + Profiler.BeginSample("WebPCreateTexture2D"); + var texture = new Texture2D(width, height, TextureFormat.RGBA32, false, linear); + var textureData = texture.GetRawTextureData(); + using var result = new NativeArray(1, Allocator.Persistent); + var job = new WebPDecodeJob + { + data = data, + textureData = textureData, + width = width, + result = result + }.Schedule(); + Profiler.EndSample(); + + while (!job.IsCompleted) + { + await Task.Yield(); + } + job.Complete(); + + if (result[0] == IntPtr.Zero) + { + UnityEngine.Object.Destroy(texture); + return null; + } + Profiler.BeginSample("WebPApply"); + texture.Apply(false, !readable); + Profiler.EndSample(); + return texture; + } + + static unsafe bool TryGetInfo(NativeArray.ReadOnly data, out int width, out int height) + { + width = 0; + height = 0; + try + { + var returnValue = WebPGetInfo((byte*)data.GetUnsafeReadOnlyPtr(), (uint)data.Length, ref width, ref height); + return returnValue != 0; + } + catch (DllNotFoundException) + { + Debug.LogError("For this example to work, you need to compile libwebp as a native plugin and name it 'webp-unity'."); + } + + return false; + } + + unsafe struct WebPDecodeJob : IJob + { + [WriteOnly] + public NativeArray result; + + [ReadOnly] + public NativeArray.ReadOnly data; + + [WriteOnly] + public NativeArray textureData; + + public int width; + + public void Execute() + { + var decodeResult = WebPDecodeRGBAInto( + (byte*)data.GetUnsafeReadOnlyPtr(), (uint)data.Length, + (byte*)textureData.GetUnsafePtr(), (uint)textureData.Length, + sizeof(Color32) * width + ); + + result[0] = decodeResult; + } + } + + [DllImport("webp-unity")] + public static extern unsafe int WebPGetInfo(byte* data, uint size, ref int width, ref int height); + + [DllImport("webp-unity")] + public static extern unsafe IntPtr WebPDecodeRGBAInto( + byte* data, uint size, + byte* outputBuffer, uint outputBufferSize, + int outputStride); + } +} diff --git a/DocExamples/WebP.cs.meta b/DocExamples/WebP.cs.meta new file mode 100644 index 000000000..cac9f6bf5 --- /dev/null +++ b/DocExamples/WebP.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57b70c10212fe4854b0d656de33430f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/DocExamples/WebpTextureAddon.cs b/DocExamples/WebpTextureAddon.cs new file mode 100644 index 000000000..1947ac21c --- /dev/null +++ b/DocExamples/WebpTextureAddon.cs @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Threading; +using System.Threading.Tasks; +using GLTFast.Addons; +using GLTFast.Schema; +using Unity.Collections; +using UnityEngine; + +namespace GLTFast.Documentation.Examples +{ + class WebpTextureAddon : ImportAddon { } + + class WebpTextureAddonInstance : ImageLoaderAddonInstance, ITextureImageLoader + { + public override void Inject(GltfImportBase gltfImport) + { +#if NEWTONSOFT_JSON + if (gltfImport is not Newtonsoft.GltfImport) + return; + + gltfImport.AddImportAddonInstance(this); +#else + Debug.LogError("WebpTextureAddon requires the Newtonsoft.Json package to be installed."); +#endif + } + + public override bool SupportsGltfExtension(string extensionName) + { + return extensionName == "EXT_texture_webp"; + } + + public bool IsAbleToLoad(TextureBase texture, out int imageIndex) + { +#if NEWTONSOFT_JSON + if (texture is GLTFast.Newtonsoft.Schema.Texture { extensions: not null } t + && t.extensions.TryGetValue( + "EXT_texture_webp", out var ext)) + { + imageIndex = ext.source; + return true; + } +#endif + imageIndex = -1; + return false; + } + + public bool IsAbleToLoad(ReadOnlySpan data) + { + return ImageFormatDetection.IsWebP(data); + } + + public async Task LoadImage( + NativeArray.ReadOnly data, + bool linear, + bool readable, + bool generateMipMaps, + CancellationToken cancellationToken + ) + { + var texture = await WebP.Decode(data, linear, readable, cancellationToken); + return new ImageResult(texture, true); + } + } + + [Serializable] + struct TextureWebpExtension + { + public int source; + } +} diff --git a/DocExamples/WebpTextureAddon.cs.meta b/DocExamples/WebpTextureAddon.cs.meta new file mode 100644 index 000000000..5fd62d006 --- /dev/null +++ b/DocExamples/WebpTextureAddon.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11436a5eff90a40d0ade007fef446742 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/DocExamples/glTFast.Documentation.Examples.asmdef b/DocExamples/glTFast.Documentation.Examples.asmdef new file mode 100644 index 000000000..48cb2ae77 --- /dev/null +++ b/DocExamples/glTFast.Documentation.Examples.asmdef @@ -0,0 +1,36 @@ +{ + "name": "glTFast.Documentation.Examples", + "rootNamespace": "GLTFast.Documentation.Examples", + "references": [ + "Unity.Burst", + "Unity.Mathematics", + "glTFast", + "glTFast.Export", + "glTFast.Newtonsoft" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": false, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.animation", + "expression": "", + "define": "UNITY_ANIMATION" + }, + { + "name": "com.unity.modules.imageconversion", + "expression": "", + "define": "UNITY_IMAGECONVERSION" + }, + { + "name": "com.unity.nuget.newtonsoft-json", + "expression": "", + "define": "NEWTONSOFT_JSON" + } + ], + "noEngineReferences": false +} diff --git a/Samples/Documentation/Unity.Cloud.Gltfast.Documentation.asmdef.meta b/DocExamples/glTFast.Documentation.Examples.asmdef.meta similarity index 100% rename from Samples/Documentation/Unity.Cloud.Gltfast.Documentation.asmdef.meta rename to DocExamples/glTFast.Documentation.Examples.asmdef.meta diff --git a/Documentation~/ExportRuntime.md b/Documentation~/ExportRuntime.md index 956dee8d3..348e1166c 100644 --- a/Documentation~/ExportRuntime.md +++ b/Documentation~/ExportRuntime.md @@ -6,11 +6,12 @@ You can export individual GameObjects or entire scenes to glTF™ files at r To be able to export certain textures correctly, a couple of shaders are required. They are located at `Runtime/Shader/Export`. Make sure to include them all in your build. -The easiest way to include them is to add `glTFExport.shadervariants` to the list of *Preloaded Shaders* under *Project Settings* > *Graphics* > *Shader Loading*. +The easiest way to include them is to add the shader variant collection `glTFExport` to the list of *Preloaded Shaders* under *Project Settings* > *Graphics* > *Shader Loading*. ## Export via Script -> **NOTE:** The `GLTFast.Export` namespace can only be used if you reference both `glTFast` and `glTFast.Export` Assemblies in your [Assembly Definition][asmdef]. +> [!IMPORTANT] +> The `GLTFast.Export` namespace can only be used if you reference both `glTFast` and `glTFast.Export` Assemblies in your [Assembly Definition][asmdef]. Here's a step-by-step guide to export a GameObject hierarchy/scene from script @@ -22,23 +23,24 @@ Here's a step-by-step guide to export a GameObject hierarchy/scene from script glTF export might create more than one file. For example the binary buffer is usually a separate `.bin` file and textures might be separate files as well. -[!code-cs [simple-export](../Samples/Documentation/Manual/SimpleExport.cs#SimpleExport)] +[!code-cs [simple-export](../DocExamples/SimpleExport.cs#SimpleExport)] After calling [SaveToFileAndDispose](xref:GLTFast.Export.GameObjectExport.SaveToFileAndDispose*) the GameObjectExport instance becomes invalid. Do not re-use it. Further, the export can be customized by passing [ExportSettings](xref:GLTFast.Export.ExportSettings), [GameObjectExportSettings](xref:GLTFast.Export.GameObjectExportSettings) and injectables to [GameObjectExport](xref:GLTFast.Export.GameObjectExport)'s constructor: -[!code-cs [advanced-export](../Samples/Documentation/Manual/ExportSamples.cs#AdvancedExport)] +[!code-cs [advanced-export](../DocExamples/ExportSamples.cs#AdvancedExport)] -> **NOTE:** Exporting to a [Stream][Stream] currently only works for self-contained glTF-Binary files (where the binary buffer and all textures are included in the `.glb` file). Trying other export settings will fail. +> [!WARNING] +> Exporting to a [Stream][Stream] currently only works for self-contained glTF-Binary files (where the binary buffer and all textures are included in the `.glb` file). Trying other export settings will fail. ### Scene Origin -When adding GameObjects to a glTF scene, the resulting glTF root nodes' positions will be their original GameObjects' world position in the Unity scene. That might be undesirable (e.g. if the scene is far off the origin and thus not centered), so [AddScene](xref:GLTFast.Export.GameObjectExport.AddScene(ICollection{UnityEngine.GameObject},Unity.Mathematics.float4x4,System.String)) allows you to provide an inverse scene origin matrix that'll be applied to all root-level nodes. +When adding GameObjects to a glTF scene, the resulting glTF root nodes' positions will be their original GameObjects' world position in the Unity scene. That might be undesirable (e.g. if the scene is far off the origin and thus not centered), so [AddScene](xref:GLTFast.Export.GameObjectExport.AddScene(System.Collections.Generic.ICollection{UnityEngine.GameObject},Unity.Mathematics.float4x4,System.String)) allows you to provide an inverse scene origin matrix that'll be applied to all root-level nodes. Here's an example how to export a GameObject, discarding its transform: -[!code-cs [local-transform](../Samples/Documentation/Manual/ExportSamples.cs#LocalTransform)] +[!code-cs [local-transform](../DocExamples/ExportSamples.cs#LocalTransform)] ### Vertex Attribute Discarding @@ -52,13 +54,14 @@ Examples of vertex attribute discarding: - Normals and tangents, when the assigned material is unlit and does not require them for shading. - When no material was assigned, a default fallback material will be assumed. This does not require tangents nor texture coordinates, hence those are discarded. -> **NOTE:** Not all cases of potential discarding are covered at the moment (e.g. unused texture coordinates when no textures are assigned). +> [!NOTE] +> Not all cases of potential discarding are covered at the moment (e.g. unused texture coordinates when no textures are assigned). ### Draco Compression *Unity glTFast* supports applying [Google Draco™ 3D Data compression][Draco] to meshes. This requires the [Draco for Unity][DracoForUnity] package to be installed. -[!code-cs [draco-export](../Samples/Documentation/Manual/ExportSamples.cs#ExportSettingsDraco)] +[!code-cs [draco-export](../DocExamples/ExportSamples.cs#ExportSettingsDraco)] ## Trademarks diff --git a/Documentation~/Images/badge_linecoverage.svg b/Documentation~/Images/badge_linecoverage.svg deleted file mode 100644 index 293df367d..000000000 --- a/Documentation~/Images/badge_linecoverage.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - Code coverage - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Generated by: ReportGenerator 5.0.4.0 - - - - Coverage - Coverage - 70.4%70.4% - - - - - Line coverage - - - \ No newline at end of file diff --git a/Documentation~/ImportRuntime.md b/Documentation~/ImportRuntime.md index b922ff847..7afff1142 100644 --- a/Documentation~/ImportRuntime.md +++ b/Documentation~/ImportRuntime.md @@ -2,42 +2,48 @@ You can load a glTF™ asset from an URL or a file path. -> Note: glTFs are loaded via [UnityWebRequests](https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.html). File paths have to be prefixed with `file://` in the Unity Editor and on certain platforms (e.g. iOS). +> [!NOTE] +> By default glTFs are loaded via [UnityWebRequests](https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.html). File paths thus have to be prefixed with `file://` in the Unity Editor and on certain platforms (e.g. iOS). ## Runtime Loading via Component -Add a `GltfAsset` component to a GameObject. It offers a lot of settings for import and instantiation. +Add a [GltfAsset] component to a GameObject. It offers a lot of settings for import and instantiation. ![GltfAsset component][gltfasset_component] ## Runtime Loading via Script -```C# -var gltf = gameObject.AddComponent(); -gltf.Url = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF/Duck.gltf"; -``` +Conveniently you can re-use the [GltfAsset] component to load from script: -### Load from byte array +[!code-cs [load-via-component](../DocExamples/LoadGltfFromMemory.cs#LoadViaComponent)] -In case you want to handle download/file loading yourself, you can load glTF binary files directly from C# byte[] like so: +To load from sources other than a URI or for advanced [customization](#customize-loading-behavior), loading is performed with these generalized steps: -```csharp -async void LoadGltfBinaryFromMemory() { - var filePath = "/path/to/file.glb"; - byte[] data = File.ReadAllBytes(filePath); - var gltf = new GltfImport(); - bool success = await gltf.LoadGltfBinary( - data, - // The URI of the original data is important for resolving relative URIs within the glTF - new Uri(filePath) - ); - if (success) { - success = await gltf.InstantiateMainSceneAsync(transform); - } -} -``` +1. Create a [GltfImport] instance. +2. Call one of the instance's loading methods, depending on your source. + - From URI, [Load(Uri,…)](xref:GLTFast.GltfImportBase.Load(System.Uri,GLTFast.ImportSettings,System.Threading.CancellationToken)) or [Load(string,…)](xref:GLTFast.GltfImportBase.Load(System.String,GLTFast.ImportSettings,System.Threading.CancellationToken)) + - From a buffer [Load(NativeArray<byte>.ReadOnly,…)](xref:GLTFast.GltfImportBase.Load(Unity.Collections.NativeArray{System.Byte}.ReadOnly,System.Uri,GLTFast.ImportSettings,System.Threading.CancellationToken)) + - From a managed buffer [Load(byte[],…)](xref:GLTFast.GltfImportBase.Load(System.Byte[],System.Uri,GLTFast.ImportSettings,System.Threading.CancellationToken)) + - From a file path [LoadFile(string,…)](xref:GLTFast.GltfImportBase.LoadFile*) + - From a glTF JSON string [LoadGltfJson(string,…)][GltfImportLoadGltfJson] + - From a [Stream] [LoadStream(Stream,…)][GltfImportLoadStream] +3. Instantiate one ore more scenes however often you need. + - The main scene [InstantiateMainSceneAsync](xref:GLTFast.GltfImportBase.InstantiateMainSceneAsync*) + - Or select one by index [InstantiateSceneAsync](xref:GLTFast.GltfImportBase.InstantiateSceneAsync*) +4. Destroy your scene instances after they're no longer needed. +5. Call [Dispose](xref:GLTFast.GltfImportBase.Dispose) on your [GltfImport] instance. + +Both the loading and instantiation methods return a boolean value indicating if the procedure was successful. -> Note: Most users want to load self-contained glTF binary files this way, but `LoadGltfBinary` also takes the original URI of glTF file as second parameter, so it can resolve relative URIs. +> [!IMPORTANT] +> Loading/instantiation methods returning `true` merely indicates that no critical error occurred. That includes partially loaded scenes (e.g. a texture failed to load). To enforce stricter behavior one has to consider the log items in addition (see [Logging](#logging)). + +### Example: Load from byte array + +[!code-cs [load-gltf-from-memory](../DocExamples/LoadGltfFromMemory.cs#LoadGltfFromMemory)] + +> [!TIP] +> Provide the original URI of glTF-binary file as `uri` parameter to [LoadGltfBinary][GltfImportLoadGltfBinary], so that it is able to resolve relative URIs in non-self-contained glTFs. ## Customize loading behavior @@ -49,68 +55,20 @@ Loading via script allows you to: - Customize [instantiation](#instantiation) - Load glTF once and instantiate its scenes many times (see example [below](#custom-post-loading-behavior)) - Access data of glTF scene (for example get material; see example [below](#custom-post-loading-behavior)) -- [Logging](#logging) allow reacting and communicating incidents during loading and instantiation +- [Logging](#logging) allows reacting to and communicating incidents during loading and instantiation - Tweak and optimize loading performance ### Import Settings `GltfImport.Load` accepts an optional instance of [`ImportSettings`][ImportSettings] as parameter. Have a look at this class to see all options available. Here's an example usage: -```C# -async void Start() -{ - var gltf = new GLTFast.GltfImport(); - - // Create a settings object and configure it accordingly - var settings = new ImportSettings { - GenerateMipMaps = true, - AnisotropicFilterLevel = 3, - NodeNameMethod = NameImportMethod.OriginalUnique - }; - // Load the glTF and pass along the settings - var success = await gltf.Load("file:///path/to/file.gltf", settings); - - if (success) { - var gameObject = new GameObject("glTF"); - await gltf.InstantiateMainSceneAsync(gameObject.transform); - } - else { - Debug.LogError("Loading glTF failed!"); - } -} -``` +[!code-cs [import-settings](../DocExamples/LoadGltfFromMemory.cs#ImportSettings)] ### Custom Post-Loading Behavior The async `Load` method can be awaited and followed up by custom behavior. -```C# -async void Start() { - // First step: load glTF - var gltf = new GLTFast.GltfImport(); - var success = await gltf.Load("file:///path/to/file.gltf"); - - if (success) { - // Here you can customize the post-loading behavior - - // Get the first material - var material = gltf.GetMaterial(); - Debug.LogFormat("The first material is called {0}", material.name); - - // Instantiate the glTF's main scene - await gltf.InstantiateMainSceneAsync( new GameObject("Instance 1").transform ); - // Instantiate the glTF's main scene - await gltf.InstantiateMainSceneAsync( new GameObject("Instance 2").transform ); - - // Instantiate each of the glTF's scenes - for (int sceneId = 0; sceneId < gltf.SceneCount; sceneId++) { - await gltf.InstantiateSceneAsync(transform, sceneId); - } - } else { - Debug.LogError("Loading glTF failed!"); - } -} -``` +[!code-cs [instantiation](../DocExamples/LoadGltfFromMemory.cs#Instantiation)] ### Instantiation @@ -177,55 +135,27 @@ After a glTF scene was instanced, you can access selected components for further [`GameObjectInstantiator`][GameObjectInstantiator] provides a [`SceneInstance`][GameObjectSceneInstance] for that purpose. Here's some code that demonstrates how to access it -```csharp -async void Start() -{ - - var gltfImport = new GltfImport(); - await gltfImport.Load("test.gltf"); - var instantiator = new GameObjectInstantiator(gltfImport,transform); - var success = await gltfImport.InstantiateMainSceneAsync(instantiator); - if (success) { - - // Get the SceneInstance to access the instance's properties - var sceneInstance = instantiator.SceneInstance; - - // Enable the first imported camera (which are disabled by default) - if (sceneInstance.Cameras is { Count: > 0 }) { - sceneInstance.Cameras[0].enabled = true; - } - - // Decrease lights' ranges - if (sceneInstance.Lights != null) { - foreach (var glTFLight in sceneInstance.Lights) { - glTFLight.range *= 0.1f; - } - } - - // Play the default (i.e. the first) animation clip - var legacyAnimation = instantiator.SceneInstance.LegacyAnimation; - if (legacyAnimation != null) { - legacyAnimation.Play(); - } - } -} -``` +[!code-cs [SceneInstanceAccess](../DocExamples/LoadGltfFromMemory.cs#SceneInstanceAccess)] ### Logging When loading a glTF file, *Unity glTFast* logs messages of varying severity (errors, warnings or infos). Developers can choose what to make of those log messages. Examples: - Log to console in readable form +- React to non-critical errors (like an image texture failed to load) in a nuanced way - Feed the information into an analytics framework - Display details to the users -The provided component `GltfAsset` logs all of those messages to the console by default. +The [GltfAsset] component logs all of those messages to the console by default. + +You can customize logging by providing an implementation of [ICodeLogger][ICodeLogger] to the constructors of [GltfImport] or [GameObjectInstantiator]. -You can customize logging by providing an implementation of [`ICodeLogger`][ICodeLogger] to methods like `GltfImport.Load` or `GltfImport.InstantiateMainScene`. +> [!IMPORTANT] +> Not providing an `ICodeLogger` will disable logging altogether, which makes finding the cause of problems hard! Always use a logger like the `ConsoleLogger` during development. -There are two common implementations bundled. The `ConsoleLogger`, which logs straight to console (the default) and `CollectingLogger`, which stores messages in a list for users to process. +There are two common implementations bundled. The [ConsoleLogger][ConsoleLogger], which logs straight to console and [CollectingLogger][CollectingLogger], which stores messages in a list for users to process. -Look into [`ICodeLogger`][ICodeLogger] and [`LogMessages`][LogMessages] for details. +Look into [ICodeLogger][ICodeLogger] and [LogMessages][LogMessages] for details. ### Tune loading performance @@ -234,7 +164,7 @@ When loading glTFs, *Unity glTFast* let's you optimize towards one of two diamet - A stable frame rate - Fastest loading time -By default each `GltfAsset` instance tries not to block the main thread for longer than a certain time budget and defer the remaining loading process to the next frame / game loop iteration. +By default each [GltfAsset] instance tries not to block the main thread for longer than a certain time budget and defer the remaining loading process to the next frame / game loop iteration. If you load many glTF files at once, by default they won't be aware of each other and collectively might block the main game loop for too long. @@ -249,36 +179,12 @@ You can accomplish the same from script by calling `GltfImport.SetDefaultDeferAg For most granular control, you can pass a custom defer agent to each individual `GltfImport` instance: -```C# -async Task CustomDeferAgentPerGltfImport() { - // Recommended: Use a common defer agent across multiple GltfImport instances! - // For a stable frame rate: - IDeferAgent deferAgent = gameObject.AddComponent(); - // Or for faster loading: - deferAgent = new UninterruptedDeferAgent(); - - var tasks = new List(); - - foreach( var url in manyUrls) { - var gltf = new GLTFast.GltfImport(null,deferAgent); - var task = gltf.Load(url).ContinueWith( - async t => { - if (t.Result) { - await gltf.InstantiateMainSceneAsync(transform); - } - }, - TaskScheduler.FromCurrentSynchronizationContext() - ); - tasks.Add(task); - } - - await Task.WhenAll(tasks); -} -``` +[!code-cs [CustomDeferAgent](../DocExamples/LoadGltfFromMemory.cs#CustomDeferAgent)] -> Note 1: Depending on your glTF scene, using the `UninterruptedDeferAgent` may block the main thread for up to multiple seconds. Be sure to not do this during critical game play action. +> [!NOTE] +> Depending on your glTF scene, using the `UninterruptedDeferAgent` may block the main thread for up to multiple seconds. Be sure to not do this during critical game play action. > -> Note2 : Using the `TimeBudgetPerFrameDeferAgent` does **not** guarantee a stutter free frame rate. This is because some sub tasks of the loading routine (like uploading a texture to the GPU) may take too long, cannot be interrupted and **have** to be done on the main thread. +> Using the `TimeBudgetPerFrameDeferAgent` does **not** guarantee a stutter free frame rate. This is because some sub tasks of the loading routine (like uploading a texture to the GPU) may take too long, cannot be interrupted and **have** to be done on the main thread. ### Disposing Resources @@ -290,8 +196,15 @@ When you no longer need a loaded instance of a glTF scene you might want to remo *Khronos®* is a registered trademark and *glTF™* is a trademark of [The Khronos Group Inc][Khronos]. +[CollectingLogger]: xref:GLTFast.Logging.CollectingLogger +[ConsoleLogger]: xref:GLTFast.Logging.ConsoleLogger +[GltfAsset]: xref:GLTFast.GltfAsset [GltfImport]: xref:GLTFast.GltfImport -[GltfImportDispose]: xref:GLTFast.GltfImport.Dispose +[GltfImportDispose]: xref:GLTFast.GltfImportBase.Dispose +[GltfImportLoad]: xref:GLTFast.GltfImportBase.Load* +[GltfImportLoadGltfBinary]: xref:GLTFast.GltfImportBase.LoadGltfBinary* +[GltfImportLoadGltfJson]: xref:GLTFast.GltfImportBase.LoadGltfJson* +[GltfImportLoadStream]: xref:GLTFast.GltfImportBase.LoadStream* [GameObjectInstantiator]: xref:GLTFast.GameObjectInstantiator [gltfasset_component]: Images/gltfasset_component.png "Inspector showing a GltfAsset component added to a GameObject" [ICodeLogger]: xref:GLTFast.Logging.ICodeLogger @@ -302,6 +215,8 @@ When you no longer need a loaded instance of a glTF scene you might want to remo [InstantiationSettings]: xref:GLTFast.InstantiationSettings [Khronos]: https://www.khronos.org [LogMessages]: xref:GLTFast.Logging.LogMessages +[NativeArrayByteReadOnly]: xref:Unity.Collections.NativeArray`1.ReadOnly [GameObjectSceneInstance]: xref:GLTFast.GameObjectSceneInstance [SceneObjectCreation]: xref:GLTFast.SceneObjectCreation +[Stream]: xref:System.IO.Stream [Unity]: https://unity.com diff --git a/Documentation~/Original.md b/Documentation~/Original.md index 3a765e433..8ca31f624 100644 --- a/Documentation~/Original.md +++ b/Documentation~/Original.md @@ -14,8 +14,11 @@ Afterwards *glTFast* and further, optional packages are listed in the *Package M If you want to clone the GIT repository and installed the package locally (which is useful if you intend to develop glTFast itself), you have to checkout the branch `openupm`. +> [!IMPORTANT] +> Unlike the Unity fork, the `openupm` branch does not contain the full [content of the monorepo structure](./UpgradeGuides.md#repository-structure-monorepo)! It contains just a slightly modified variant of the package itself without tests, tools or test projects and is not recommended for [development](./development.md). + The package identifier in the `main` branch was changed, which likely leads to errors if you've cloned it before and pulled that change. In that case either switch to the `openupm` branch or [transition to the new package identifier][transition]. -[fork]: ./UpgradeGuides#unity-fork -[transition]: ./UpgradeGuides#transition-to-unity-gltfast +[fork]: ./UpgradeGuides.md#unity-fork +[transition]: ./UpgradeGuides.md#transition-to-unity-gltfast [OpenUPM]: https://openupm.com/ diff --git a/Documentation~/ProjectSetup.md b/Documentation~/ProjectSetup.md index 043ea5844..21d20317d 100644 --- a/Documentation~/ProjectSetup.md +++ b/Documentation~/ProjectSetup.md @@ -4,6 +4,8 @@ uid: doc-project-setup # Project Setup +This page explains how projects can be setup to fit your needs and tweaked in detail. As a prerequisite you first need to [install *glTFast*](installation.md). + ## Materials and Shader Variants For runtime import *Unity glTFast* uses custom shader graphs or shaders for rendering glTF™ materials. Depending on the properties of a glTF material (and extensions it relies on), a specific [shader variant][shader-variants] will get used. In the Editor this shader variant will be built on-demand, but in order for materials to work in your build, you **have** to make sure all shader variants that you're going to need are included. @@ -11,30 +13,58 @@ For runtime import *Unity glTFast* uses custom shader graphs or shaders for rend Including all possible variants is the safest approach, but can make your build very big. There's another way to find the right subset, if you already know what files you'll expect: - Run your scene that loads all glTFs you expect in the editor. -- Go to Edit->Project Settings->Graphics -- At the bottom end you'll see the "Shader Preloading" section +- Go to **Edit > Project Settings > Graphics** +- At the bottom end you'll see the *Shader Preloading* section - Save the currently tracked shaders/variants to an asset -- Take this ShaderVariantCollection asset and add it to the "Preloaded Shaders" list +- Take this ShaderVariantCollection asset and add it to the *Preloaded Shaders* list An alternative way is to create placeholder materials for all feature combinations you expect and put them in a "Resource" folder in your project. -Read the documentation about [`Shader.Find`](https://docs.unity3d.com/ScriptReference/Shader.Find.html) for details how to include shaders in builds. It's also recommended to learning more about [shader variants][shader-variants]. +Read the documentation about [Shader.Find](https://docs.unity3d.com/ScriptReference/Shader.Find.html) for details how to include shaders in builds. It's also recommended to learn more about [shader variants][shader-variants]. Depending on the Unity version and render pipeline in use, different shader graphs or shaders will be used. -- Shader graphs under `Runtime/Shader` for - - Universal render pipe 12 or newer - - High-Definition render pipe 10 or newer - - Built-in render pipe (experimental opt-in; see below) -- Shader graphs in folder `Runtime/Shader/HDRP` for HDRP-specific material types -- Shader graphs in folder `Runtime/Shader/Legacy` for older Universal / High-Definition render pipe versions -- Shaders in folder `Runtime/Shader/Built-In` for the built-in render pipeline +- Shader graphs in `Runtime/Shader` for + - [Universal Render Pipeline (URP)][URP] + - [High-Definition Render Pipeline (HDRP)][HDRP] + - [Built-In Render Pipeline (BiRP)][BiRP] (experimental opt-in; see below) +- Shader graphs in folder `Runtime/Shader/URP` for [URP] specific material types (e.g. clearcoat) +- Shader graphs in folder `Runtime/Shader/HDRP` for [HDRP] specific material types (e.g. StackLit) +- Shaders in folder `Runtime/Shader/Built-In` for [BiRP] +- Shared `Runtime/Shader/Includes` and `Runtime/Shader/SubGraphs` folders contain include files and shader subgraphs referenced by the shader graphs above; do not remove them when stripping unused content + +### Missing Shader Variants + +If a *glTFast* material renders correctly in Editor playmode, but does not in a player build, the cause is almost always one of two: + +1. **The shader asset itself is missing from the build.** *glTFast* logs an error of the form *"Shader "…" is missing. Make sure to include it in the build"* and material generation returns `null` for the affected mesh primitive. The renderer ends up without a material entirely (renders solid magenta). Add the shader to *Always Included Shaders* (**Edit > Project Settings > Graphics**) or reference it from a Resources folder so the build pipeline picks it up. +2. **The shader is included, but the specific keyword variant requested at runtime was stripped from the build** by Unity's shader variant stripping. What the user actually sees as a result depends on the *Strict Shader Variant Matching* player setting (see below). + +### Strict Shader Variant Matching + +*Strict Shader Variant Matching* is a Unity engine setting. It is configured under **Edit > Project Settings > Player > Other Settings > Shader Settings** and only changes behavior in player builds. + +- **Disabled (default):** Unity silently substitutes the closest available variant when an exact match for the requested keyword combination is missing. Materials still render, but *glTFast* features driven by keywords — normal mapping, alpha clipping, UV transforms, secondary UV sets, occlusion, transmission, double-sided rendering, etc. — may quietly produce wrong results without any console warning. +- **Enabled:** Unity refuses to substitute. The affected geometry renders with the **error (magenta) shader** and Unity logs an error naming the shader, subshader, pass and the requested keywords, making missing variants immediately visible. + +Because *glTFast*'s shaders combine many keywords, even small stripping mistakes can mask bugs that only surface for specific glTF assets. -## Texture Support +> [!TIP] +> Enabling *Strict Shader Variant Matching* while validating builds is recommended — it converts silent visual regressions into clear console errors. -In order to be able to import and export PNG and Jpeg textures, the built-in packages [*Unity Web Request Texture*][uwrt] (for loading image URIs) and [*Image Conversion*][ImgConv] have to be enabled. +### Shader Build Settings (Unity 6.3+) -So if you don't need PNG/Jpeg support (because you use only KTX™ 2.0 textures or no textures at all), you can disable those packages and reduce your build size a bit. +Unity 6.3 introduced [Shader Build Settings](https://docs.unity3d.com/6000.3/Documentation/Manual/shader-variant-stripping.html) under **Edit > Project Settings > Graphics > Shader Build Settings** (also configurable per build target through Build Profiles). It lets you list keyword sets and apply a *Type Override* of either: + +- `shader_feature` — strip variants of those keywords that are not statically reachable, or +- `dynamic_branch` — collapse variants into a runtime branch. + +Both reduce variant count, build size, shader load time, and runtime memory usage. + +Shader Build Settings **complements** `ShaderVariantCollection` / *Preloaded Shaders* workflow rather than replacing it: *Preloaded Shaders* warm up variants at runtime, while Shader Build Settings controls which variants exist in the build at all. + +> [!CAUTION] +> Aggressive stripping can remove *glTFast* variants that are only requested for specific glTF assets. Pair Shader Build Settings with *Strict Shader Variant Matching* (see above) so missing variants are caught during build validation instead of shipping as silent visual regressions. ### Shader Graphs and the Built-In Render Pipeline @@ -45,6 +75,12 @@ Built-In render pipe projects can optionally use the shader graphs instead of th - Installing Shader Graph version 12 or newer - Adding `GLTFAST_BUILTIN_SHADER_GRAPH` to the list of scripting define symbols in the project settings +## Optional Packages + +*glTFast* has soft-dependencies on some [optional packages](installation.md#optional-packages). By not installing those packages you might be able to reduce your final build size, so consider doing that. + +For example, if you don't need PNG/Jpeg support (because you use only KTX™ 2.0 textures or no textures at all), you can disable the *Image Conversion* and *UnityWebRequestTexture* modules. + ## Readable Mesh Data By default *Unity glTFast* discards mesh data after it was uploaded to the GPU to free up main memory (see [`markNoLongerReadable`](https://docs.unity3d.com/ScriptReference/Mesh.UploadMeshData.html)). You can disable this globally by using the scripting define `GLTFAST_KEEP_MESH_DATA`. @@ -73,9 +109,10 @@ add `GLTFAST_EDITOR_IMPORT_OFF` to the *Scripting Define Symbols* in the *Player *KTX™* and the KTX logo are trademarks of the [The Khronos Group Inc][khronos]. -[ImgConv]: https://docs.unity3d.com/2021.3/Documentation/ScriptReference/UnityEngine.ImageConversionModule.html +[BiRP]: https://docs.unity3d.com/6000.6/Documentation/Manual/built-in-render-pipeline.html +[HDRP]: https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/ [Khronos]: https://www.khronos.org [MRTK]: https://github.com/microsoft/MixedRealityToolkit-Unity [shader-variants]: https://docs.unity3d.com/Manual/shader-variants.html +[URP]: https://docs.unity3d.com/6000.6/Documentation/Manual/urp/urp-introduction.html [Unity]: https://unity.com -[uwrt]: https://docs.unity3d.com/2021.3/Documentation/ScriptReference/UnityEngine.UnityWebRequestTextureModule.html diff --git a/Documentation~/TableOfContents.md b/Documentation~/TableOfContents.md index 18adbd921..a9f6d9fcc 100644 --- a/Documentation~/TableOfContents.md +++ b/Documentation~/TableOfContents.md @@ -11,8 +11,14 @@ * [Project Setup](ProjectSetup.md) * Use Cases * [Use glTFast Add-on API to import custom data](UseCaseCustomExtras.md) +* [Development](development.md) + * [Sources](sources.md) + * [Test Project](test-project-setup.md) + * [Run Tests](tests.md) + * [Contributing](contributing.md) * More Information * [Known Issues](KnownIssues.md) * [Physical Light Units in glTF](LightUnits.md) * [Implementation Details](ImplementationDetails.md) + * [Code of Conduct](code-of-conduct.md) * [Apple Privacy Manifest](apple-privacy-manifest.md) diff --git a/Documentation~/UpgradeGuides.md b/Documentation~/UpgradeGuides.md index 96b98c0ea..1e52f3496 100644 --- a/Documentation~/UpgradeGuides.md +++ b/Documentation~/UpgradeGuides.md @@ -6,6 +6,24 @@ uid: doc-upgrade-guides These guides will help you upgrade your project to use the latest version of *Unity glTFast*. If you still encounter problems, help us improving this guide and *Unity glTFast* in general by reaching out by raising an issue. +## Repository Structure: Monorepo + +The Git repository of *glTFast* used to have the package content only at its root level. Shortly after version 6.8.0 this was changed to a [Monorepo][Monorepo] structure where the package resides in a sub-folder (`/Packages/com.unity.cloud.gltfast`). This was done so that the repository can also host additional content like test projects and assets that improve the development experience. Read the [development guide](development.md) and [Repository Structure](sources.md#repository-structure) for details. + +Users who installed *glTFast* via its package identifier/name won't notice a difference, but if you've [installed it via Git URL][GitPackageInstall] (usually for development purpose), you'll need to update the URL to include a `path` parameter like so: + +```none +https://github.com/Unity-Technologies/com.unity.cloud.gltfast.git?path=/Packages/com.unity.cloud.gltfast +``` + +You can do this by manually editing the URL in the [project manifest][ProjectManifest]. + +## Upgrade to 6.0 + +Use Unity 2021.3.46f1 or newer only. + +*GltfAnimation* was renamed to [Animation](xref:GLTFast.Schema.Animation). + ## Unity Fork With the release of version 5.2.0 the package name and identifier were changed to *Unity glTFast* (`com.unity.cloud.gltfast`) for the following reasons: @@ -20,7 +38,7 @@ For now, both the Unity variant and the original version will receive updates. The C# namespaces are identical between the variants, so all you need to do is: - Removed original *glTFast* (with package identifier `com.atteneder.gltfast`). -- [Install *Unity glTFast*](installation.html) (`com.unity.cloud.gltfast`). +- [Install *Unity glTFast*](installation.md) (`com.unity.cloud.gltfast`). - Update assembly definition references (if your project had any). - Update any dependencies in your packages manifest (if your package had any) @@ -260,10 +278,13 @@ In the future materials can be created before textures are available/downloaded [GameObjectInstantiator]: xref:GLTFast.GameObjectInstantiator [GameObjectSceneInstance]: xref:GLTFast.GameObjectSceneInstance +[GitPackageInstall]: https://docs.unity3d.com/Manual/upm-ui-giturl.html [gltf-spec-coords]: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#coordinate-system-and-units [GltfAsset]: xref:GLTFast.GltfAsset [gltfast3to4]: Images/gltfast3to4.png "3D scene view showing BoomBoxWithAxes model twice. One with the legacy axis conversion and one with the new orientation" [GltfImport]: xref:GLTFast.GltfImport +[Monorepo]: https://en.wikipedia.org/wiki/Monorepo +[ProjectManifest]: https://docs.unity3d.com/Manual/upm-git.html [IGltfReadable]: xref:GLTFast.IGltfReadable [ImgConv]: https://docs.unity3d.com/2021.3/Documentation/ScriptReference/UnityEngine.ImageConversionModule.html [OpenUPM]: https://openupm.com/ diff --git a/Documentation~/UseCaseCustomExtras.md b/Documentation~/UseCaseCustomExtras.md index 23c53507a..b3ddcd0bd 100644 --- a/Documentation~/UseCaseCustomExtras.md +++ b/Documentation~/UseCaseCustomExtras.md @@ -59,11 +59,11 @@ To create a custom glTF import behavior, follow these steps: 4. Select **C# Script**. 5. Rename the new script as `CustomGltfImport`. 6. Open the `CustomGltfImport` script and replace the content with the following: - [!code-cs [custom-gltf-import](../Samples/Documentation/Manual/CustomGltfImport.cs#CustomGltfImport)] + [!code-cs [custom-gltf-import](../DocExamples/CustomGltfImport.cs#CustomGltfImport)] 7. Repeat step 2-4 to create another new script 8. Rename the new script as `ExtraData`. 9. Open the `ExtraData` script and replace the content with the following: - [!code-cs [extra-data](../Samples/Documentation/Manual/ExtraData.cs#ExtraData)] + [!code-cs [extra-data](../DocExamples/ExtraData.cs#ExtraData)] ### Add assembly definitions @@ -92,7 +92,7 @@ To set up a new scene, follow these steps: Select **Play**, the glTF asset should be loaded and displayed at runtime. You can verify that the custom data in the `extras` property of the glTF is imported correctly by inspecting the loaded glTF asset: -![Screen capture that displays the extra data in the imported glTF asset](Images/gltf-extra-data.PNG) +![Screen capture that displays the extra data in the imported glTF asset](Images/gltf-extra-data.png) ## Trademarks diff --git a/Documentation~/UseCaseCustomPlayablesAnimation.md b/Documentation~/UseCaseCustomPlayablesAnimation.md new file mode 100644 index 000000000..82079e18d --- /dev/null +++ b/Documentation~/UseCaseCustomPlayablesAnimation.md @@ -0,0 +1,20 @@ +# Use case: Use Playables API for animation + +> [!CAUTION] +> This feature is obsolete! + +This use case was added in a previous version but has since been removed. It was not functioning correctly in builds due to the way animations are imported at runtime rather than in the editor. It is recommended to use legacy animation clips instead. + +Please refer to the following note copied from the [AnimationClip.SetCurve](https://docs.unity3d.com/6000.1/Documentation/ScriptReference/AnimationClip.SetCurve.html) documentation: + +> [!NOTE] +> `SetCurve` will only work at runtime for legacy animation clips. For non-legacy AnimationClips it is an editor-only function. + +## Trademarks + +*Unity®* is a registered trademark of [Unity Technologies][Unity]. + +*glTF™* is a trademark of [The Khronos Group Inc][Khronos]. + +[Khronos]: https://www.khronos.org +[Unity]: https://unity.com diff --git a/Documentation~/code-of-conduct.md b/Documentation~/code-of-conduct.md new file mode 100644 index 000000000..6d78d7a88 --- /dev/null +++ b/Documentation~/code-of-conduct.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team. +All complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at + +For answers to common questions about this code of conduct, see + + +[homepage]: https://www.contributor-covenant.org diff --git a/Documentation~/config.json b/Documentation~/config.json deleted file mode 100644 index df2b0d874..000000000 --- a/Documentation~/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "DefineConstants": "DRACO_UNITY;KTX_UNITY;KTX_UNITY_1_3_OR_NEWER;KTX_UNITY_2_2_OR_NEWER;USING_URP;USING_HDRP;USING_HDRP_10_OR_NEWER;UNITY_PHYSICS;UNITY_IMAGECONVERSION;UNITY_WEBREQUEST_TEXTURE;MESHOPT;USING_URP_12_OR_NEWER;UNITY_SHADER_GRAPH;UNITY_SHADER_GRAPH_12_OR_NEWER;UNITY_ANIMATION;UNITY_ENTITIES_GRAPHICS;NEWTONSOFT_JSON" -} \ No newline at end of file diff --git a/Documentation~/contributing.md b/Documentation~/contributing.md new file mode 100644 index 000000000..5a8aabb2f --- /dev/null +++ b/Documentation~/contributing.md @@ -0,0 +1,81 @@ +# Contributing + +Thank you for your interest in contributing to *glTFast*! We are +incredibly excited to see how members of our community will use and extend +*glTFast*. To facilitate your contributions, we've outlined a brief set +of guidelines to ensure that your extensions can be easily integrated. + +## Communication + +Please read through our [code of conduct][COC], as we expect all our contributors to follow it. + +## Contact + +For inquiries of all sorts there are ways to get in touch with the *glTFast* maintainers. + +- Create an [issue on GitHub][NewIssue] (preferred way for bug reports and feature requests) +- Post a reply in the [glTFast announcement post][Announcement] on [Unity Discussions][Discussions]. + +## Contribution Ideas + +If you're looking for ideas on ways to contribute browse the [issues][issues], +especially ones with the *help wanted* or *good first issue* label. + +## Preparation + +Before starting to work on a contribution we recommend searching within the +existing [issues][issues] and [pull requests][pulls] for similar topics to +avoid redundant efforts and make sure you got all contextual information. + +Feel free to propose ideas upfront via an [issue][NewIssue] that briefly outlines +your intended changes. We'll then try to give you advice and feedback on how to +optimally implement those changes or, if justifiable, reasons to abandon an +idea. This pre-evaluation can raise the chances of getting a contribution +accepted. + +## Version Control + +*glTFast* uses [Git][Git] and [GitHub][repo] for version control. + +## Submission via Pull Request + +Changes can be proposed via [pull requests (PR)][GithubDocPR] on the [pull requests][pulls] page. + +In order to get a positive review and increase the chances getting a PR merged, make sure the PR has the following traits. + +- Concise title. +- Detailed description of the proposed improvements. +- Testing + - All existing [tests](tests.md) pass. + - Added or modified code is covered by tests. Add new tests if needed. +- [Changelog][changelog] entry. +- Updates and additions to documentation, if applicable. +- References to issues that the PR resolves, if any. +- [Contributor License Agreements](#contributor-license-agreements) signed by all authors. + +PRs will be transferred to an internal, mirrored repository to undergo review and (automated) tests that use Unity® internal tools and infrastructure. If those tests and reviews are not successful, we'll try to help you resolving remaining issues. Once all problems are resolved, the actual merge will happen on the mirrored repository and the original pull requests will get closed with a proper notification about expected release version and date. + +## Contributor License Agreements + +When you open a pull request, you will be asked to acknowledge our [Contributor +License Agreement][GltfastCLA]. You will have to confirm that your Contributions are your +original creation and that you have complete right and authority to make your +contributions. We allow both individual contributions and contributions made on +behalf of companies. + +## Trademarks + +*Unity®* is a registered trademark of [Unity Technologies][unity]. + +[Announcement]: https://discussions.unity.com/t/unity-gltfast-package-is-now-available/935685 +[changelog]: https://keepachangelog.com/en/1.0.0/ +[COC]: code-of-conduct.md +[Discussions]: https://discussions.unity.com/ +[Git]: https://git-scm.com/ +[GltfastCLA]: https://cla-assistant.cds.internal.unity3d.com/Unity-Technologies/com.unity.cloud.gltfast +[repo]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast +[issues]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast/issues +[NewIssue]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast/issues/new/choose +[pulls]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pulls +[GithubDocPR]: https://docs.github.com/pull-requests +[unity]: https://unity.com diff --git a/Documentation~/development.md b/Documentation~/development.md new file mode 100644 index 000000000..b73f36bce --- /dev/null +++ b/Documentation~/development.md @@ -0,0 +1,22 @@ +# Development + +> [!CAUTION] +> To do meaningful development you have to [switch to the Unity fork](./UpgradeGuides#transition-to-unity-gltfast), as this repository/branch does not contain the tools, test and projects required for development. See [Download Sources](./sources.md#download-sources) to learn where to obtain said fork. + +Here's a guide to getting started with development, testing your modifications and making a contribution to *glTFast*. + +As prerequisites you'll need to [install](installation.md) a version of Unity® that is [compatible with *glTFast*](features.md#unity-version-support). + +- [Download Sources](sources.md#download-sources) +- [Test Projects](test-project-setup.md) + - [Provided Projects](test-project-setup.md#test-projects) + - [Custom Project](test-project-setup.md#setup-a-custom-project) +- [Load glTF files](test-open-file.md) +- [Run Tests](tests.md) +- [Contribute](contributing.md) + +## Trademarks + +*Unity®* is a registered trademark of [Unity Technologies][unity]. + +[unity]: https://unity.com diff --git a/Documentation~/features.md b/Documentation~/features.md index 86b40ffc0..5430cf66d 100644 --- a/Documentation~/features.md +++ b/Documentation~/features.md @@ -72,10 +72,9 @@ The glTF 2.0 specification is fully supported, with only a few minor remarks. | Per primitive material | ✅ | ✅ | Joints (up to 4 per vertex) | ✅ | ✅ | Weights (up to 4 per vertex) | ✅ | ✅ -| | | -| **Morph Targets / Blend Shapes** -| Sparse accessors | ² ✅ | | [Skins][Skins] | ✅ | ✅ +| Morph Targets (Blend Shapes) | ✅ | +| Sparse accessors | ² ✅ | | | | | **Animation** | via legacy Animation System | ✅ | @@ -90,6 +89,8 @@ The glTF 2.0 specification is fully supported, with only a few minor remarks. ## Extensions +glTF defines an [extension mechanism][gltf-ext] that allows the base format to be extended with new capabilities. Here's a list of extensions and their current state of support. + ### Official Khronos® extensions | | Import | Export @@ -101,6 +102,7 @@ The glTF 2.0 specification is fully supported, with only a few minor remarks. | KHR_lights_punctual | ✅ | ✅ | KHR_materials_anisotropy | | | | KHR_materials_clearcoat | ✅ | ✅ +| KHR_materials_diffuse_transmission | | | | KHR_materials_dispersion | | | | KHR_materials_emissive_strength | | | | KHR_materials_ior | [ℹ️][IOR] | @@ -306,7 +308,7 @@ Possibly incomplete list of things that are known to not work with Entities yet: ## Unity Version Support -*Unity glTFast* requires Unity 2020.1 or newer. +*Unity glTFast* requires Unity 6000.0 or newer. ## Legend @@ -335,6 +337,7 @@ Possibly incomplete list of things that are known to not work with Entities yet: [Entities]: https://docs.unity3d.com/Packages/com.unity.entities@latest [EntitiesGraphics]: https://docs.unity3d.com/Packages/com.unity.entities.graphics@latest [GoogleLLC]: https://about.google/ +[gltf-ext]: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#specifying-extensions [HDRP]: https://unity.com/srp/High-Definition-Render-Pipeline [IBL]: https://github.com/atteneder/glTFast/issues/108 [IOR]: https://github.com/atteneder/glTFast/issues/207 diff --git a/Documentation~/filter.yml b/Documentation~/filter.yml index 07beaff6b..65ab908bd 100644 --- a/Documentation~/filter.yml +++ b/Documentation~/filter.yml @@ -3,9 +3,3 @@ apiRules: hasAttribute: uid: System.ObsoleteAttribute type: Type - - exclude: - uidRegex: ^GLTFast\.Tests\..*$ - type: Namespace - - exclude: - uidRegex: ^Samples\..*$ - type: Namespace diff --git a/Documentation~/index.md b/Documentation~/index.md index 830872217..f10304b6d 100644 --- a/Documentation~/index.md +++ b/Documentation~/index.md @@ -1,17 +1,20 @@ # Unity glTFast Documentation -*Unity glTFast* enables use of [glTF™ (GL Transmission Format)][gltf] asset files in [Unity][unity]. +Use *glTFast* to import and export [glTF™][gltf] 3D files efficiently at runtime or in the Editor. -It focuses on speed, memory efficiency and a small build footprint while also providing: +## Installing -- 100% [glTF 2.0 specification][gltf-spec] compliance -- Ease of use -- Robustness and Stability -- Customization and extensibility for advanced users +*Unity glTFast* is a [Package][UnityPackage] and is installed via the name `com.unity.cloud.gltfast` in the Package Manager window in Unity®. See [installation](installation.md) for detailed instructions. ## Features -*Unity glTFast* supports the full [glTF 2.0 specification][gltf-spec] and many extensions. It works with Universal, High Definition and the Built-In Render Pipelines on all platforms. +Speed, memory efficiency and a small build footprint are focus points of *Unity glTFast*. + +The [glTF 2.0 specification][gltf-spec] and a large and growing number of [glTF extensions][gltf-ext] are supported. + +All platforms as well as Universal, High Definition and Built-In Render Pipelines are supported. + +Advanced users can customize or extend *glTFast* in various ways. See the [comprehensive list of supported features and extensions](./features.md). @@ -60,7 +63,8 @@ Read about [usage](ImportEditor.md) below. Use the Unity Editor as an authoring tool and export your scenes and GameObjects as *glTFs*. -> Note: This feature is experimental +> [!WARNING] +> This feature is experimental ##### Use-cases for Editor Export @@ -81,8 +85,6 @@ Allows your Unity-powered application/game to export scenes/GameObjects to glTF - Build high level editing and authoring tools with Unity - Social media sharing -> Note: This feature is coming soon (see [issue](https://github.com/atteneder/glTFast/issues/259)) - ## Trademarks *Unity®* is a registered trademark of [Unity Technologies][unity]. @@ -96,6 +98,8 @@ Allows your Unity-powered application/game to export scenes/GameObjects to glTF [gltf]: https://www.khronos.org/gltf [gltf-projects]: https://github.khronos.org/glTF-Project-Explorer [gltf-spec]: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html +[gltf-ext]: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#specifying-extensions [GoogleLLC]: https://about.google/ [khronos]: https://www.khronos.org [unity]: https://unity.com +[UnityPackage]: https://docs.unity3d.com/Manual/PackagesList.html diff --git a/Documentation~/installation.md b/Documentation~/installation.md index 7a5528ecf..2ff8f4698 100644 --- a/Documentation~/installation.md +++ b/Documentation~/installation.md @@ -2,23 +2,39 @@ ## Install the *Unity glTFast* package using the Unity Package Manager +> [!TIP] +> Click the following link to fast-track the installation and skip to step 5: [com.unity.cloud.gltfast](com.unity3d.kharma:upmpackage/com.unity.cloud.gltfast) + To install the *Unity glTFast* package, follow these steps: -- In your Unity project, go to Windows > Package Manager. -- On the status bar, select the Add (+) button. -- From the Add menu, select Add + package by name. Name and Version fields appear. -- In the Name field, enter `com.unity.cloud.gltfast`. -- Select Add. -- The Editor installs the latest available version of the package and any dependent packages. +1. In your Unity project, go to Windows > Package Manager. +2. On the status bar, select the Add (+) button. +3. From the Add menu, select Add + package by name. Name and Version fields appear. +4. In the Name field, enter `com.unity.cloud.gltfast`. +5. Click *Add*. +6. The Editor installs the latest available version of the package and any dependent packages. ## Optional Packages There are some related package that improve *Unity glTFast* by extending its feature set. +- [Built-in Packages](https://docs.unity3d.com/Manual/pack-build.html) + - [Image Conversion](https://docs.unity3d.com/6000.3/Documentation/ScriptReference/UnityEngine.ImageConversionModule.html) for import/export of Jpeg and PNG textures. + - [Unity Web Request Texture](https://docs.unity3d.com/6000.3/Documentation/ScriptReference/UnityEngine.UnityWebRequestTextureModule.html) for import of Jpeg/PNG images from URI. + - [Animation](https://docs.unity3d.com/6000.3/Documentation/ScriptReference/UnityEngine.AnimationModule.html) for animation playback. + - [Physics](https://docs.unity3d.com/6000.3/Documentation/ScriptReference/UnityEngine.PhysicsModule.html) to create a glTF scene's [bounding box collider](xref:UnityEngine.BoxCollider) via [GltfBoundsAsset](xref:GLTFast.GltfBoundsAsset). - [Draco™ for Unity][DracoForUnity] (provides support for [KHR_draco_mesh_compression][ExtDraco]) - [KTX™ for Unity][KtxUnity] (provides support for [KHR_texture_basisu][ExtBasisU]) - [*meshoptimizer decompression for Unity*][Meshopt] (provides support for [EXT_meshopt_compression][ExtMeshopt]) +## Project Setup + +With the package(s) installed you're ready to get started, but have a look at [Project Setup](ProjectSetup.md) to certify your builds work as expected as well and tweak the package's behavior overall. + +## Install from Source Repository + +If you intend to modify or develop *glTFast* you need to install it from the source repository. See the [development documentation](development.md) for instructions on how the [get the sources](sources.md) and [setup your project](test-project-setup.md#setup-a-custom-project). + ## Trademarks *Unity®* is a registered trademark of [Unity Technologies][unity]. diff --git a/Documentation~/projectMetadata.json b/Documentation~/projectMetadata.json new file mode 100644 index 000000000..9418ce423 --- /dev/null +++ b/Documentation~/projectMetadata.json @@ -0,0 +1,14 @@ +{ + "pmdt-additional-preprocessors": "UNITY_PHYSICS;UNITY_IMAGECONVERSION;UNITY_WEBREQUEST_TEXTURE;UNITY_ANIMATION", + "additional-dependencies": { + "com.unity.cloud.draco": "5.4.3", + "com.unity.cloud.ktx": "3.6.3", + "com.unity.collections": "1.4.0", + "com.unity.entities.graphics": "1.4.18", + "com.unity.mathematics": "1.3.0", + "com.unity.meshopt.decompress": "0.2.0-exp.1", + "com.unity.nuget.newtonsoft-json": "3.2.2", + "com.unity.render-pipelines.high-definition": "14.0.12", + "com.unity.render-pipelines.universal": "14.0.12" + } +} diff --git a/Documentation~/sources.md b/Documentation~/sources.md new file mode 100644 index 000000000..d0bbdb191 --- /dev/null +++ b/Documentation~/sources.md @@ -0,0 +1,56 @@ +# Sources + +## Download Sources + +*glTFast*'s sources are hosted in a [GitHub repository][UnityGltfastGitHub] that needs to be cloned (i.e. downloaded) first. + +> [!TIP] +> See [Cloning a repository][GitHubCloning] for detailed instructions how to download a repository. +> [Git LFS](https://git-lfs.com/) is used for binary files, so make sure your Git client handles it correctly. + +Clone via command line interface: + +```sh +git clone git@github.com:Unity-Technologies/com.unity.cloud.gltfast.git +``` + +This will download the repository into a sub-folder named `com.unity.cloud.gltfast`. + +> [!NOTE] +> Cloning requires authentication configured properly. + +## Repository Structure + +*glTFast* is part of a larger [Monorepo][Monorepo] and can be found in the subfolder `Packages/com.unity.cloud.gltfast`. + +Here's an overview of the repository structure. + +```none + +├── Packages +│ ├── com.unity.cloud.gltfast +│ └── com.unity.cloud.gltfast.tests +│ └── Assets~ +└── Projects + ├── glTFast-Test + └── ... +``` + +- *Packages* - Unity® packages + - *com.unity.cloud.gltfast* - The actual *glTFast* package + - *com.unity.cloud.gltfast.tests* - Test code and assets + - *Assets~* - glTF™ test assets +- *Projects* - see [Test Projects](test-project-setup.md#test-projects) + +## Trademarks + +*Unity®* is a registered trademark of [Unity Technologies][unity]. + +*Khronos®* is a registered trademark and [glTF™][gltf] is a trademark of [The Khronos Group Inc][khronos]. + +[GitHubCloning]: https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository +[gltf]: https://www.khronos.org/gltf +[khronos]: https://www.khronos.org +[Monorepo]: https://en.wikipedia.org/wiki/Monorepo +[UnityGltfastGitHub]: https://github.com/Unity-Technologies/com.unity.cloud.gltfast +[unity]: https://unity.com diff --git a/Documentation~/test-open-file.md b/Documentation~/test-open-file.md new file mode 100644 index 000000000..819de6d39 --- /dev/null +++ b/Documentation~/test-open-file.md @@ -0,0 +1,18 @@ +# Open glTF files + +During development there's often the need to load designated, custom glTF files. + +## Open glTF File Dialog + +A convenient way to do this is the *OpenGltfScene* scene, which is located in the project view under `Packages/Unity glTFast Tests/Tests/Runtime/Scenes` and enter play mode. An open file dialog for opening `.gltf`/`.glb` files will be displayed. The selected glTF file will be loaded and instantiated into the scene and can be inspected, if it succeeded. + +Press *Control* and *G* to repeatedly open the same open file dialog within the same play mode session. + +> [!NOTE] +> This convenient open file dialog works in the Editor only and won't work in a build. + +You can copy and modify the scene to make further adjustments like camera position, lighting, etc. + +## Custom Test Environment + +If you have many test iterations on one file or you want to load multiple files at once the open file dialog above might not work well for you. An alternative is to create a custom test scene that utilizes the [GltfAsset](ImportRuntime.md#runtime-loading-via-component) component or [custom load scripting](ImportRuntime.md#runtime-loading-via-script) to run your tailored test procedure. diff --git a/Documentation~/test-project-setup.md b/Documentation~/test-project-setup.md new file mode 100644 index 000000000..f0590fd6e --- /dev/null +++ b/Documentation~/test-project-setup.md @@ -0,0 +1,46 @@ +# Test Project Setup + +> [!CAUTION] +> To do meaningful development you have to [switch to the Unity fork](./UpgradeGuides#transition-to-unity-gltfast), as this repository/branch does not contain the tools, test and projects required for development. See [Download Sources](./sources.md#download-sources) to learn where to obtain said fork. + +You can get started quickly by opening one of the provided [test projects](#test-projects) or [setup a custom project](#setup-a-custom-project). + +## Test Projects + +This repository comes with test projects that are pre-configured to have all required packages installed and ready to run [tests](tests.md). + +### Project List + +| Project | Description | +|---------------------------|---------------------------------------------------------| +| glTFast-Test | Default project with all [optional packages](installation.md#optional-packages) installed. | +| glTFast-Test-minimalistic | Minimalistic setup with none of the optional dependency packages installed. | + +### Open a Project + +To open a project open [Unity® Hub][UnityHub], go to *Projects* and pick *Add* → *Add project from disk*. Select the respective project folder from within the `Projects` directory in your local copy. + +Upon opening the project you can pick a Unity version of your choice (within the range of [supported versions](features.md#unity-version-support)). In fact you might have to, if the predefined version is not installed. If you decide to work on more recent versions, keep in mind that for contributions your changes have to be backwards compatible to all supported versions. + +## Setup a Custom Project + +The setup of an existing project can give you a development context that is not covered by any of the provided [test projects](test-project-setup.md#test-projects). Examples are custom scripts for import/export of glTFs, the constellation of installed packages, the choice of [render pipeline][RenderPipelines] or use of [Entities][Entities]. + +In such scenarios it makes sense to setup the existing project for *glTFast* development. + +Prerequisite is that you have a [local copy of the repository](sources.md#download-sources). + +With your project opened, open the *Package Manager* and click the ➕ symbol at the top left. Select *Add package from disk* and navigate to `Packages/com.unity.cloud.gltfast/package.json` within your local copy. + +Repeat the same steps for the tests package at `Packages/com.unity.cloud.gltfast.tests/package.json`. + +You're now ready to start modifying *glTFast* and [run the tests](tests.md). + +## Trademarks + +*Unity®* is a registered trademark of [Unity Technologies][unity]. + +[Entities]: https://docs.unity3d.com/Packages/com.unity.entities@latest/ +[RenderPipelines]: https://docs.unity3d.com/Manual/render-pipelines.html +[unity]: https://unity.com +[UnityHub]: https://unity.com/unity-hub diff --git a/Documentation~/tests.md b/Documentation~/tests.md new file mode 100644 index 000000000..af81d6deb --- /dev/null +++ b/Documentation~/tests.md @@ -0,0 +1,55 @@ +# Tests + +> [!CAUTION] +> To do meaningful development you have to [switch to the Unity fork](./UpgradeGuides#transition-to-unity-gltfast), as this repository/branch does not contain the tools, test and projects required for development. See [Download Sources](./sources.md#download-sources) to learn where to obtain said fork. + +*glTFast* comes with a set of unit and integration tests that ensure the software functions without unexpected errors and certify the correctness of the results. Those tests and the assets they require can be found in the tests package under `Packages/com.unity.cloud.gltfast.tests`. + +Once your project is correctly setup (by either opening one of the provided [test projects](test-project-setup.md#test-projects) or following the steps to [setup your own project](test-project-setup.md#setup-a-custom-project)) you'll be able to run all tests via the *Test Runner* window (under *Window* → *General* → *Test Runner*; see [Test Framework documentation][UTFRunTests] for details about running tests). + +> [!NOTE] +> Passing all tests is a requirement for getting a [contribution](contributing.md) accepted. + +On an unmodified copy of *glTFast* all tests should pass. Once you start introducing changes it's recommended to periodically check that the tests still pass. + +If a test doesn't succeed you'll have to investigate if it revealed a flaw in you modification or the tests itself needs to be adjusted. + +## Adding Tests + +If you add new code to *glTFast* you should also add tests that certify correctness of the new code. + +For more information about creating and running tests, consult the documentation of the [Unity® Test Framework][UTF] + +## Test Assets + +Some tests consume glTF™ files or other kinds of test input data. Those test assets can be found in the hidden directory `Packages/com.unity.cloud.gltfast.tests/Assets~`. + +When tests are run in Editor playmode, the test assets are loaded from that location directly. + +When tests are run in a player build, `GLTFast.Editor.Tests.PreprocessBuild` copies all test assets into a directory named `gltfast` within [StreamingAssets][StreamingAssets], effectively packing the assets with the build and ensuring the files are accessible when the tests are run. + +> [!CAUTION] +> If you ran the tests in a production project, you need to remove the test folders in StreamingAssets to ensure they don't end up in a production build. + +## Performance Tests + +*glTFast* comes with a set of procedurally generated glTFs and tests dedicated to measure and track performance metrics. In order to run the performance tests the [Performance Testing Package for Unity Test Framework][UTFPerformance] has to be installed, otherwise they won't show up. + +The glTFs required for the tests have to be generated prior to running the tests by clicking *Tools* → *glTFast* → *Create performance test glTFs* from the main menu. + +> [!TIP] +> The performance test can be included or excluded from test runs via the *Performance* test category they've been assigned to. + +## Trademarks + +*Unity®* is a registered trademark of [Unity Technologies][unity]. + +*Khronos®* is a registered trademark and [glTF™][gltf] is a trademark of [The Khronos Group Inc][khronos]. + +[gltf]: https://www.khronos.org/gltf +[khronos]: https://www.khronos.org +[StreamingAssets]: https://docs.unity3d.com/Manual/StreamingAssets.html +[unity]: https://unity.com +[UTF]: https://docs.unity3d.com/Packages/com.unity.test-framework@latest/ +[UTFPerformance]: https://docs.unity3d.com/Packages/com.unity.test-framework.performance@latest/ +[UTFRunTests]: https://docs.unity3d.com/Packages/com.unity.test-framework@1.4/manual/workflow-run-test.html diff --git a/Editor/Scripts/AssemblyInfo.cs b/Editor/Scripts/AssemblyInfo.cs new file mode 100644 index 000000000..cb86af105 --- /dev/null +++ b/Editor/Scripts/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("glTFast.Editor.Tests")] diff --git a/Editor/Scripts/AssemblyInfo.cs.meta b/Editor/Scripts/AssemblyInfo.cs.meta new file mode 100644 index 000000000..1c878d9c5 --- /dev/null +++ b/Editor/Scripts/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0da5eda5fa95e4275ad1af63eda3dd54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Scripts/AsyncHelpers.cs b/Editor/Scripts/AsyncHelpers.cs index c2bd2bd3a..8f07ed88d 100644 --- a/Editor/Scripts/AsyncHelpers.cs +++ b/Editor/Scripts/AsyncHelpers.cs @@ -1,9 +1,9 @@ // Source: https://social.msdn.microsoft.com/Forums/en-US/163ef755-ff7b-4ea5-b226-bbe8ef5f4796/is-there-a-pattern-for-calling-an-async-method-synchronously?forum=async using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using System.Collections.Generic; namespace GLTFast.Utils { @@ -20,25 +20,32 @@ public static void RunSync(Func task) var sync = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(sync); // ReSharper disable once AsyncVoidLambda - sync.Post(async _ => + try { - try - { - await task(); - } - catch (Exception e) + sync.Post(async _ => { - sync.InnerException = e; - throw; - } - finally - { - sync.EndMessageLoop(); - } - }, null); - sync.BeginMessageLoop(); + try + { + await task(); + } + catch (Exception e) + { + sync.InnerException = e; + throw; + } + finally + { + sync.EndMessageLoop(); + } + }, null); - SynchronizationContext.SetSynchronizationContext(oldContext); + sync.BeginMessageLoop(); + } + finally + { + // Always restore the old context, even if there's an exception + SynchronizationContext.SetSynchronizationContext(oldContext); + } } /// @@ -54,24 +61,32 @@ public static T RunSync(Func> task) SynchronizationContext.SetSynchronizationContext(sync); T ret = default(T); // ReSharper disable once AsyncVoidLambda - sync.Post(async _ => + try { - try + sync.Post(async _ => { - ret = await task(); - } - catch (Exception e) - { - sync.InnerException = e; - throw; - } - finally - { - sync.EndMessageLoop(); - } - }, null); - sync.BeginMessageLoop(); - SynchronizationContext.SetSynchronizationContext(oldContext); + try + { + ret = await task(); + } + catch (Exception e) + { + sync.InnerException = e; + throw; + } + finally + { + sync.EndMessageLoop(); + } + }, null); + + sync.BeginMessageLoop(); + } + finally + { + // Always restore the old context, even if there's an exception + SynchronizationContext.SetSynchronizationContext(oldContext); + } return ret; } diff --git a/Editor/Scripts/BuiltInShaderGUI.cs b/Editor/Scripts/BuiltInShaderGUI.cs index a10cbecbb..ed5b606be 100644 --- a/Editor/Scripts/BuiltInShaderGUI.cs +++ b/Editor/Scripts/BuiltInShaderGUI.cs @@ -1,10 +1,11 @@ // SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 +using Unity.Mathematics; using UnityEditor; using UnityEngine; -using static GLTFast.Materials.MaterialGenerator; using static GLTFast.Materials.BuiltInMaterialGenerator; +using static GLTFast.Materials.MaterialGenerator; namespace GLTFast.Editor { @@ -70,7 +71,7 @@ public override void OnGUI(MaterialEditor materialEditor, UnityEditor.MaterialPr "Base Color Tex Rotation"); if (m_UVTransform.HasValue) { - if (m_UVTransform.Value.rotation != 0) + if (math.abs(m_UVTransform.Value.rotation) >= float.Epsilon) { material.EnableKeyword(TextureTransformKeyword); } diff --git a/Editor/Scripts/Constants.cs b/Editor/Scripts/Constants.cs new file mode 100644 index 000000000..3ccf92991 --- /dev/null +++ b/Editor/Scripts/Constants.cs @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2025 Unity Technologies and the glTFast authors +// SPDX-License-Identifier: Apache-2.0 + +using UnityEngine; + +namespace GLTFast.Editor +{ + static class Constants + { + public const string gltfExtension = "gltf"; + public const string gltfBinaryExtension = "glb"; + } +} diff --git a/Tests/Runtime/Scripts/Constants.cs.meta b/Editor/Scripts/Constants.cs.meta similarity index 83% rename from Tests/Runtime/Scripts/Constants.cs.meta rename to Editor/Scripts/Constants.cs.meta index ec6772713..43a1e7556 100644 --- a/Tests/Runtime/Scripts/Constants.cs.meta +++ b/Editor/Scripts/Constants.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 010a75c3d12e4521a8f278cd3264abaf +guid: 19321ba41adf44e7b8819d4f4731b62c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Scripts/EditorDownloadProvider.cs b/Editor/Scripts/EditorDownloadProvider.cs index 652bdea88..3e20e04b5 100644 --- a/Editor/Scripts/EditorDownloadProvider.cs +++ b/Editor/Scripts/EditorDownloadProvider.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using Unity.Collections; using UnityEditor; using UnityEngine; @@ -44,14 +45,19 @@ public async Task RequestTexture(Uri url, bool nonReadable) #pragma warning restore 1998 } - class SyncFileLoader : IDownload + class SyncFileLoader : IDownload, INativeDownload { + ReadOnlyNativeArrayFromManagedArray m_ManagedNativeArray; + public SyncFileLoader(Uri url) { var path = url.OriginalString; if (File.Exists(path)) { Data = File.ReadAllBytes(path); + // TODO: Is there a better way to load a file into a NativeArray, like AsyncReadManager? + m_ManagedNativeArray = new ReadOnlyNativeArrayFromManagedArray(Data); + NativeData = m_ManagedNativeArray.Array.AsNativeArrayReadOnly(); } else { @@ -68,7 +74,9 @@ public void Reset() { } public string Error { get; protected set; } public byte[] Data { get; private set; } - public string Text => System.Text.Encoding.UTF8.GetString(Data); + public NativeArray.ReadOnly NativeData { get; private set; } + + public string Text => Data != null ? System.Text.Encoding.UTF8.GetString(Data) : null; public bool? IsBinary { @@ -76,19 +84,31 @@ public bool? IsBinary { if (Success) { - return GltfGlobals.IsGltfBinary(Data); + return GltfGlobals.IsGltfBinary(NativeData); } return null; } } - public virtual void Dispose() + public void Dispose() { - Data = null; + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + m_ManagedNativeArray?.Dispose(); + m_ManagedNativeArray = null; + Data = null; + NativeData = default; + } } } - class SyncTextureLoader : SyncFileLoader, ITextureDownload + sealed class SyncTextureLoader : SyncFileLoader, ITextureDownload { public Texture2D Texture { get; private set; } @@ -105,9 +125,9 @@ public SyncTextureLoader(Uri url) } } - public override void Dispose() + protected override void Dispose(bool disposing) { - base.Dispose(); + base.Dispose(disposing); Texture = null; } } diff --git a/Editor/Scripts/GltfImporter.cs b/Editor/Scripts/GltfImporter.cs index 4d641e82d..1214adc9a 100644 --- a/Editor/Scripts/GltfImporter.cs +++ b/Editor/Scripts/GltfImporter.cs @@ -30,8 +30,6 @@ using UnityEngine.Rendering; using Object = UnityEngine.Object; -[assembly: InternalsVisibleTo("glTFast.Editor.Tests")] - namespace GLTFast.Editor { @@ -199,7 +197,7 @@ public override void OnImportAsset(AssetImportContext ctx) AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } - var meshes = m_Gltf.GetMeshes(); + var meshes = m_Gltf.Meshes; if (meshes != null) { foreach (var mesh in meshes) @@ -218,15 +216,19 @@ public override void OnImportAsset(AssetImportContext ctx) #if UNITY_ANIMATION var clips = m_Gltf.GetAnimationClips(); - if (clips != null) { - foreach (var animationClip in clips) { - if (animationClip == null) { + if (clips != null) + { + foreach (var animationClip in clips) + { + if (animationClip == null) + { continue; } - if (importSettings.AnimationMethod == AnimationMethod.Mecanim) { + if (importSettings.AnimationMethod == AnimationMethod.Mecanim) + { var settings = AnimationUtility.GetAnimationClipSettings(animationClip); settings.loopTime = true; - AnimationUtility.SetAnimationClipSettings (animationClip, settings); + AnimationUtility.SetAnimationClipSettings(animationClip, settings); } AddObjectToAsset(ctx, $"animations/{animationClip.name}", animationClip); } @@ -292,6 +294,8 @@ public override void OnImportAsset(AssetImportContext ctx) Debug.LogError($"Failed to import {assetPath} (see inspector for details)", this); } reportItems = reportItemList.ToArray(); + + m_Gltf.DisposeRequiredForInstantiationData(); } void ImportScene( @@ -327,21 +331,23 @@ void ImportScene( { throw new InvalidOperationException("Instantiating scene failed"); } - var useFirstChild = true; - var multipleNodes = scene.nodes.Length > 1; + var useFirstChild = scene.nodes is { Length: > 0 }; + var singleNode = scene.nodes is { Length: 1 }; var hasAnimation = false; #if UNITY_ANIMATION if (importSettings.AnimationMethod != AnimationMethod.None - && (instantiationSettings.Mask & ComponentType.Animation) != 0) { + && (instantiationSettings.Mask & ComponentType.Animation) != 0) + { var animationClips = m_Gltf.GetAnimationClips(); - if (animationClips != null && animationClips.Length > 0) { + if (animationClips != null && animationClips.Length > 0) + { hasAnimation = true; } } #endif if (instantiationSettings.SceneObjectCreation == SceneObjectCreation.Never - || instantiationSettings.SceneObjectCreation == SceneObjectCreation.WhenMultipleRootNodes && !multipleNodes) + || instantiationSettings.SceneObjectCreation == SceneObjectCreation.WhenMultipleRootNodes && singleNode) { // No scene GameObject was created, so the first // child is the first (and in this case only) node. diff --git a/Editor/Scripts/ImportSettingsEditor.cs b/Editor/Scripts/ImportSettingsEditor.cs index 6961f5965..2a66c21c4 100644 --- a/Editor/Scripts/ImportSettingsEditor.cs +++ b/Editor/Scripts/ImportSettingsEditor.cs @@ -33,6 +33,7 @@ internal static void CreateUI(SerializedObject serializedObject, VisualElement c // Group texture related properties in a foldout var properties = new[] { serializedObject.FindProperty($"{pathPrefix}generateMipMaps"), + serializedObject.FindProperty($"{pathPrefix}texturesReadable"), serializedObject.FindProperty($"{pathPrefix}defaultMinFilterMode"), serializedObject.FindProperty($"{pathPrefix}defaultMagFilterMode"), serializedObject.FindProperty($"{pathPrefix}anisotropicFilterLevel"), diff --git a/Editor/Scripts/InstantiationSettingsEditor.cs b/Editor/Scripts/InstantiationSettingsEditor.cs index 519cbffc0..3c900bfcf 100644 --- a/Editor/Scripts/InstantiationSettingsEditor.cs +++ b/Editor/Scripts/InstantiationSettingsEditor.cs @@ -30,9 +30,7 @@ internal static void CreateUI(SerializedObject serializedObject, VisualElement c prop = serializedObject.FindProperty($"{pathPrefix}layer"); var layerField = new LayerField("Destination Layer"); -#if UNITY_2021_2_OR_NEWER layerField.AddToClassList(BaseField.alignedFieldUssClassName); -#endif layerField.BindProperty(prop); container.Add(layerField); diff --git a/Editor/Scripts/MaterialsVariantsComponentInspector.cs b/Editor/Scripts/MaterialsVariantsComponentInspector.cs index 257251e90..a338895f5 100644 --- a/Editor/Scripts/MaterialsVariantsComponentInspector.cs +++ b/Editor/Scripts/MaterialsVariantsComponentInspector.cs @@ -14,30 +14,24 @@ class MaterialsVariantsComponentInspector : UnityEditor.Editor [SerializeField] VisualTreeAsset m_MainMarkup; List m_VariantNames; -#if UNITY_2021_2_OR_NEWER DropdownField m_Dropdown; -#endif public override VisualElement CreateInspectorGUI() { - if (m_VariantNames == null) + var control = (target as MaterialsVariantsComponent)?.Control; + if (control != null && m_VariantNames == null) { - var control = (target as MaterialsVariantsComponent)?.Control; - if (control != null) + var count = control.MaterialsVariantsCount; + m_VariantNames = new List(count + 1) + { + "" + }; + for (var variantIndex = 0; variantIndex < count; variantIndex++) { - var count = control.MaterialsVariantsCount; - m_VariantNames = new List(count + 1) - { - "" - }; - for (var variantIndex = 0; variantIndex < count; variantIndex++) - { - m_VariantNames.Add(control.GetMaterialsVariantName(variantIndex)); - } + m_VariantNames.Add(control.GetMaterialsVariantName(variantIndex)); } } var myInspector = new VisualElement(); -#if UNITY_2021_2_OR_NEWER m_MainMarkup.CloneTree(myInspector); m_Dropdown = myInspector.Query().First(); @@ -48,33 +42,13 @@ public override VisualElement CreateInspectorGUI() else { m_Dropdown.choices = m_VariantNames; - m_Dropdown.index = 0; + m_Dropdown.index = control != null ? control.CurrentVariantIndex + 1 : 0; m_Dropdown.RegisterValueChangedCallback(OnMaterialsVariantChanged); myInspector.Add(m_Dropdown); } -#else - if (m_VariantNames == null) - { - myInspector.SetEnabled(false); - } - else - { - for (var i = 0; i < m_VariantNames.Count; i++) - { - var button = new Button - { - text = m_VariantNames[i] - }; - - button.RegisterCallback(OnVariantButtonClicked, i - 1); // asset is the root visual element that will be closed - myInspector.Add(button); - } - } -#endif return myInspector; } -#if UNITY_2021_2_OR_NEWER void OnMaterialsVariantChanged(ChangeEvent evt) { var control = (target as MaterialsVariantsComponent)?.Control; @@ -83,15 +57,5 @@ void OnMaterialsVariantChanged(ChangeEvent evt) _ = control.ApplyMaterialsVariantAsync(m_Dropdown.index - 1); } } -#else - void OnVariantButtonClicked(ClickEvent evt, int variantIndex) - { - var control = (target as MaterialsVariantsComponent)?.Control; - if (control != null) - { - _ = control.ApplyMaterialsVariantAsync(variantIndex); - } - } -#endif } } diff --git a/Editor/Scripts/MenuEntries.cs b/Editor/Scripts/MenuEntries.cs index 1cdf1bea2..137af1b63 100644 --- a/Editor/Scripts/MenuEntries.cs +++ b/Editor/Scripts/MenuEntries.cs @@ -1,16 +1,19 @@ // SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 +using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using GLTFast.Export; -using GLTFast.Utils; using UnityEditor; using UnityEngine; using UnityEngine.SceneManagement; +// MenuItem are designed for `static void` signatures, but `async Task` is required for the async export methods. +// ReSharper disable Unity.IncorrectMethodSignature #if GLTF_VALIDATOR -using Unity.glTF.Validator; +using UnityEditor.Formats.Gltf.Validation; #endif namespace GLTFast.Editor @@ -20,10 +23,6 @@ namespace GLTFast.Editor static class MenuEntries { - - const string k_GltfExtension = "gltf"; - const string k_GltfBinaryExtension = "glb"; - static string SaveFolderPath { get @@ -45,9 +44,16 @@ static bool ExportSelectionValidate() } [MenuItem("Assets/Export glTF/glTF (.gltf)", false, 31)] - static void ExportSelectionMenu() + static async Task ExportSelectionMenu() { - ExportSelection(false); + try + { + await ExportSelection(false); + } + catch (Exception e) + { + Debug.LogException(e); + } } [MenuItem("Assets/Export glTF/glTF-Binary (.glb)", true)] @@ -57,9 +63,16 @@ static bool ExportSelectionBinaryValidate() } [MenuItem("Assets/Export glTF/glTF-Binary (.glb)", false, 32)] - static void ExportSelectionBinaryMenu() + static async Task ExportSelectionBinaryMenu() { - ExportSelection(true); + try + { + await ExportSelection(true); + } + catch (Exception e) + { + Debug.LogException(e); + } } [MenuItem("GameObject/Export glTF/glTF (.gltf)", true)] @@ -69,9 +82,16 @@ static bool ExportGameObjectValidate() } [MenuItem("GameObject/Export glTF/glTF (.gltf)", false, 32)] - static void ExportGameObjectMenu(MenuCommand command) + static async Task ExportGameObjectMenu(MenuCommand command) { - ExportGameObject(command, false); + try + { + await ExportGameObject(command, false); + } + catch (Exception e) + { + Debug.LogException(e); + } } [MenuItem("GameObject/Export glTF/glTF-Binary (.glb)", true)] @@ -81,29 +101,36 @@ static bool ExportGameObjectBinaryValidate() } [MenuItem("GameObject/Export glTF/glTF-Binary (.glb)", false, 31)] - static void ExportGameObjectBinaryMenu(MenuCommand command) + static async Task ExportGameObjectBinaryMenu(MenuCommand command) { - ExportGameObject(command, true); + try + { + await ExportGameObject(command, true); + } + catch (Exception e) + { + Debug.LogException(e); + } } - static void ExportGameObject(MenuCommand command, bool binary) + static async Task ExportGameObject(MenuCommand command, bool binary) { var go = command.context as GameObject; if (go != null) { - Export(binary, go.name, new[] { go }); + await Export(binary, go.name, new[] { go }); } else if (TryGetExportNameAndGameObjects(out var name, out var gameObjects)) { - Export(binary, name, gameObjects); + await Export(binary, name, gameObjects); } } - static void ExportSelection(bool binary) + static async Task ExportSelection(bool binary) { if (TryGetExportNameAndGameObjects(out var name, out var gameObjects)) { - Export(binary, name, gameObjects); + await Export(binary, name, gameObjects); } else { @@ -111,9 +138,9 @@ static void ExportSelection(bool binary) } } - static void Export(bool binary, string name, GameObject[] gameObjects) + static async Task Export(bool binary, string name, GameObject[] gameObjects) { - var extension = binary ? k_GltfBinaryExtension : k_GltfExtension; + var extension = binary ? Constants.gltfBinaryExtension : Constants.gltfExtension; var path = EditorUtility.SaveFilePanel( "glTF Export Path", SaveFolderPath, @@ -122,21 +149,29 @@ static void Export(bool binary, string name, GameObject[] gameObjects) ); if (!string.IsNullOrEmpty(path)) { - SaveFolderPath = Directory.GetParent(path)?.FullName; - var settings = GetDefaultSettings(binary); - var goSettings = new GameObjectExportSettings { OnlyActiveInHierarchy = false }; - var export = new GameObjectExport(settings, gameObjectExportSettings: goSettings, logger: new ConsoleLogger()); - export.AddScene(gameObjects, name); - var success = AsyncHelpers.RunSync(() => export.SaveToFileAndDispose(path)); + await Export(path, binary, name, gameObjects); + } + } + internal static async Task Export(string destinationPath, bool binary, string name, GameObject[] gameObjects) + { + SaveFolderPath = Directory.GetParent(destinationPath)?.FullName; + var settings = GetDefaultSettings(binary); + var goSettings = new GameObjectExportSettings { OnlyActiveInHierarchy = false }; + var export = new GameObjectExport(settings, gameObjectExportSettings: goSettings, logger: new ConsoleLogger()); + export.AddScene(gameObjects, name); #if GLTF_VALIDATOR - if (success) - { - var report = Validator.Validate(path); - report.Log(); - } + var success = #endif + await export.SaveToFileAndDispose(destinationPath); + +#if GLTF_VALIDATOR + if (success) + { + var report = Validator.Validate(destinationPath); + report.Log(); } +#endif } static ExportSettings GetDefaultSettings(bool binary) @@ -149,22 +184,36 @@ static ExportSettings GetDefaultSettings(bool binary) } [MenuItem("File/Export Scene/glTF (.gltf)", false, 173)] - static void ExportSceneMenu() + static async Task ExportSceneMenu() { - ExportScene(false); + try + { + await ExportScene(false); + } + catch (Exception e) + { + Debug.LogException(e); + } } [MenuItem("File/Export Scene/glTF-Binary (.glb)", false, 174)] - static void ExportSceneBinaryMenu() + static async Task ExportSceneBinaryMenu() { - ExportScene(true); + try + { + await ExportScene(true); + } + catch (Exception e) + { + Debug.LogException(e); + } } - static void ExportScene(bool binary) + static async Task ExportScene(bool binary) { var scene = SceneManager.GetActiveScene(); var gameObjects = scene.GetRootGameObjects(); - var extension = binary ? k_GltfBinaryExtension : k_GltfExtension; + var extension = binary ? Constants.gltfBinaryExtension : Constants.gltfExtension; var path = EditorUtility.SaveFilePanel( "glTF Export Path", @@ -178,7 +227,7 @@ static void ExportScene(bool binary) var settings = GetDefaultSettings(binary); var export = new GameObjectExport(settings, logger: new ConsoleLogger()); export.AddScene(gameObjects, scene.name); - AsyncHelpers.RunSync(() => export.SaveToFileAndDispose(path)); + await export.SaveToFileAndDispose(path); #if GLTF_VALIDATOR var report = Validator.Validate(path); report.Log(); diff --git a/Editor/Scripts/OnScriptsReloadHandler.cs b/Editor/Scripts/OnScriptsReloadHandler.cs index c0ecdb714..308e6fadd 100644 --- a/Editor/Scripts/OnScriptsReloadHandler.cs +++ b/Editor/Scripts/OnScriptsReloadHandler.cs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using UnityEditor; -using UnityEngine; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; +using UnityEngine; namespace GLTFast { @@ -18,7 +18,8 @@ static class OnScriptsReloadHandler static ListRequest s_Request; [UnityEditor.Callbacks.DidReloadScripts] - static void OnScriptsReloaded() { + static void OnScriptsReloaded() + { s_Request = Client.List(); EditorApplication.update += Progress; } @@ -27,17 +28,22 @@ static void Progress() { if (s_Request.IsCompleted) { - if (s_Request.Status == StatusCode.Success) { - foreach (var package in s_Request.Result) { - if (package.name == GltfGlobals.GltfPackageName) { + if (s_Request.Status == StatusCode.Success) + { + foreach (var package in s_Request.Result) + { + if (package.name == GltfGlobals.GltfPackageName) + { var version = package.version; - if (Export.Constants.version != version) { + if (Export.Constants.version != version) + { Debug.LogWarning($"Version mismatch in Constants.cs (is {Export.Constants.version}, should be {version}). Please update!"); } } } } - else if (s_Request.Status >= StatusCode.Failure) { + else if (s_Request.Status >= StatusCode.Failure) + { Debug.Log(s_Request.Error.message); } diff --git a/Editor/Scripts/PackageSetupCheck.cs b/Editor/Scripts/PackageSetupCheck.cs index 775fa47a6..e21383573 100644 --- a/Editor/Scripts/PackageSetupCheck.cs +++ b/Editor/Scripts/PackageSetupCheck.cs @@ -1,21 +1,16 @@ // SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 -#if UNITY_2021_2_OR_NEWER -#define HYPERLINK -#define COMBINED -#endif - using System; -using System.Collections.Generic; using UnityEditor; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; using UnityEngine; +using UnityEngine.TestTools; namespace GLTFast.Editor { - [InitializeOnLoad] + [InitializeOnLoad, ExcludeFromCoverage] static class PackageSetupCheck { static ListRequest s_ListRequest; @@ -48,9 +43,7 @@ static PackageSetupCheck() { EditorApplication.update += WaitForPackageList; s_ListRequest = Client.List(true); -#if HYPERLINK EditorGUI.hyperLinkClicked += HyperLinkClicked; -#endif } static void WaitForPackageList() @@ -90,10 +83,9 @@ PackageReplacement pkg } } -#if HYPERLINK static void HyperLinkClicked(EditorWindow window, HyperLinkClickedEventArgs args) { - if(args.hyperLinkData.TryGetValue("command", out var command) && command=="replace") + if (args.hyperLinkData.TryGetValue("command", out var command) && command == "replace") { if (args.hyperLinkData.TryGetValue("arg", out var pkg)) { @@ -107,9 +99,7 @@ static void HyperLinkClicked(EditorWindow window, HyperLinkClickedEventArgs args } } } -#endif -#if COMBINED static void ReplacePackage(PackageReplacement package) { if (EditorUtility.DisplayDialog( @@ -126,7 +116,6 @@ static void ReplacePackage(PackageReplacement package) ); } } -#endif } struct PackageReplacement @@ -144,14 +133,9 @@ public void LogUpgradeMessage() var message = $"Deprecated package {legacyName} ({legacyIdentifier}) detected!\n" + $"glTFast now requires {name} ({identifier}) instead to provide support for " + $"{feature}.\n"; -#if HYPERLINK message += $"You can automatically replace the " + $"deprecated package or do it manually following the documentation."; -#else - message += "To upgrade the package, follow the documentation at " + - $"{upgradeDocsUri}"; -#endif Debug.LogWarning(message); } } diff --git a/Editor/Scripts/ShaderGUIBase.cs b/Editor/Scripts/ShaderGUIBase.cs index 3c2b1ae8f..bbff52085 100644 --- a/Editor/Scripts/ShaderGUIBase.cs +++ b/Editor/Scripts/ShaderGUIBase.cs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using Unity.Mathematics; using UnityEditor; using UnityEngine; -using Unity.Mathematics; using static GLTFast.Materials.MaterialGenerator; namespace GLTFast.Editor @@ -77,7 +77,7 @@ class ShaderGUIBase : ShaderGUI float2x2 rotScale = math.mul(new float2x2(cos, sin, -sin, cos), new float2x2(newUvTransform.scale.x, 0, 0, newUvTransform.scale.y)); material.SetVector(scaleTransformPropertyId, new Vector4(rotScale.c0.x, rotScale.c1.y, currentScaleTransform.z, currentScaleTransform.w)); material.SetVector(rotationPropertyId, new Vector4(rotScale.c1.x, rotScale.c0.y, 0, 0)); - if (newUvTransform.rotation == 0) + if (math.abs(newUvTransform.rotation) < float.Epsilon) { material.DisableKeyword(TextureTransformKeyword); } diff --git a/Editor/Scripts/ShaderGraphGUI.cs b/Editor/Scripts/ShaderGraphGUI.cs index 6dea276eb..0a59069a6 100644 --- a/Editor/Scripts/ShaderGraphGUI.cs +++ b/Editor/Scripts/ShaderGraphGUI.cs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 -#if USING_URP || USING_HDRP || (UNITY_SHADER_GRAPH_12_OR_NEWER && GLTFAST_BUILTIN_SHADER_GRAPH) +#if USING_URP || USING_HDRP || GLTFAST_BUILTIN_SHADER_GRAPH #define GLTFAST_SHADER_GRAPH #endif @@ -18,16 +18,18 @@ class ShaderGraphGUI : ShaderGUIBase public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { - if (materialEditor.target is Material material) { + if (materialEditor.target is Material material) + { m_UVTransform = TextureRotationSlider( material, m_UVTransform, Materials.MaterialProperty.BaseColorTextureScaleTransform, Materials.MaterialProperty.BaseColorTextureRotation, - label:"Base Color Tex Rotation" + label: "Base Color Tex Rotation" ); - if (GUI.changed) { + if (GUI.changed) + { EditorUtility.SetDirty(material); } } diff --git a/Editor/Scripts/glTFast.Editor.asmdef b/Editor/Scripts/glTFast.Editor.asmdef index 57fae5031..3c56952b8 100644 --- a/Editor/Scripts/glTFast.Editor.asmdef +++ b/Editor/Scripts/glTFast.Editor.asmdef @@ -7,7 +7,7 @@ "glTFast.Export", "UnityEngine.TestTools.Graphics", "Unity.RenderPipelines.HighDefinition.Runtime", - "com.unity.formats.gltf.validator.Editor" + "UnityEditor.Formats.Gltf.Validation" ], "includePlatforms": [ "Editor" @@ -41,7 +41,7 @@ }, { "name": "com.unity.formats.gltf.validator", - "expression": "", + "expression": "0.2.0-preview.1", "define": "GLTF_VALIDATOR" } ], diff --git a/Editor/UI/GltfImporter.uxml b/Editor/UI/GltfImporter.uxml index 7827f3686..1ed1a4ef1 100644 --- a/Editor/UI/GltfImporter.uxml +++ b/Editor/UI/GltfImporter.uxml @@ -1,7 +1,7 @@