├── .github └── workflows │ ├── docs.yml │ ├── release.yml │ └── run-tests.yml ├── .gitignore ├── .vsconfig ├── Assets └── .gitkeep ├── Documents ├── .gitignore ├── docfx.json ├── docs │ ├── en │ │ ├── getting-started.md │ │ ├── introduction.md │ │ └── toc.yml │ ├── ja │ │ ├── getting-started.md │ │ ├── introduction.md │ │ └── toc.yml │ └── toc.yml ├── images │ └── logo.svg ├── index.md └── toc.yml ├── LICENSE.md ├── Packages ├── .gitignore ├── com.ramtype0.meshia.mesh-simplification │ ├── Ndmf.meta │ ├── Ndmf │ │ ├── Editor.meta │ │ ├── Editor │ │ │ ├── Meshia.MeshSimplification.Ndmf.Editor.asmdef │ │ │ ├── Meshia.MeshSimplification.Ndmf.Editor.asmdef.meta │ │ │ ├── MeshiaMeshSimplifierEditor.cs │ │ │ ├── MeshiaMeshSimplifierEditor.cs.meta │ │ │ ├── MeshiaMeshSimplifierEditor.uxml │ │ │ ├── MeshiaMeshSimplifierEditor.uxml.meta │ │ │ ├── NdmfPlugin.cs │ │ │ └── NdmfPlugin.cs.meta │ │ ├── Runtime.meta │ │ └── Runtime │ │ │ ├── Meshia.MeshSimplification.Ndmf.Runtime.asmdef │ │ │ ├── Meshia.MeshSimplification.Ndmf.Runtime.asmdef.meta │ │ │ ├── MeshiaMeshSimplifier.cs │ │ │ └── MeshiaMeshSimplifier.cs.meta │ ├── Runtime.meta │ ├── Runtime │ │ ├── BlendShapeData.cs │ │ ├── BlendShapeData.cs.meta │ │ ├── BlendShapeFrameData.cs │ │ ├── BlendShapeFrameData.cs.meta │ │ ├── ErrorQuadric.cs │ │ ├── ErrorQuadric.cs.meta │ │ ├── JobHandleSpanExtensions.cs │ │ ├── JobHandleSpanExtensions.cs.meta │ │ ├── Jobs.meta │ │ ├── Jobs │ │ │ ├── CollectEdgesJob.cs │ │ │ ├── CollectEdgesJob.cs.meta │ │ │ ├── CollectMergePairsJob.cs │ │ │ ├── CollectMergePairsJob.cs.meta │ │ │ ├── CollectNeighborVertexPairsJob.cs │ │ │ ├── CollectNeighborVertexPairsJob.cs.meta │ │ │ ├── CollectSmartLinksJob.cs │ │ │ ├── CollectSmartLinksJob.cs.meta │ │ │ ├── CollectVertexContainingSubMeshIndicesJob.cs │ │ │ ├── CollectVertexContainingSubMeshIndicesJob.cs.meta │ │ │ ├── CollectVertexContainingTrianglesAndMarkInvalidTrianglesJob.cs │ │ │ ├── CollectVertexContainingTrianglesAndMarkInvalidTrianglesJob.cs.meta │ │ │ ├── CollectVertexMergeOpponmentsJob.cs │ │ │ ├── CollectVertexMergeOpponmentsJob.cs.meta │ │ │ ├── CollectVertexMergesJob.cs │ │ │ ├── CollectVertexMergesJob.cs.meta │ │ │ ├── ComputeMergesJob.cs │ │ │ ├── ComputeMergesJob.cs.meta │ │ │ ├── ComputeTriangleNormalsAndErrorQuadricsJob.cs │ │ │ ├── ComputeTriangleNormalsAndErrorQuadricsJob.cs.meta │ │ │ ├── ComputeVertexErrorQuadricsJob.cs │ │ │ ├── ComputeVertexErrorQuadricsJob.cs.meta │ │ │ ├── CopyTrianglesJob.cs │ │ │ ├── CopyTrianglesJob.cs.meta │ │ │ ├── CopyVertexAttributesJobs.cs │ │ │ ├── CopyVertexAttributesJobs.cs.meta │ │ │ ├── DisposeBlendShapesJob.cs │ │ │ ├── DisposeBlendShapesJob.cs.meta │ │ │ ├── FindNonReferencedVerticesJob.cs │ │ │ ├── FindNonReferencedVerticesJob.cs.meta │ │ │ ├── InitializeBufferJobs.cs │ │ │ ├── InitializeBufferJobs.cs.meta │ │ │ ├── MarkBorderEdgeVerticesJob.cs │ │ │ ├── MarkBorderEdgeVerticesJob.cs.meta │ │ │ ├── RemoveHighCostSmartLinksJob.cs │ │ │ ├── RemoveHighCostSmartLinksJob.cs.meta │ │ │ ├── SimplifyJob.cs │ │ │ ├── SimplifyJob.cs.meta │ │ │ ├── WriteToMeshDataJob.cs │ │ │ └── WriteToMeshDataJob.cs.meta │ │ ├── MergeFactory.cs │ │ ├── MergeFactory.cs.meta │ │ ├── MeshDataHelpers.cs │ │ ├── MeshDataHelpers.cs.meta │ │ ├── MeshSimplificationTarget.cs │ │ ├── MeshSimplificationTarget.cs.meta │ │ ├── MeshSimplificationTargetKind.cs │ │ ├── MeshSimplificationTargetKind.cs.meta │ │ ├── MeshSimplifier.cs │ │ ├── MeshSimplifier.cs.meta │ │ ├── MeshSimplifierOptions.cs │ │ ├── MeshSimplifierOptions.cs.meta │ │ ├── Meshia.MeshSimplification.Runtime.asmdef │ │ ├── Meshia.MeshSimplification.Runtime.asmdef.meta │ │ ├── NativeMinPriorityQueue.cs │ │ ├── NativeMinPriorityQueue.cs.meta │ │ ├── Tests.meta │ │ ├── Tests │ │ │ ├── MeshSimplifierTests.cs │ │ │ ├── MeshSimplifierTests.cs.meta │ │ │ ├── Meshia.MeshSimplification.Runtime.Tests.asmdef │ │ │ └── Meshia.MeshSimplification.Runtime.Tests.asmdef.meta │ │ ├── UnityCollectionsHelpers.cs │ │ ├── UnityCollectionsHelpers.cs.meta │ │ ├── UnsafeKdTree.cs │ │ ├── UnsafeKdTree.cs.meta │ │ ├── UnsafeMinPriorityQueue.cs │ │ ├── UnsafeMinPriorityQueue.cs.meta │ │ ├── VertexMerge.cs │ │ └── VertexMerge.cs.meta │ ├── VRChat.meta │ ├── VRChat │ │ ├── Worlds.meta │ │ └── Worlds │ │ │ ├── Editor.meta │ │ │ └── Editor │ │ │ ├── BuildWorldMeshSimplificationHook.cs │ │ │ ├── BuildWorldMeshSimplificationHook.cs.meta │ │ │ ├── Meshia.MeshSimplification.VRChat.Worlds.Editor.asmdef │ │ │ └── Meshia.MeshSimplification.VRChat.Worlds.Editor.asmdef.meta │ ├── package.json │ └── package.json.meta ├── com.vrchat.core.bootstrap │ ├── Editor.meta │ ├── Editor │ │ ├── Bootstrap.cs │ │ ├── Bootstrap.cs.meta │ │ ├── VRChat.Bootstrapper.Editor.asmdef │ │ └── VRChat.Bootstrapper.Editor.asmdef.meta │ ├── License.md │ ├── License.md.meta │ ├── package.json │ └── package.json.meta ├── com.vrchat.core.vpm-resolver │ ├── Editor.meta │ ├── Editor │ │ ├── Dependencies.meta │ │ ├── Dependencies │ │ │ ├── ICSharpCode.SharpZipLib.dll │ │ │ ├── ICSharpCode.SharpZipLib.dll.meta │ │ │ ├── SemanticVersioning.License.txt │ │ │ ├── SemanticVersioning.License.txt.meta │ │ │ ├── SemanticVersioning.dll │ │ │ ├── SemanticVersioning.dll.meta │ │ │ ├── Serilog.License.txt │ │ │ ├── Serilog.License.txt.meta │ │ │ ├── Serilog.Sinks.File.dll │ │ │ ├── Serilog.Sinks.File.dll.meta │ │ │ ├── Serilog.Sinks.File.txt │ │ │ ├── Serilog.Sinks.File.txt.meta │ │ │ ├── Serilog.Sinks.Unity3D.License.md │ │ │ ├── Serilog.Sinks.Unity3D.License.md.meta │ │ │ ├── Serilog.Sinks.Unity3D.dll │ │ │ ├── Serilog.Sinks.Unity3D.dll.meta │ │ │ ├── Serilog.dll │ │ │ ├── Serilog.dll.meta │ │ │ ├── YamlDotNet.License.txt │ │ │ ├── YamlDotNet.License.txt.meta │ │ │ ├── YamlDotNet.dll │ │ │ ├── YamlDotNet.dll.meta │ │ │ ├── vpm-core-lib.dll │ │ │ └── vpm-core-lib.dll.meta │ │ ├── PackageMaker.meta │ │ ├── PackageMaker │ │ │ ├── PackageMakerWindow.cs │ │ │ ├── PackageMakerWindow.cs.meta │ │ │ ├── PackageMakerWindowData.cs │ │ │ └── PackageMakerWindowData.cs.meta │ │ ├── Resolver.meta │ │ ├── Resolver │ │ │ ├── Resolver.cs │ │ │ ├── Resolver.cs.meta │ │ │ ├── ResolverWindow.cs │ │ │ └── ResolverWindow.cs.meta │ │ ├── Resources.meta │ │ ├── Resources │ │ │ ├── PackageMakerWindowStyle.uss │ │ │ ├── PackageMakerWindowStyle.uss.meta │ │ │ ├── ResolverWindowStyle.uss │ │ │ └── ResolverWindowStyle.uss.meta │ │ ├── com.vrchat.core.vpm-resolver.Editor.asmdef │ │ └── com.vrchat.core.vpm-resolver.Editor.asmdef.meta │ ├── License.md │ ├── License.md.meta │ ├── package.json │ └── package.json.meta ├── manifest.json ├── packages-lock.json └── vpm-manifest.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── MemorySettings.asset ├── NavMeshAreas.asset ├── PackageManagerSettings.asset ├── Packages │ └── com.vrchat.base │ │ └── settings.json ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset ├── VersionControlSettings.asset ├── XRPackageSettings.asset └── XRSettings.asset ├── README.md └── UserSettings ├── EditorUserSettings.asset ├── Layouts └── default-2022.dwlt └── Search.settings /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Build Docs 2 | 3 | on: 4 | workflow_dispatch: 5 | workflow_run: 6 | workflows: [Build Release] 7 | types: 8 | - completed 9 | release: 10 | types: [published, created, edited, unpublished, deleted, released] 11 | 12 | env: 13 | DOCFX_PROJECT_PATH: Documents 14 | 15 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 16 | permissions: 17 | actions: read 18 | pages: write 19 | id-token: write 20 | 21 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 22 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 23 | concurrency: 24 | group: "pages" 25 | cancel-in-progress: false 26 | 27 | jobs: 28 | publish-docs: 29 | environment: 30 | name: github-pages 31 | url: ${{ steps.deployment.outputs.page_url }} 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: Checkout 35 | uses: actions/checkout@v3 36 | - name: Dotnet Setup 37 | uses: actions/setup-dotnet@v3 38 | with: 39 | dotnet-version: 8.x 40 | 41 | - run: dotnet tool update -g docfx 42 | - run: docfx ${{ env.DOCFX_PROJECT_PATH }}/docfx.json 43 | 44 | - name: Upload artifact 45 | uses: actions/upload-pages-artifact@v3 46 | with: 47 | # Upload entire repository 48 | path: '${{ env.DOCFX_PROJECT_PATH }}/_site' 49 | - name: Deploy to GitHub Pages 50 | id: deployment 51 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build Release 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | 8 | # Validate Repository Configuration 9 | config: 10 | runs-on: ubuntu-latest 11 | outputs: 12 | config_package: ${{ steps.config_package.outputs.configPackage }} 13 | steps: 14 | 15 | # Ensure that required repository variable has been created for the Package 16 | - name: Validate Package Config 17 | id: config_package 18 | run: | 19 | if [ "${{ vars.PACKAGE_NAME }}" != "" ]; then 20 | echo "configPackage=true" >> $GITHUB_OUTPUT; 21 | else 22 | echo "configPackage=false" >> $GITHUB_OUTPUT; 23 | fi 24 | 25 | # Build and release the Package 26 | # If the repository is not configured properly, this job will be skipped 27 | build: 28 | needs: config 29 | runs-on: ubuntu-latest 30 | permissions: 31 | contents: write 32 | env: 33 | packagePath: Packages/${{ vars.PACKAGE_NAME }} 34 | if: needs.config.outputs.config_package == 'true' 35 | steps: 36 | 37 | # Checkout Local Repository 38 | - name: Checkout 39 | uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac 40 | 41 | # Get the Package version based on the package.json file 42 | - name: Get Version 43 | id: version 44 | uses: zoexx/github-action-json-file-properties@b9f36ce6ee6fe2680cd3c32b2c62e22eade7e590 45 | with: 46 | file_path: "${{ env.packagePath }}/package.json" 47 | prop_path: "version" 48 | 49 | # Configure the Environment Variables needed for releasing the Package 50 | - name: Set Environment Variables 51 | run: | 52 | echo "zipFile=${{ vars.PACKAGE_NAME }}-${{ steps.version.outputs.value }}".zip >> $GITHUB_ENV 53 | echo "unityPackage=${{ vars.PACKAGE_NAME }}-${{ steps.version.outputs.value }}.unitypackage" >> $GITHUB_ENV 54 | echo "version=${{ steps.version.outputs.value }}" >> $GITHUB_ENV 55 | 56 | # Zip the Package for release 57 | - name: Create Package Zip 58 | working-directory: "${{ env.packagePath }}" 59 | run: zip -r "${{ github.workspace }}/${{ env.zipFile }}" . 60 | 61 | # Build a list of .meta files for future use 62 | - name: Track Package Meta Files 63 | run: find "${{ env.packagePath }}/" -name \*.meta >> metaList 64 | 65 | # Make a UnityPackage version of the Package for release 66 | - name: Create UnityPackage 67 | uses: pCYSl5EDgo/create-unitypackage@v1.2.3 68 | with: 69 | package-path: ${{ env.unityPackage }} 70 | include-files: metaList 71 | 72 | # Make a release tag of the version from the package.json file 73 | - name: Create Tag 74 | id: tag_version 75 | uses: rickstaa/action-create-tag@88dbf7ff6fe2405f8e8f6c6fdfd78829bc631f83 76 | with: 77 | tag: "${{ env.version }}" 78 | 79 | # Publish the Release to GitHub 80 | - name: Make Release 81 | uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 82 | with: 83 | files: | 84 | ${{ env.zipFile }} 85 | ${{ env.unityPackage }} 86 | ${{ env.packagePath }}/package.json 87 | tag_name: ${{ env.version }} 88 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: Run Tests 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | pull_request_target: 7 | 8 | env: 9 | WORKING_DIRECTORY: . 10 | UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} 11 | UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} 12 | UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} 13 | 14 | jobs: 15 | test: 16 | name: Test in ${{ matrix.testMode }} on ${{ matrix.unityVersion }} 17 | runs-on: ubuntu-latest 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | unityVersion: 22 | - 2022.3.22f1 23 | testMode: 24 | - playmode 25 | - editmode 26 | - standalone 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v4 30 | 31 | - name: Create LFS file list 32 | run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id 33 | working-directory: ${{ env.WORKING_DIRECTORY }} 34 | 35 | - name: Restore LFS cache 36 | uses: actions/cache@v3 37 | with: 38 | path: ${{ env.WORKING_DIRECTORY }}/.git/lfs 39 | key: ${{ runner.os }}-lfs-${{ hashFiles('${{ env.WORKING_DIRECTORY }}/.lfs-assets-id') }} 40 | 41 | - name: Git LFS Pull 42 | run: | 43 | git lfs pull 44 | git add . 45 | git reset --hard 46 | working-directory: ${{ env.WORKING_DIRECTORY }} 47 | 48 | - uses: actions/cache@v3 49 | with: 50 | path: ${{ env.WORKING_DIRECTORY }}/Library 51 | key: Library-${{ hashFiles('${{ env.WORKING_DIRECTORY }}/Assets/**', '${{ env.WORKING_DIRECTORY }}/Packages/**', '${{ env.WORKING_DIRECTORY }}/ProjectSettings/**') }} 52 | restore-keys: | 53 | Library- 54 | 55 | - uses: game-ci/unity-test-runner@v4 56 | with: 57 | unityVersion: ${{ matrix.unityVersion }} 58 | testMode: ${{ matrix.testMode }} 59 | artifactsPath: ${{ matrix.testMode }}-artifacts 60 | githubToken: ${{ secrets.GITHUB_TOKEN }} 61 | checkName: ${{ matrix.testMode }} Test Results 62 | coverageOptions: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+my.assembly.*' 63 | projectPath: ${{ env.WORKING_DIRECTORY }} 64 | 65 | - uses: actions/upload-artifact@v4 66 | if: always() 67 | with: 68 | name: Test results for ${{ matrix.testMode }} on ${{ matrix.unityVersion }} 69 | path: ${{ env.WORKING_DIRECTORY }}/${{ steps.tests.outputs.artifactsPath }} 70 | 71 | - uses: actions/upload-artifact@v4 72 | if: always() 73 | with: 74 | name: Coverage results for ${{ matrix.testMode }} on ${{ matrix.unityVersion }} 75 | path: ${{ env.WORKING_DIRECTORY }}/${{ steps.tests.outputs.coveragePath }} 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | *.unitypackage 57 | 58 | # Crashlytics generated file 59 | crashlytics-build.properties 60 | 61 | .idea/.idea.vpm-package-maker/.idea 62 | Assets/PackageMakerWindowData.asset* 63 | .idea 64 | .vscode 65 | -------------------------------------------------------------------------------- /.vsconfig: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "components": [ 4 | "Microsoft.VisualStudio.Workload.ManagedGame" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Assets/.gitkeep -------------------------------------------------------------------------------- /Documents/.gitignore: -------------------------------------------------------------------------------- 1 | api 2 | _site 3 | _site_pdf -------------------------------------------------------------------------------- /Documents/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json", 3 | "metadata": [ 4 | { 5 | "src": [ 6 | { 7 | "src": "../Packages/com.ramtype0.meshia.mesh-simplification", 8 | "files": [ 9 | "Runtime/**/*.cs" 10 | ], 11 | "exclude":[ 12 | "Runtime/Tests/**/*.cs" 13 | ] 14 | } 15 | ], 16 | "dest": "api", 17 | "allowCompilationErrors": true 18 | } 19 | ], 20 | "build": { 21 | "content": [ 22 | { 23 | "files": [ 24 | "**/*.{md,yml}" 25 | ], 26 | "exclude": [ 27 | "_site/**" 28 | ] 29 | } 30 | ], 31 | "resource": [ 32 | { 33 | "files": [ 34 | "images/**" 35 | ] 36 | } 37 | ], 38 | "output": "_site", 39 | "template": [ 40 | "default", 41 | "modern" 42 | ], 43 | "globalMetadata": { 44 | "_appName": "Meshia.MeshSimplification", 45 | "_appTitle": "Meshia.MeshSimplification", 46 | "_appLogoPath": "images/logo.svg", 47 | "_appFaviconPath": "images/logo.svg", 48 | "_enableSearch": true 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Documents/docs/en/getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ## Installation 4 | 5 | ### VPM 6 | 7 | Add [my VPM repository](https://ramtype0.github.io/VpmRepository/) to VCC, then add Meshia Mesh Simplification package to your projects. 8 | 9 | ## How to use 10 | 11 | ### NDMF integration 12 | 13 | Attach `MeshiaMeshSimplifier` to your models. 14 | 15 | You can preview the result in EditMode. 16 | 17 | ### Call from C# 18 | 19 | ```csharp 20 | 21 | using Meshia.MeshSimplification; 22 | 23 | Mesh simplifiedMesh = new(); 24 | 25 | // Asynchronous API 26 | 27 | await MeshSimplifier.SimplifyAsync(originalMesh, target, options, simplifiedMesh); 28 | 29 | // Synchronous API 30 | 31 | MeshSimplifier.Simplify(originalMesh, target, options, simplifiedMesh); 32 | 33 | ``` -------------------------------------------------------------------------------- /Documents/docs/en/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Meshia Mesh Simplification provides, fast, asynchronous mesh simplification. -------------------------------------------------------------------------------- /Documents/docs/en/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Introduction 2 | href: introduction.md 3 | - name: Getting Started 4 | href: getting-started.md -------------------------------------------------------------------------------- /Documents/docs/ja/getting-started.md: -------------------------------------------------------------------------------- 1 | # チュートリアル 2 | 3 | ## インストール 4 | 5 | ### VPM 6 | 7 | [VPM repository](https://ramtype0.github.io/VpmRepository/)をVCCに追加してから、Manage Project > Manage PackagesからMeshia Mesh Simplificationをプロジェクトに追加してください。 8 | 9 | ## 使い方 10 | 11 | ### NDMF統合 12 | 13 | NDMFがプロジェクトにインポートされている場合、`MeshiaMeshSimplifier`が使えます。 14 | エディターで軽量化結果をプレビューしながらパラメーターの調整ができます。 15 | 16 | ### C#から呼び出す 17 | 18 | ```csharp 19 | 20 | using Meshia.MeshSimplification; 21 | 22 | Mesh simplifiedMesh = new(); 23 | 24 | // 非同期API 25 | 26 | await MeshSimplifier.SimplifyAsync(originalMesh, target, options, simplifiedMesh); 27 | 28 | // 同期API 29 | 30 | MeshSimplifier.Simplify(originalMesh, target, options, simplifiedMesh); 31 | 32 | ``` 33 | 34 | 35 | -------------------------------------------------------------------------------- /Documents/docs/ja/introduction.md: -------------------------------------------------------------------------------- 1 | # Meshia Mesh Simplificationとは? 2 | 3 | Meshia Mesh SimplificationはUnity Job System上で動作する、非同期、高速なメッシュ軽量化ツールです。 -------------------------------------------------------------------------------- /Documents/docs/ja/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Meshia Mesh Simplificationとは? 2 | href: introduction.md 3 | - name: チュートリアル 4 | href: getting-started.md -------------------------------------------------------------------------------- /Documents/docs/toc.yml: -------------------------------------------------------------------------------- 1 | - name: English 2 | href: en/ 3 | - name: 日本語 4 | href: ja/ -------------------------------------------------------------------------------- /Documents/images/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Documents/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | _layout: landing 3 | --- 4 | 5 | # Meshia Mesh Simplification 6 | 7 | - [English](#english) 8 | - [日本語](#日本語) 9 | 10 | ## English 11 | Mesh simplification tool/library for Unity, VRChat. 12 | 13 | Based on Unity Job System, and Burst. 14 | Provides fast, asynchronous mesh simplification. 15 | 16 | Can be executed at runtime or in the editor. 17 | 18 | ### Installation 19 | 20 | ### VPM 21 | 22 | Add [my VPM repository](https://ramtype0.github.io/VpmRepository/) to VCC, then add Meshia Mesh Simplification package to your projects. 23 | 24 | 25 | ### How to use 26 | 27 | #### NDMF integration 28 | 29 | Attach `MeshiaMeshSimplifier` to your models. 30 | 31 | You can preview the result in EditMode. 32 | 33 | 34 | #### Call from C# 35 | 36 | ```csharp 37 | 38 | using Meshia.MeshSimplification; 39 | 40 | Mesh simplifiedMesh = new(); 41 | 42 | // Asynchronous API 43 | 44 | await MeshSimplifier.SimplifyAsync(originalMesh, target, options, simplifiedMesh); 45 | 46 | // Synchronous API 47 | 48 | MeshSimplifier.Simplify(originalMesh, target, options, simplifiedMesh); 49 | 50 | ``` 51 | 52 | ## 日本語 53 | 54 | Unity、VRChat向けのメッシュ軽量化ツールです。 55 | Unity Job Systemで動作するため、Burstと合わせて高速、かつ非同期で処理ができるのが特徴です。 56 | ランタイム、エディターの双方で動作します。 57 | 58 | ### インストール 59 | 60 | ### VPM 61 | 62 | [VPM repository](https://ramtype0.github.io/VpmRepository/)をVCCに追加してから、Manage Project > Manage PackagesからMeshia Mesh Simplificationをプロジェクトに追加してください。 63 | 64 | ### 使い方 65 | 66 | #### NDMF統合 67 | 68 | NDMFがプロジェクトにインポートされている場合、`MeshiaMeshSimplifier`が使えます。 69 | エディターで軽量化結果をプレビューしながらパラメーターの調整ができます。 70 | 71 | #### C#から呼び出す 72 | 73 | ```csharp 74 | 75 | using Meshia.MeshSimplification; 76 | 77 | Mesh simplifiedMesh = new(); 78 | 79 | // 非同期API 80 | 81 | await MeshSimplifier.SimplifyAsync(originalMesh, target, options, simplifiedMesh); 82 | 83 | // 同期API 84 | 85 | MeshSimplifier.Simplify(originalMesh, target, options, simplifiedMesh); 86 | 87 | ``` 88 | 89 | 90 | -------------------------------------------------------------------------------- /Documents/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Docs 2 | href: docs/toc.yml 3 | - name: API 4 | href: api/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2025 Ram.Type-0 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Packages/.gitignore: -------------------------------------------------------------------------------- 1 | /*/ 2 | !com.vrchat.core.* 3 | 4 | # Change this to match your new package name 5 | !com.ramtype0.meshia.mesh-simplification 6 | !com.vrchat.core.*/ 7 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a9ab3ce6d13bc94baf624041ce6f673 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81ddbdfe04f51c84f8ee175f2d4c3574 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/Meshia.MeshSimplification.Ndmf.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Meshia.MeshSimplification.Ndmf.Editor", 3 | "rootNamespace": "Meshia.MeshSimplification.Ndmf.Editor", 4 | "references": [ 5 | "Meshia.MeshSimplification.Runtime", 6 | "Meshia.MeshSimplification.Ndmf.Runtime", 7 | "nadena.dev.ndmf" 8 | ], 9 | "includePlatforms": [ 10 | "Editor" 11 | ], 12 | "excludePlatforms": [], 13 | "allowUnsafeCode": false, 14 | "overrideReferences": true, 15 | "precompiledReferences": [ 16 | "System.Collections.Immutable.dll" 17 | ], 18 | "autoReferenced": false, 19 | "defineConstraints": [], 20 | "versionDefines": [ 21 | { 22 | "name": "nadena.dev.ndmf", 23 | "expression": "", 24 | "define": "ENABLE_NDMF" 25 | } 26 | ], 27 | "noEngineReferences": false 28 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/Meshia.MeshSimplification.Ndmf.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e73c90830ea1eb46909fa65cfd645cc 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/MeshiaMeshSimplifierEditor.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | using System.Diagnostics.CodeAnalysis; 3 | using System.IO; 4 | using UnityEditor; 5 | using UnityEditor.UIElements; 6 | using UnityEngine; 7 | using UnityEngine.UIElements; 8 | 9 | namespace Meshia.MeshSimplification.Ndmf.Editor 10 | { 11 | [CustomEditor(typeof(MeshiaMeshSimplifier))] 12 | [CanEditMultipleObjects] 13 | public class MeshiaMeshSimplifierEditor : UnityEditor.Editor 14 | { 15 | [SerializeField] 16 | VisualTreeAsset visualTreeAsset = null!; 17 | 18 | public override VisualElement CreateInspectorGUI() 19 | { 20 | VisualElement root = new(); 21 | visualTreeAsset.CloneTree(root); 22 | root.Bind(serializedObject); 23 | 24 | var ndmfNotImportedWarning = root.Q("NdmfNotImportedWarning"); 25 | DisplayStyle warningDisplayStyle; 26 | #if ENABLE_NDMF 27 | warningDisplayStyle = DisplayStyle.None; 28 | #else 29 | warningDisplayStyle = DisplayStyle.Flex; 30 | #endif 31 | ndmfNotImportedWarning.style.display = warningDisplayStyle; 32 | 33 | var bakeMeshButtonContainer = root.Q("BakeMeshButtonContainer"); 34 | bakeMeshButtonContainer.onGUIHandler = () => 35 | { 36 | // TODO: Replace this with non-IMGUI implementation 37 | // But how could we register callback for whether target mesh is currently available? 38 | if (targets.Length == 1) 39 | { 40 | var ndmfMeshSimplifier = (MeshiaMeshSimplifier)target; 41 | if (TryGetTargetMesh(ndmfMeshSimplifier, out var targetMesh)) 42 | { 43 | if (GUILayout.Button("Bake mesh")) 44 | { 45 | var absolutePath = EditorUtility.SaveFilePanel( 46 | title: "Save baked mesh", 47 | directory: "", 48 | defaultName: $"{targetMesh.name}-Simplified.asset", 49 | extension: "asset"); 50 | 51 | if (!string.IsNullOrEmpty(absolutePath)) 52 | { 53 | Mesh simplifiedMesh = new(); 54 | 55 | MeshSimplifier.Simplify(targetMesh, ndmfMeshSimplifier.target, ndmfMeshSimplifier.options, simplifiedMesh); 56 | 57 | AssetDatabase.CreateAsset(simplifiedMesh, Path.Join("Assets/", Path.GetRelativePath(Application.dataPath, absolutePath))); 58 | } 59 | } 60 | } 61 | 62 | } 63 | }; 64 | 65 | return root; 66 | } 67 | 68 | private static bool TryGetTargetMesh(MeshiaMeshSimplifier ndmfMeshSimplifier, [NotNullWhen(true)] out Mesh? targetMesh) 69 | { 70 | targetMesh = null; 71 | if (ndmfMeshSimplifier.TryGetComponent(out var meshFilter)) 72 | { 73 | targetMesh = meshFilter.sharedMesh; 74 | if (targetMesh != null) 75 | { 76 | return true; 77 | } 78 | } 79 | if (ndmfMeshSimplifier.TryGetComponent(out var skinnedMeshRenderer)) 80 | { 81 | targetMesh = skinnedMeshRenderer.sharedMesh; 82 | if (targetMesh != null) 83 | { 84 | return true; 85 | } 86 | } 87 | 88 | return false; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/MeshiaMeshSimplifierEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 290ad9263e902094d82148dc8a3ec089 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - visualTreeAsset: {fileID: 9197481963319205126, guid: 8132ade07e7e2b14dba6ea4ee4ef0867, 8 | type: 3} 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/MeshiaMeshSimplifierEditor.uxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/MeshiaMeshSimplifierEditor.uxml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8132ade07e7e2b14dba6ea4ee4ef0867 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0} 11 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/NdmfPlugin.cs: -------------------------------------------------------------------------------- 1 | #if ENABLE_NDMF 2 | 3 | using Meshia.MeshSimplification.Ndmf.Editor; 4 | using nadena.dev.ndmf; 5 | using nadena.dev.ndmf.preview; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Collections.Immutable; 9 | using System.Linq; 10 | using System.Threading.Tasks; 11 | using UnityEditor; 12 | using UnityEngine; 13 | using UnityEngine.Pool; 14 | 15 | 16 | [assembly: ExportsPlugin(typeof(NdmfPlugin))] 17 | 18 | namespace Meshia.MeshSimplification.Ndmf.Editor 19 | { 20 | class NdmfPlugin : Plugin 21 | { 22 | public override string DisplayName => "Meshia NDMF Mesh Simplifier"; 23 | 24 | protected override void Configure() 25 | { 26 | InPhase(BuildPhase.Optimizing) 27 | .BeforePlugin("com.anatawa12.avatar-optimizer") 28 | .Run("Simplify meshes", ctx => 29 | { 30 | var nfmfMeshSimplifiers = ctx.AvatarRootObject.GetComponentsInChildren(true); 31 | using(ListPool<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, Mesh Destination)>.Get(out var parameters)) 32 | { 33 | foreach (var ndmfMeshSimplifier in nfmfMeshSimplifiers) 34 | { 35 | if (ndmfMeshSimplifier.TryGetComponent(out var skinnedMeshRenderer)) 36 | { 37 | var sourceMesh = skinnedMeshRenderer.sharedMesh; 38 | Mesh simplifiedMesh = new(); 39 | parameters.Add((sourceMesh, ndmfMeshSimplifier.target, ndmfMeshSimplifier.options, simplifiedMesh)); 40 | } 41 | if (ndmfMeshSimplifier.TryGetComponent(out var meshFilter)) 42 | { 43 | var sourceMesh = meshFilter.sharedMesh; 44 | Mesh simplifiedMesh = new(); 45 | parameters.Add((sourceMesh, ndmfMeshSimplifier.target, ndmfMeshSimplifier.options, simplifiedMesh)); 46 | } 47 | 48 | } 49 | MeshSimplifier.SimplifyBatch(parameters); 50 | { 51 | var i = 0; 52 | 53 | foreach (var ndmfMeshSimplifier in nfmfMeshSimplifiers) 54 | { 55 | if (ndmfMeshSimplifier.TryGetComponent(out var skinnedMeshRenderer)) 56 | { 57 | var (mesh, target, options, simplifiedMesh) = parameters[i++]; 58 | AssetDatabase.AddObjectToAsset(simplifiedMesh, ctx.AssetContainer); 59 | skinnedMeshRenderer.sharedMesh = simplifiedMesh; 60 | } 61 | if (ndmfMeshSimplifier.TryGetComponent(out var meshFilter)) 62 | { 63 | var (mesh, target, options, simplifiedMesh) = parameters[i++]; 64 | AssetDatabase.AddObjectToAsset(simplifiedMesh, ctx.AssetContainer); 65 | meshFilter.sharedMesh = simplifiedMesh; 66 | } 67 | 68 | UnityEngine.Object.DestroyImmediate(ndmfMeshSimplifier); 69 | } 70 | } 71 | 72 | } 73 | 74 | }).PreviewingWith(new NdmfMeshSimplifierPreviewer()) 75 | ; 76 | } 77 | } 78 | class NdmfMeshSimplifierPreviewer : IRenderFilter 79 | { 80 | public ImmutableList GetTargetGroups(ComputeContext context) 81 | { 82 | return context.GetComponentsByType() 83 | .Select(ndmfMeshSimplifier => context.GetComponent(ndmfMeshSimplifier.gameObject)) 84 | .Where(renderer => renderer is MeshRenderer or SkinnedMeshRenderer) 85 | .Select(renderer => RenderGroup.For(renderer)) 86 | .ToImmutableList(); 87 | } 88 | 89 | public async Task Instantiate(RenderGroup group, IEnumerable<(Renderer, Renderer)> proxyPairs, ComputeContext context) 90 | { 91 | var ndmfMeshSimplifier = group.Renderers.First().GetComponent(); 92 | var targetRenderer = proxyPairs.First().Item2; 93 | var mesh = targetRenderer switch 94 | { 95 | SkinnedMeshRenderer skinnedMeshRenderer => skinnedMeshRenderer.sharedMesh, 96 | MeshRenderer meshRenderer => meshRenderer.TryGetComponent(out var meshFilter) ? meshFilter.sharedMesh : null, 97 | _ => null, 98 | }; 99 | 100 | if (mesh == null) 101 | { 102 | return null; 103 | } 104 | context.Observe(ndmfMeshSimplifier, ndmfMeshSimplifier => ndmfMeshSimplifier.target, (x, y) => x == y); 105 | context.Observe(ndmfMeshSimplifier, ndmfMeshSimplifier => ndmfMeshSimplifier.options, (x, y) => x == y); 106 | context.Observe(mesh); 107 | 108 | Mesh simplifiedMesh = new(); 109 | try 110 | { 111 | await MeshSimplifier.SimplifyAsync(mesh, ndmfMeshSimplifier.target, ndmfMeshSimplifier.options, simplifiedMesh); 112 | } 113 | catch (Exception) 114 | { 115 | UnityEngine.Object.DestroyImmediate(simplifiedMesh); 116 | throw; 117 | } 118 | return new NdmfMeshSimplifierPreviewNode(simplifiedMesh); 119 | } 120 | 121 | 122 | } 123 | class NdmfMeshSimplifierPreviewNode : IRenderFilterNode 124 | { 125 | public RenderAspects WhatChanged => RenderAspects.Mesh; 126 | 127 | Mesh simplifiedMesh; 128 | 129 | public NdmfMeshSimplifierPreviewNode(Mesh mesh) 130 | { 131 | simplifiedMesh = mesh; 132 | } 133 | 134 | public void OnFrame(Renderer original, Renderer proxy) 135 | { 136 | switch (proxy) 137 | { 138 | case SkinnedMeshRenderer skinnedMeshRenderer: 139 | { 140 | skinnedMeshRenderer.sharedMesh = simplifiedMesh; 141 | } 142 | break; 143 | case MeshRenderer meshRenderer: 144 | { 145 | if (meshRenderer.TryGetComponent(out var meshFilter)) 146 | { 147 | meshFilter.sharedMesh = simplifiedMesh; 148 | } 149 | } 150 | break; 151 | } 152 | } 153 | 154 | void IDisposable.Dispose() => UnityEngine.Object.DestroyImmediate(simplifiedMesh); 155 | 156 | } 157 | } 158 | 159 | #endif -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Editor/NdmfPlugin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1ba33bc5980544499c978a60be056b2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fff02076bdbc971459eb49414f2dfce2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Runtime/Meshia.MeshSimplification.Ndmf.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Meshia.MeshSimplification.Ndmf.Runtime", 3 | "rootNamespace": "Meshia.MeshSimplification.Ndmf", 4 | "references": [ 5 | "Meshia.MeshSimplification.Runtime", 6 | "VRC.SDKBase" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": true, 12 | "precompiledReferences": [ 13 | "VRCSDKBase.dll" 14 | ], 15 | "autoReferenced": false, 16 | "defineConstraints": [], 17 | "versionDefines": [ 18 | { 19 | "name": "com.vrchat.base", 20 | "expression": "", 21 | "define": "ENABLE_VRCHAT_BASE" 22 | }, 23 | { 24 | "name": "com.vrchat.worlds", 25 | "expression": "", 26 | "define": "ENABLE_VRCHAT_WORLDS" 27 | } 28 | ], 29 | "noEngineReferences": false 30 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Runtime/Meshia.MeshSimplification.Ndmf.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b7227f38ccc85a47b25d2736821d761 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Runtime/MeshiaMeshSimplifier.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | 4 | namespace Meshia.MeshSimplification.Ndmf 5 | { 6 | [AddComponentMenu("Meshia Mesh Simplification/Meshia Mesh Simplifier")] 7 | [DisallowMultipleComponent] 8 | [RequireComponent(typeof(Renderer))] 9 | public class MeshiaMeshSimplifier : MonoBehaviour 10 | #if ENABLE_VRCHAT_BASE 11 | , VRC.SDKBase.IEditorOnly 12 | #endif 13 | { 14 | public MeshSimplificationTarget target = new() 15 | { 16 | Kind = MeshSimplificationTargetKind.RelativeVertexCount, 17 | Value = 0.5f, 18 | }; 19 | public MeshSimplifierOptions options = MeshSimplifierOptions.Default; 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Ndmf/Runtime/MeshiaMeshSimplifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed140cfac7c1b364dae352ebbf9b51eb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 866247a23169da5469580af6a03c0885 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/BlendShapeData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using Unity.Collections; 4 | using Unity.Collections.LowLevel.Unsafe; 5 | using Unity.Mathematics; 6 | using UnityEngine; 7 | namespace Meshia.MeshSimplification 8 | { 9 | public struct BlendShapeData : IDisposable 10 | { 11 | public UnsafeText Name; 12 | public UnsafeList Frames; 13 | 14 | /// 15 | /// Initializes the new list of from the given . 16 | /// 17 | /// The mesh from which blend shapes are loaded. 18 | /// The allocator for returned list of . 19 | /// 20 | public static NativeList GetMeshBlendShapes(Mesh mesh, AllocatorManager.AllocatorHandle allocator) 21 | { 22 | NativeList blendShapes = new(mesh.blendShapeCount, allocator); 23 | if (mesh.blendShapeCount > 0) 24 | { 25 | var deltaVerticesBuffer = new Vector3[mesh.vertexCount]; 26 | var deltaNormalsBuffer = new Vector3[mesh.vertexCount]; 27 | var deltaTangentsBuffer = new Vector3[mesh.vertexCount]; 28 | for (int shapeIndex = 0; shapeIndex < mesh.blendShapeCount; shapeIndex++) 29 | { 30 | var blendShape = Create(mesh, shapeIndex, deltaVerticesBuffer, deltaNormalsBuffer, deltaTangentsBuffer, allocator); 31 | blendShapes.Add(blendShape); 32 | } 33 | } 34 | 35 | return blendShapes; 36 | } 37 | /// 38 | /// Sets the blend shapes of the given from the given . 39 | /// 40 | /// The mesh to set its blend shapes. 41 | /// The blend shapes to set. 42 | public static void SetBlendShapes(Mesh mesh, ReadOnlySpan blendShapes) 43 | { 44 | var vertexCount = mesh.vertexCount; 45 | var deltaVerticesBuffer = new Vector3[vertexCount]; 46 | var deltaNormalsBuffer = new Vector3[vertexCount]; 47 | var deltaTangentsBuffer = new Vector3[vertexCount]; 48 | 49 | mesh.ClearBlendShapes(); 50 | for (int shapeIndex = 0; shapeIndex < blendShapes.Length; shapeIndex++) 51 | { 52 | var blendShape = blendShapes[shapeIndex]; 53 | var name = blendShape.Name.ConvertToString(); 54 | var frames = blendShape.Frames; 55 | for (int frameIndex = 0; frameIndex < frames.Length; frameIndex++) 56 | { 57 | var frame = frames[frameIndex]; 58 | MemoryMarshal.Cast(frame.DeltaVertices.AsSpan()).CopyTo(deltaVerticesBuffer); 59 | MemoryMarshal.Cast(frame.DeltaNormals.AsSpan()).CopyTo(deltaNormalsBuffer); 60 | MemoryMarshal.Cast(frame.DeltaTangents.AsSpan()).CopyTo(deltaTangentsBuffer); 61 | 62 | mesh.AddBlendShapeFrame(name, frame.Weight, deltaVerticesBuffer, deltaNormalsBuffer, deltaTangentsBuffer); 63 | } 64 | } 65 | } 66 | 67 | internal static BlendShapeData Create(Mesh mesh, int shapeIndex, Vector3[] deltaVerticesBuffer, Vector3[] deltaNormalsBuffer, Vector3[] deltaTangentsBuffer, AllocatorManager.AllocatorHandle allocator) 68 | { 69 | var nameString = mesh.GetBlendShapeName(shapeIndex); 70 | UnsafeText name = new(nameString.Length, allocator); 71 | 72 | name.CopyFrom(nameString); 73 | var frameCount = mesh.GetBlendShapeFrameCount(shapeIndex); 74 | UnsafeList frames = new(frameCount, allocator); 75 | for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) 76 | { 77 | var frame = BlendShapeFrameData.Create(mesh, shapeIndex, frameIndex, deltaVerticesBuffer, deltaNormalsBuffer, deltaTangentsBuffer, allocator); 78 | frames.Add(frame); 79 | } 80 | 81 | return new() 82 | { 83 | Name = name, 84 | Frames = frames, 85 | }; 86 | } 87 | /// 88 | /// Disposes the and its frames. 89 | /// 90 | public void Dispose() 91 | { 92 | Name.Dispose(); 93 | for (int i = 0; i < Frames.Length; i++) 94 | { 95 | Frames[i].Dispose(); 96 | } 97 | Frames.Dispose(); 98 | 99 | } 100 | } 101 | } 102 | 103 | 104 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/BlendShapeData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a2aaf6e889556a4d9c32dce0b195eb5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/BlendShapeFrameData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Collections; 3 | using Unity.Collections.LowLevel.Unsafe; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | namespace Meshia.MeshSimplification 7 | { 8 | public struct BlendShapeFrameData : IDisposable 9 | { 10 | public float Weight; 11 | public UnsafeList DeltaVertices; 12 | public UnsafeList DeltaNormals; 13 | public UnsafeList DeltaTangents; 14 | 15 | internal unsafe static BlendShapeFrameData Create(Mesh mesh, int shapeIndex, int frameIndex, Vector3[] deltaVerticesBuffer, Vector3[] deltaNormalsBuffer, Vector3[] deltaTangentsBuffer, AllocatorManager.AllocatorHandle allocator) 16 | { 17 | var weight = mesh.GetBlendShapeFrameWeight(shapeIndex, frameIndex); 18 | mesh.GetBlendShapeFrameVertices(shapeIndex, frameIndex, deltaVerticesBuffer, deltaNormalsBuffer, deltaTangentsBuffer); 19 | 20 | UnsafeList deltaVertices = new(deltaVerticesBuffer.Length, allocator); 21 | deltaVertices.Resize(deltaVerticesBuffer.Length); 22 | deltaVerticesBuffer.AsSpan().CopyTo(new(deltaVertices.Ptr, deltaVertices.Length)); 23 | 24 | UnsafeList deltaNormals = new(deltaNormalsBuffer.Length, allocator); 25 | deltaNormals.Resize(deltaNormalsBuffer.Length); 26 | deltaNormalsBuffer.AsSpan().CopyTo(new(deltaNormals.Ptr, deltaNormals.Length)); 27 | 28 | UnsafeList deltaTangents = new(deltaTangentsBuffer.Length, allocator); 29 | deltaTangents.Resize(deltaTangentsBuffer.Length); 30 | deltaTangentsBuffer.AsSpan().CopyTo(new(deltaTangents.Ptr, deltaTangents.Length)); 31 | return new() 32 | { 33 | Weight = weight, 34 | DeltaVertices = deltaVertices, 35 | DeltaNormals = deltaNormals, 36 | DeltaTangents = deltaTangents, 37 | }; 38 | } 39 | /// 40 | /// Disposes the and its internal buffers. 41 | /// 42 | public void Dispose() 43 | { 44 | DeltaVertices.Dispose(); 45 | DeltaNormals.Dispose(); 46 | DeltaTangents.Dispose(); 47 | } 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/BlendShapeFrameData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 461f2462176cd03478128d366a07a774 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/ErrorQuadric.cs: -------------------------------------------------------------------------------- 1 | using Unity.Mathematics; 2 | using Plane = Unity.Mathematics.Geometry.Plane; 3 | namespace Meshia.MeshSimplification 4 | { 5 | struct ErrorQuadric 6 | { 7 | public ErrorQuadric(Plane plane) 8 | { 9 | float4 normalAndDistance = plane.NormalAndDistance; 10 | m0 = normalAndDistance.x * normalAndDistance.x; 11 | m1 = normalAndDistance.x * normalAndDistance.y; 12 | m2 = normalAndDistance.x * normalAndDistance.z; 13 | m3 = normalAndDistance.x * normalAndDistance.w; 14 | 15 | m4 = normalAndDistance.y * normalAndDistance.y; 16 | m5 = normalAndDistance.y * normalAndDistance.z; 17 | m6 = normalAndDistance.y * normalAndDistance.w; 18 | 19 | m7 = normalAndDistance.z * normalAndDistance.z; 20 | m8 = normalAndDistance.z * normalAndDistance.w; 21 | 22 | m9 = normalAndDistance.w * normalAndDistance.w; 23 | 24 | } 25 | float m0; 26 | float m1; 27 | float m2; 28 | float m3; 29 | 30 | float m4; 31 | float m5; 32 | float m6; 33 | 34 | float m7; 35 | float m8; 36 | 37 | float m9; 38 | 39 | public static ErrorQuadric operator +(ErrorQuadric left, ErrorQuadric right) => new() 40 | { 41 | m0 = left.m0 + right.m0, 42 | m1 = left.m1 + right.m1, 43 | m2 = left.m2 + right.m2, 44 | m3 = left.m3 + right.m3, 45 | m4 = left.m4 + right.m4, 46 | m5 = left.m5 + right.m5, 47 | m6 = left.m6 + right.m6, 48 | m7 = left.m7 + right.m7, 49 | m8 = left.m8 + right.m8, 50 | m9 = left.m9 + right.m9 51 | }; 52 | 53 | 54 | /// 55 | /// Determinant(0, 1, 2, 1, 4, 5, 2, 5, 7) 56 | /// 57 | /// 58 | public readonly float Determinant1() 59 | { 60 | var det = 61 | m0 * m4 * m7 + 62 | m2 * m1 * m5 + 63 | m1 * m5 * m2 - 64 | m2 * m4 * m2 - 65 | m0 * m5 * m5 - 66 | m1 * m1 * m7; 67 | return det; 68 | } 69 | 70 | /// 71 | /// Determinant(1, 2, 3, 4, 5, 6, 5, 7, 8) 72 | /// 73 | /// 74 | public readonly float Determinant2() 75 | { 76 | var det = 77 | m1 * m5 * m8 + 78 | m3 * m4 * m7 + 79 | m2 * m6 * m5 - 80 | m3 * m5 * m5 - 81 | m1 * m6 * m7 - 82 | m2 * m4 * m8; 83 | return det; 84 | } 85 | 86 | /// 87 | /// Determinant(0, 2, 3, 1, 5, 6, 2, 7, 8) 88 | /// 89 | /// 90 | public readonly float Determinant3() 91 | { 92 | var det = 93 | m0 * m5 * m8 + 94 | m3 * m1 * m7 + 95 | m2 * m6 * m2 - 96 | m3 * m5 * m2 - 97 | m0 * m6 * m7 - 98 | m2 * m1 * m8; 99 | return det; 100 | } 101 | 102 | /// 103 | /// Determinant(0, 1, 3, 1, 4, 6, 2, 5, 8) 104 | /// 105 | /// 106 | public readonly float Determinant4() 107 | { 108 | var det = 109 | m0 * m4 * m8 + 110 | m3 * m1 * m5 + 111 | m1 * m6 * m2 - 112 | m3 * m4 * m2 - 113 | m0 * m6 * m5 - 114 | m1 * m1 * m8; 115 | return det; 116 | } 117 | 118 | public readonly float ComputeError(float3 position) 119 | { 120 | var x = position.x; 121 | var y = position.y; 122 | var z = position.z; 123 | 124 | return m0 * x * x 125 | + 2 * m1 * x * y 126 | + 2 * m2 * x * z 127 | + 2 * m3 * x 128 | + m4 * y * y 129 | + 2 * m5 * y * z 130 | + 2 * m6 * y 131 | + m7 * z * z 132 | + 2 * m8 * z + m9; 133 | } 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/ErrorQuadric.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3384960ddfb832b41beabc44b51c5717 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/JobHandleSpanExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Jobs; 3 | using Unity.Jobs.LowLevel.Unsafe; 4 | namespace Meshia.MeshSimplification 5 | { 6 | internal static class JobHandleSpanExtensions 7 | { 8 | public static unsafe JobHandle CombineDependencies(this ReadOnlySpan jobHandles) 9 | { 10 | fixed (JobHandle* jobHandlesPtr = jobHandles) 11 | { 12 | return JobHandleUnsafeUtility.CombineDependencies(jobHandlesPtr, jobHandles.Length); 13 | } 14 | } 15 | public static unsafe JobHandle CombineDependencies(this Span jobHandles) => ((ReadOnlySpan)jobHandles).CombineDependencies(); 16 | } 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/JobHandleSpanExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7192aa13ec6cce448a794b745bb41a3d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0197af1f25bcaf0448b70b30993fb432 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectEdgesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | namespace Meshia.MeshSimplification 6 | { 7 | [BurstCompile] 8 | struct CollectEdgesJob : IJob 9 | { 10 | [ReadOnly] 11 | public NativeArray Triangles; 12 | 13 | public NativeHashSet Edges; 14 | 15 | public void Execute() 16 | { 17 | Edges.Clear(); 18 | var maxEdgeCount = Triangles.Length * 3; 19 | if (Edges.Capacity < maxEdgeCount) 20 | { 21 | Edges.Capacity = maxEdgeCount; 22 | } 23 | foreach (var triangle in Triangles) 24 | { 25 | Edges.Add(triangle.xy); 26 | Edges.Add(triangle.yz); 27 | Edges.Add(triangle.zx); 28 | } 29 | } 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectEdgesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15fd813f1adc1a547ac2bc949e6558b6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectMergePairsJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | namespace Meshia.MeshSimplification 6 | { 7 | [BurstCompile] 8 | struct CollectMergePairsJob : IJob 9 | { 10 | [ReadOnly] 11 | public NativeHashSet Edges; 12 | [ReadOnly] 13 | public NativeHashSet SmartLinks; 14 | public NativeList MergePairs; 15 | 16 | public void Execute() 17 | { 18 | 19 | var maxPairCount = Edges.Count + SmartLinks.Count; 20 | 21 | 22 | MergePairs.Clear(); 23 | if (MergePairs.Capacity < maxPairCount) 24 | { 25 | MergePairs.Capacity = maxPairCount; 26 | } 27 | 28 | foreach (var link in SmartLinks) 29 | { 30 | if (!(Edges.Contains(link) || Edges.Contains(link.yx))) 31 | { 32 | MergePairs.AddNoResize(link); 33 | } 34 | } 35 | 36 | foreach (var pair in Edges) 37 | { 38 | var x = pair.x; 39 | var y = pair.y; 40 | if (pair.x <= pair.y) 41 | { 42 | MergePairs.AddNoResize(pair); 43 | } 44 | else 45 | { 46 | if (!Edges.Contains(pair.yx)) 47 | { 48 | MergePairs.AddNoResize(pair.yx); 49 | } 50 | 51 | 52 | } 53 | } 54 | } 55 | } 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectMergePairsJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0acb011243504a42a7c48749cc5a3e6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectNeighborVertexPairsJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Collections.LowLevel.Unsafe; 4 | using Unity.Jobs; 5 | using Unity.Mathematics; 6 | using UnityEngine; 7 | 8 | namespace Meshia.MeshSimplification 9 | { 10 | [BurstCompile] 11 | struct CollectNeighborVertexPairsJob : IJobParallelForDefer 12 | { 13 | [ReadOnly] 14 | public Mesh.MeshData Mesh; 15 | [ReadOnly] 16 | public NativeArray VertexPositionBuffer; 17 | [ReadOnly] 18 | public NativeBitArray VertexIsDiscardedBits; 19 | public MeshSimplifierOptions Options; 20 | public AllocatorManager.AllocatorHandle SubMeshSmartLinkListAllocator; 21 | public NativeArray> SubMeshSmartLinkLists; 22 | 23 | public void Execute(int subMeshIndex) 24 | { 25 | var subMeshDescriptor = Mesh.GetSubMesh(subMeshIndex); 26 | var subMeshVertexPositions = VertexPositionBuffer.GetSubArray(subMeshDescriptor.firstVertex, subMeshDescriptor.vertexCount); 27 | ref var subMeshSmartLinkList = ref SubMeshSmartLinkLists.ElementAt(subMeshIndex); 28 | subMeshSmartLinkList = new(256, SubMeshSmartLinkListAllocator); 29 | UnsafeKdTree kdTree = new(Allocator.Temp); 30 | UnsafeList linkOpponentVertices = new(16, Allocator.Temp); 31 | kdTree.Initialize(subMeshVertexPositions); 32 | 33 | for (int subMeshVertexIndex = 0; subMeshVertexIndex < subMeshVertexPositions.Length; subMeshVertexIndex++) 34 | { 35 | if (VertexIsDiscardedBits.IsSet(subMeshDescriptor.firstVertex + subMeshVertexIndex)) 36 | { 37 | continue; 38 | } 39 | var vertexPosition = subMeshVertexPositions[subMeshVertexIndex]; 40 | 41 | kdTree.QueryPointsInSphere(subMeshVertexPositions, vertexPosition, Options.VertexLinkDistance, ref linkOpponentVertices); 42 | 43 | foreach (var linkOpponentVertexIndex in linkOpponentVertices) 44 | { 45 | if (subMeshVertexIndex < linkOpponentVertexIndex && !VertexIsDiscardedBits.IsSet(subMeshDescriptor.firstVertex + linkOpponentVertexIndex)) 46 | { 47 | var pair = new int2(subMeshVertexIndex, linkOpponentVertexIndex) + subMeshDescriptor.firstVertex; 48 | subMeshSmartLinkList.Add(pair); 49 | } 50 | } 51 | 52 | linkOpponentVertices.Clear(); 53 | } 54 | 55 | linkOpponentVertices.Dispose(); 56 | kdTree.Dispose(); 57 | } 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectNeighborVertexPairsJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9683a9384075e274fab3b4351326fc9e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectSmartLinksJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Collections.LowLevel.Unsafe; 4 | using Unity.Jobs; 5 | using Unity.Mathematics; 6 | 7 | namespace Meshia.MeshSimplification 8 | { 9 | [BurstCompile] 10 | struct CollectSmartLinksJob : IJob 11 | { 12 | public NativeArray> SubMeshSmartLinkLists; 13 | public NativeHashSet SmartLinks; 14 | public void Execute() 15 | { 16 | var smartLinkCount = 0; 17 | for (int subMeshIndex = 0; subMeshIndex < SubMeshSmartLinkLists.Length; subMeshIndex++) 18 | { 19 | smartLinkCount += SubMeshSmartLinkLists[subMeshIndex].Length; 20 | } 21 | SmartLinks.Clear(); 22 | if (SmartLinks.Capacity < smartLinkCount) 23 | { 24 | SmartLinks.Capacity = smartLinkCount; 25 | } 26 | for (int subMeshIndex = 0; subMeshIndex < SubMeshSmartLinkLists.Length; subMeshIndex++) 27 | { 28 | ref var subMeshSmartLinkList = ref SubMeshSmartLinkLists.ElementAt(subMeshIndex); 29 | for (int subMeshSmartLinkIndex = 0; subMeshSmartLinkIndex < subMeshSmartLinkList.Length; subMeshSmartLinkIndex++) 30 | { 31 | var link = subMeshSmartLinkList[subMeshSmartLinkIndex]; 32 | SmartLinks.Add(link); 33 | } 34 | subMeshSmartLinkList.Dispose(); 35 | } 36 | } 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectSmartLinksJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae0883c13bdae2d45b8f57346a6b6541 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexContainingSubMeshIndicesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Burst.CompilerServices; 3 | using Unity.Collections; 4 | using Unity.Jobs; 5 | using UnityEngine; 6 | 7 | namespace Meshia.MeshSimplification 8 | { 9 | [BurstCompile] 10 | struct CollectVertexContainingSubMeshIndicesJob : IJob 11 | { 12 | [ReadOnly] public Mesh.MeshData Mesh; 13 | 14 | public NativeList VertexContainingSubMeshIndices; 15 | 16 | public void Execute() 17 | { 18 | VertexContainingSubMeshIndices.Resize(Mesh.vertexCount, NativeArrayOptions.ClearMemory); 19 | for (int subMeshIndex = 0; subMeshIndex < Mesh.subMeshCount; subMeshIndex++) 20 | { 21 | ProcessSubMesh(subMeshIndex); 22 | } 23 | } 24 | 25 | private void ProcessSubMesh(int subMeshIndex) 26 | { 27 | var subMesh = Mesh.GetSubMesh(subMeshIndex); 28 | uint bit = 1u << subMeshIndex; 29 | 30 | var subMeshVertexContainingSubMeshIndices = VertexContainingSubMeshIndices.AsArray().GetSubArray(subMesh.firstVertex, subMesh.vertexCount).AsSpan(); 31 | 32 | for (int subMeshVertexIndex = 0; subMeshVertexIndex < subMeshVertexContainingSubMeshIndices.Length; subMeshVertexIndex++) 33 | { 34 | #if UNITY_BURST_EXPERIMENTAL_LOOP_INTRINSICS 35 | Loop.ExpectVectorized(); 36 | #endif 37 | subMeshVertexContainingSubMeshIndices[subMeshVertexIndex] |= bit; 38 | } 39 | 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexContainingSubMeshIndicesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f095b4a3d6c82064989f78a6a072f5c2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexContainingTrianglesAndMarkInvalidTrianglesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | namespace Meshia.MeshSimplification 6 | { 7 | [BurstCompile] 8 | struct CollectVertexContainingTrianglesAndMarkInvalidTrianglesJob : IJob 9 | { 10 | [ReadOnly] public NativeArray Triangles; 11 | public NativeParallelMultiHashMap VertexContainingTriangles; 12 | public NativeBitArray TriangleIsDiscardedBits; 13 | public void Execute() 14 | { 15 | VertexContainingTriangles.Clear(); 16 | VertexContainingTriangles.Capacity = Triangles.Length * 3; 17 | TriangleIsDiscardedBits.Resize(Triangles.Length); 18 | 19 | for (int triangle = 0; triangle < Triangles.Length; triangle++) 20 | { 21 | var vertices = Triangles[triangle]; 22 | 23 | if (vertices.x == vertices.y | vertices.y == vertices.z | vertices.z == vertices.x) 24 | { 25 | TriangleIsDiscardedBits.Set(triangle, true); 26 | } 27 | else 28 | { 29 | TriangleIsDiscardedBits.Set(triangle, false); 30 | 31 | VertexContainingTriangles.Add(vertices.x, triangle); 32 | VertexContainingTriangles.Add(vertices.y, triangle); 33 | VertexContainingTriangles.Add(vertices.z, triangle); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexContainingTrianglesAndMarkInvalidTrianglesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0bdb81e29db3c6a49bd4688154120c30 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexMergeOpponmentsJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | namespace Meshia.MeshSimplification 5 | { 6 | [BurstCompile] 7 | unsafe struct CollectVertexMergeOpponmentsJob : IJob 8 | { 9 | [ReadOnly] 10 | public NativeArray UnorderedDirtyVertexMerges; 11 | public NativeParallelMultiHashMap VertexMergeOpponentVertices; 12 | public void Execute() 13 | { 14 | VertexMergeOpponentVertices.Clear(); 15 | VertexMergeOpponentVertices.Capacity = UnorderedDirtyVertexMerges.Length * 2; 16 | for (int index = 0; index < UnorderedDirtyVertexMerges.Length; index++) 17 | { 18 | var merge = UnorderedDirtyVertexMerges[index]; 19 | if (float.IsPositiveInfinity(merge.Cost)) 20 | { 21 | continue; 22 | } 23 | var vertexA = merge.VertexAIndex; 24 | var vertexB = merge.VertexBIndex; 25 | VertexMergeOpponentVertices.Add(vertexA, vertexB); 26 | VertexMergeOpponentVertices.Add(vertexB, vertexA); 27 | } 28 | } 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexMergeOpponmentsJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 637fcf8289a91bb4eb5afa3413232e63 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexMergesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | namespace Meshia.MeshSimplification 5 | { 6 | [BurstCompile] 7 | unsafe struct CollectVertexMergesJob : IJob 8 | { 9 | [ReadOnly] 10 | public NativeArray UnorderedDirtyVertexMerges; 11 | public NativeMinPriorityQueue VertexMerges; 12 | public void Execute() 13 | { 14 | ref var vertexMerges = ref VertexMerges.GetUnsafePriorityQueue()->nodes; 15 | vertexMerges.Clear(); 16 | vertexMerges.SetCapacity(UnorderedDirtyVertexMerges.Length); 17 | 18 | for (int i = 0; i < UnorderedDirtyVertexMerges.Length; i++) 19 | { 20 | var merge = UnorderedDirtyVertexMerges[i]; 21 | if (!float.IsPositiveInfinity(merge.Cost)) 22 | { 23 | vertexMerges.AddNoResize(merge); 24 | } 25 | } 26 | VertexMerges.GetUnsafePriorityQueue()->Heapify(); 27 | } 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CollectVertexMergesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 488dec1560e2d91499c28d906a5bda77 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/ComputeMergesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | namespace Meshia.MeshSimplification 6 | { 7 | [BurstCompile] 8 | struct ComputeMergesJob : IJobParallelForDefer 9 | { 10 | [ReadOnly] 11 | public NativeArray VertexPositionBuffer; 12 | [ReadOnly] 13 | public NativeArray VertexErrorQuadrics; 14 | [ReadOnly] 15 | public NativeArray TriangleNormals; 16 | [ReadOnly] 17 | public NativeParallelMultiHashMap VertexContainingTriangles; 18 | [ReadOnly] 19 | public NativeBitArray VertexIsBorderEdgeBits; 20 | [ReadOnly] 21 | public NativeArray Edges; 22 | [WriteOnly] 23 | public NativeArray UnorderedDirtyVertexMerges; 24 | 25 | public MeshSimplifierOptions Options; 26 | public void Execute(int index) 27 | { 28 | var mergeFactory = new MergeFactory 29 | { 30 | VertexPositions = VertexPositionBuffer, 31 | VertexErrorQuadrics = VertexErrorQuadrics, 32 | VertexContainingTriangles = VertexContainingTriangles, 33 | VertexIsBorderEdgeBits = VertexIsBorderEdgeBits, 34 | TriangleNormals = TriangleNormals, 35 | Options = Options, 36 | }; 37 | var edge = Edges[index]; 38 | VertexMerge merge; 39 | if (mergeFactory.TryComputeMerge(edge, out var position, out var cost)) 40 | { 41 | merge = new() 42 | { 43 | VertexAIndex = edge.x, 44 | VertexBIndex = edge.y, 45 | VertexAVersion = 0, 46 | VertexBVersion = 0, 47 | Position = position, 48 | Cost = cost, 49 | }; 50 | 51 | } 52 | else 53 | { 54 | 55 | merge = new() 56 | { 57 | VertexAIndex = edge.x, 58 | VertexBIndex = edge.y, 59 | VertexAVersion = 0, 60 | VertexBVersion = 0, 61 | Position = float.NaN, 62 | Cost = float.PositiveInfinity, 63 | }; 64 | } 65 | UnorderedDirtyVertexMerges[index] = merge; 66 | 67 | } 68 | } 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/ComputeMergesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f509248d642d4a41beeca7d968ccf5d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/ComputeTriangleNormalsAndErrorQuadricsJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | using Plane = Unity.Mathematics.Geometry.Plane; 6 | namespace Meshia.MeshSimplification 7 | { 8 | [BurstCompile] 9 | struct ComputeTriangleNormalsAndErrorQuadricsJob : IJobParallelForDefer 10 | { 11 | [ReadOnly] 12 | public NativeArray VertexPositionBuffer; 13 | [ReadOnly] 14 | public NativeArray Triangles; 15 | [WriteOnly] 16 | public NativeArray TriangleNormals; 17 | [WriteOnly] 18 | public NativeArray TriangleErrorQuadrics; 19 | public void Execute(int triangleIndex) 20 | { 21 | var triangle = Triangles[triangleIndex]; 22 | var x = VertexPositionBuffer[triangle.x]; 23 | var y = VertexPositionBuffer[triangle.y]; 24 | var z = VertexPositionBuffer[triangle.z]; 25 | 26 | var xy = y - x; 27 | var xz = z - x; 28 | var plane = new Plane(math.cross(xy, xz), x); 29 | 30 | TriangleNormals[triangleIndex] = plane.Normal; 31 | 32 | TriangleErrorQuadrics[triangleIndex] = new ErrorQuadric(plane); 33 | } 34 | } 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/ComputeTriangleNormalsAndErrorQuadricsJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59bef79974d17504aaf1566763d8c1da 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/ComputeVertexErrorQuadricsJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Burst; 3 | using Unity.Collections; 4 | using Unity.Jobs; 5 | using Unity.Mathematics; 6 | using Plane = Unity.Mathematics.Geometry.Plane; 7 | namespace Meshia.MeshSimplification 8 | { 9 | [BurstCompile] 10 | struct ComputeVertexErrorQuadricsJob : IJobParallelForDefer 11 | { 12 | [ReadOnly] 13 | public NativeArray VertexPositionBuffer; 14 | [ReadOnly] 15 | public NativeArray Triangles; 16 | [ReadOnly] 17 | public NativeParallelMultiHashMap VertexContainingTriangles; 18 | [ReadOnly] 19 | public NativeHashSet Edges; 20 | [ReadOnly] 21 | public NativeArray TriangleErrorQuadrics; 22 | [WriteOnly] 23 | public NativeArray VertexErrorQuadrics; 24 | public void Execute(int vertexIndex) 25 | { 26 | var vertexErrorQuadric = new ErrorQuadric(); 27 | var vertexPosition = VertexPositionBuffer[vertexIndex]; 28 | foreach (var triangleIndex in VertexContainingTriangles.GetValuesForKey(vertexIndex)) 29 | { 30 | var triangle = Triangles[triangleIndex]; 31 | 32 | int2x2 belongingEdges; 33 | if (vertexIndex == triangle.x) 34 | { 35 | belongingEdges = new(triangle.xy, triangle.zx); 36 | } 37 | else if (vertexIndex == triangle.y) 38 | { 39 | belongingEdges = new(triangle.xy, triangle.yz); 40 | } 41 | else if (vertexIndex == triangle.z) 42 | { 43 | belongingEdges = new(triangle.yz, triangle.zx); 44 | } 45 | else 46 | { 47 | throw new Exception(); 48 | } 49 | 50 | 51 | if (!Edges.Contains(belongingEdges.c0.yx) || !Edges.Contains(belongingEdges.c1.yx)) 52 | { 53 | vertexErrorQuadric += new ErrorQuadric(new Plane(math.right(), vertexPosition)); 54 | 55 | vertexErrorQuadric += new ErrorQuadric(new Plane(math.up(), vertexPosition)); 56 | 57 | vertexErrorQuadric += new ErrorQuadric(new Plane(math.forward(), vertexPosition)); 58 | } 59 | else 60 | { 61 | vertexErrorQuadric += TriangleErrorQuadrics[triangleIndex]; 62 | } 63 | } 64 | VertexErrorQuadrics[vertexIndex] = vertexErrorQuadric; 65 | } 66 | } 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/ComputeVertexErrorQuadricsJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 651adf73a30a9da4eafe1026a874d1cf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CopyTrianglesJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Burst; 3 | using Unity.Collections; 4 | using Unity.Jobs; 5 | using Unity.Mathematics; 6 | using UnityEngine; 7 | using UnityEngine.Rendering; 8 | namespace Meshia.MeshSimplification 9 | { 10 | [BurstCompile] 11 | struct CopyTrianglesJob : IJob 12 | { 13 | [ReadOnly] 14 | public Mesh.MeshData Mesh; 15 | 16 | public NativeList Triangles; 17 | 18 | public void Execute() 19 | { 20 | 21 | var triangleCount = Mesh.GetTriangleCount(); 22 | Triangles.Clear(); 23 | Triangles.Capacity = triangleCount; 24 | 25 | switch (Mesh.indexFormat) 26 | { 27 | case IndexFormat.UInt16: 28 | { 29 | var indexBuffer = Mesh.GetIndexData(); 30 | for (int subMeshIndex = 0; subMeshIndex < Mesh.subMeshCount; subMeshIndex++) 31 | { 32 | var subMesh = Mesh.GetSubMesh(subMeshIndex); 33 | if (subMesh.topology == MeshTopology.Triangles) 34 | { 35 | var subMeshIndexBuffer = indexBuffer.GetSubArray(subMesh.indexStart, subMesh.indexCount); 36 | var subMeshTriangleCount = subMesh.indexCount / 3; 37 | for (int subMeshTriangleIndex = 0; subMeshTriangleIndex < subMeshTriangleCount; subMeshTriangleIndex++) 38 | { 39 | int3 triangle = new() 40 | { 41 | x = subMesh.baseVertex + subMeshIndexBuffer[subMeshTriangleIndex * 3 + 0], 42 | y = subMesh.baseVertex + subMeshIndexBuffer[subMeshTriangleIndex * 3 + 1], 43 | z = subMesh.baseVertex + subMeshIndexBuffer[subMeshTriangleIndex * 3 + 2], 44 | }; 45 | Triangles.AddNoResize(triangle); 46 | } 47 | } 48 | } 49 | } 50 | break; 51 | case IndexFormat.UInt32: 52 | { 53 | var indexBuffer = Mesh.GetIndexData(); 54 | for (int subMeshIndex = 0; subMeshIndex < Mesh.subMeshCount; subMeshIndex++) 55 | { 56 | var subMesh = Mesh.GetSubMesh(subMeshIndex); 57 | if (subMesh.topology == MeshTopology.Triangles) 58 | { 59 | var subMeshIndexBuffer = indexBuffer.GetSubArray(subMesh.indexStart, subMesh.indexCount); 60 | var subMeshTriangleCount = subMesh.indexCount / 3; 61 | for (int subMeshTriangleIndex = 0; subMeshTriangleIndex < subMeshTriangleCount; subMeshTriangleIndex++) 62 | { 63 | int3 triangle = new() 64 | { 65 | x = subMesh.baseVertex + subMeshIndexBuffer[subMeshTriangleIndex * 3 + 0], 66 | y = subMesh.baseVertex + subMeshIndexBuffer[subMeshTriangleIndex * 3 + 1], 67 | z = subMesh.baseVertex + subMeshIndexBuffer[subMeshTriangleIndex * 3 + 2], 68 | }; 69 | Triangles.AddNoResize(triangle); 70 | } 71 | } 72 | } 73 | } 74 | break; 75 | default: 76 | throw new NotSupportedException(); 77 | } 78 | } 79 | } 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CopyTrianglesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5c64590314fd1c9418e64bcc536406f7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CopyVertexAttributesJobs.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | using UnityEngine.Rendering; 7 | 8 | namespace Meshia.MeshSimplification 9 | { 10 | [BurstCompile] 11 | struct CopyVertexPositionBufferJob : IJob 12 | { 13 | [ReadOnly] public Mesh.MeshData Mesh; 14 | public NativeList VertexPositionBuffer; 15 | public void Execute() 16 | { 17 | VertexPositionBuffer.Resize(Mesh.vertexCount, NativeArrayOptions.UninitializedMemory); 18 | Mesh.GetVertices(VertexPositionBuffer.AsArray().Reinterpret()); 19 | } 20 | } 21 | [BurstCompile] 22 | struct CopyVertexNormalBufferJob : IJob 23 | { 24 | [ReadOnly] public Mesh.MeshData Mesh; 25 | public NativeList VertexNormalBuffer; 26 | public void Execute() 27 | { 28 | if (Mesh.HasVertexAttribute(VertexAttribute.Normal)) 29 | { 30 | VertexNormalBuffer.Resize(Mesh.vertexCount, NativeArrayOptions.UninitializedMemory); 31 | Mesh.GetNormals(VertexNormalBuffer.AsArray().Reinterpret()); 32 | } 33 | else 34 | { 35 | VertexNormalBuffer.Clear(); 36 | } 37 | } 38 | 39 | } 40 | 41 | [BurstCompile] 42 | struct CopyVertexAttributeBufferAsFloat4Job : IJob 43 | { 44 | [ReadOnly] public Mesh.MeshData Mesh; 45 | public VertexAttribute VertexAttribute; 46 | public NativeList VertexAttributeBuffer; 47 | 48 | public void Execute() 49 | { 50 | if (Mesh.HasVertexAttribute(VertexAttribute)) 51 | { 52 | 53 | VertexAttributeBuffer.Resize(Mesh.vertexCount, NativeArrayOptions.UninitializedMemory); 54 | Mesh.GetVertexAttributeDataAsFloat4(VertexAttribute, VertexAttributeBuffer.AsArray().AsSpan()); 55 | } 56 | else 57 | { 58 | VertexAttributeBuffer.Clear(); 59 | } 60 | } 61 | } 62 | [BurstCompile] 63 | struct CopyVertexBlendWeightBufferJob : IJob 64 | { 65 | [ReadOnly] public Mesh.MeshData Mesh; 66 | public NativeList VertexBlendWeightBuffer; 67 | public void Execute() 68 | { 69 | 70 | 71 | if (Mesh.HasVertexAttribute(VertexAttribute.BlendWeight)) 72 | { 73 | VertexBlendWeightBuffer.Resize(Mesh.vertexCount * Mesh.GetVertexAttributeDimension(VertexAttribute.BlendWeight), NativeArrayOptions.UninitializedMemory); 74 | Mesh.GetVertexAttributeDataAsFloats(VertexAttribute.BlendWeight, VertexBlendWeightBuffer.AsArray()); 75 | } 76 | else 77 | { 78 | VertexBlendWeightBuffer.Clear(); 79 | } 80 | } 81 | } 82 | [BurstCompile] 83 | struct CopyVertexBlendIndicesBufferJob : IJob 84 | { 85 | [ReadOnly] public Mesh.MeshData Mesh; 86 | public NativeList VertexBlendIndicesBuffer; 87 | public void Execute() 88 | { 89 | 90 | 91 | if (Mesh.HasVertexAttribute(VertexAttribute.BlendIndices)) 92 | { 93 | VertexBlendIndicesBuffer.Resize(Mesh.vertexCount * Mesh.GetVertexAttributeDimension(VertexAttribute.BlendIndices), NativeArrayOptions.UninitializedMemory); 94 | Mesh.GetVertexAttributeDataAsInts(VertexAttribute.BlendIndices, VertexBlendIndicesBuffer.AsArray().Reinterpret()); 95 | } 96 | else 97 | { 98 | VertexBlendIndicesBuffer.Clear(); 99 | } 100 | } 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/CopyVertexAttributesJobs.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30a598bf266ffa240b6524f5c465ade5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/DisposeBlendShapesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | 5 | namespace Meshia.MeshSimplification 6 | { 7 | [BurstCompile] 8 | struct DisposeBlendShapesJob : IJob 9 | { 10 | public NativeList BlendShapes; 11 | 12 | public void Execute() 13 | { 14 | for (int simplifiedBlendShapesIndex = 0; simplifiedBlendShapesIndex < BlendShapes.Length; simplifiedBlendShapesIndex++) 15 | { 16 | var blendShape = BlendShapes[simplifiedBlendShapesIndex]; 17 | blendShape.Dispose(); 18 | } 19 | } 20 | } 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/DisposeBlendShapesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7671ac537619f5d438f8ebbce2029c74 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/FindNonReferencedVerticesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using UnityEngine; 5 | namespace Meshia.MeshSimplification 6 | { 7 | [BurstCompile] 8 | struct FindNonReferencedVerticesJob : IJob 9 | { 10 | [ReadOnly] public Mesh.MeshData Mesh; 11 | [ReadOnly] public NativeParallelMultiHashMap VertexContainingTriangles; 12 | public NativeBitArray VertexIsDiscardedBits; 13 | public void Execute() 14 | { 15 | VertexIsDiscardedBits.Resize(Mesh.vertexCount); 16 | 17 | 18 | for (int vertex = 0; vertex < Mesh.vertexCount; vertex++) 19 | { 20 | VertexIsDiscardedBits.Set(vertex, !VertexContainingTriangles.ContainsKey(vertex)); 21 | } 22 | 23 | for (int subMeshIndex = 0; subMeshIndex < Mesh.subMeshCount; subMeshIndex++) 24 | { 25 | var subMeshDescriptor = Mesh.GetSubMesh(subMeshIndex); 26 | if (subMeshDescriptor.topology is not MeshTopology.Triangles) 27 | { 28 | VertexIsDiscardedBits.SetBits(subMeshDescriptor.firstVertex, false, subMeshDescriptor.vertexCount); 29 | } 30 | } 31 | } 32 | } 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/FindNonReferencedVerticesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d3bc8ad297738d640b4c45cade115f43 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/InitializeBufferJobs.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | namespace Meshia.MeshSimplification 7 | { 8 | 9 | [BurstCompile] 10 | struct InitializeVertexListJob : IJob 11 | where T : unmanaged 12 | { 13 | [ReadOnly] 14 | public Mesh.MeshData MeshData; 15 | public NativeArrayOptions Options; 16 | public NativeList Buffer; 17 | public void Execute() 18 | { 19 | Buffer.Clear(); 20 | Buffer.Resize(MeshData.vertexCount, Options); 21 | } 22 | } 23 | [BurstCompile] 24 | struct InitializeSubMeshListJob : IJob 25 | where T : unmanaged 26 | { 27 | [ReadOnly] 28 | public Mesh.MeshData MeshData; 29 | public NativeArrayOptions Options; 30 | public NativeList Buffer; 31 | public void Execute() 32 | { 33 | Buffer.Clear(); 34 | Buffer.Resize(MeshData.subMeshCount, Options); 35 | } 36 | } 37 | 38 | [BurstCompile] 39 | struct InitializeVertexBitArrayJob : IJob 40 | { 41 | [ReadOnly] 42 | public Mesh.MeshData MeshData; 43 | public NativeBitArray Buffer; 44 | public void Execute() 45 | { 46 | Buffer.Resize(MeshData.vertexCount, NativeArrayOptions.UninitializedMemory); 47 | Buffer.Clear(); 48 | } 49 | } 50 | 51 | [BurstCompile] 52 | struct InitializeTriangleListJob : IJob 53 | where T : unmanaged 54 | { 55 | [ReadOnly] 56 | public Mesh.MeshData MeshData; 57 | public NativeArrayOptions Options; 58 | public NativeList Buffer; 59 | public void Execute() 60 | { 61 | var triangleCount = MeshData.GetTriangleCount(); 62 | Buffer.Clear(); 63 | Buffer.Resize(triangleCount, Options); 64 | } 65 | } 66 | [BurstCompile] 67 | struct InitializeUnorderedDirtyVertexMergesJob : IJob 68 | { 69 | 70 | [ReadOnly] 71 | public NativeArray Edges; 72 | public NativeList UnorderedDirtyVertexMerges; 73 | 74 | public void Execute() 75 | { 76 | UnorderedDirtyVertexMerges.ResizeUninitialized(Edges.Length); 77 | } 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/InitializeBufferJobs.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5a760878729ce74baba122c83a11416 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/MarkBorderEdgeVerticesJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | namespace Meshia.MeshSimplification 7 | { 8 | [BurstCompile] 9 | struct MarkBorderEdgeVerticesJob : IJob 10 | { 11 | [ReadOnly] 12 | public Mesh.MeshData Mesh; 13 | [ReadOnly] 14 | public NativeHashSet Edges; 15 | public NativeBitArray VertexIsBorderEdgeBits; 16 | public void Execute() 17 | { 18 | VertexIsBorderEdgeBits.Resize(Mesh.vertexCount); 19 | VertexIsBorderEdgeBits.Clear(); 20 | foreach (var pair in Edges) 21 | { 22 | var x = pair.x; 23 | var y = pair.y; 24 | if (!Edges.Contains(new(y, x))) 25 | { 26 | VertexIsBorderEdgeBits.Set(x, true); 27 | VertexIsBorderEdgeBits.Set(y, true); 28 | } 29 | } 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/MarkBorderEdgeVerticesJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d9a4da1ddc7d4d44a8cf2013bf949ed4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/RemoveHighCostSmartLinksJob.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Collections.LowLevel.Unsafe; 4 | using Unity.Jobs; 5 | using Unity.Mathematics; 6 | 7 | namespace Meshia.MeshSimplification 8 | { 9 | [BurstCompile] 10 | struct RemoveHighCostSmartLinksJob : IJobParallelForDefer 11 | { 12 | [ReadOnly] 13 | public NativeArray VertexNormalBuffer; 14 | [ReadOnly] 15 | public NativeArray VertexColorBuffer; 16 | [ReadOnly] 17 | public NativeArray VertexTexCoord0Buffer; 18 | [ReadOnly] 19 | public NativeArray VertexTexCoord1Buffer; 20 | [ReadOnly] 21 | public NativeArray VertexTexCoord2Buffer; 22 | [ReadOnly] 23 | public NativeArray VertexTexCoord3Buffer; 24 | [ReadOnly] 25 | public NativeArray VertexTexCoord4Buffer; 26 | [ReadOnly] 27 | public NativeArray VertexTexCoord5Buffer; 28 | [ReadOnly] 29 | public NativeArray VertexTexCoord6Buffer; 30 | [ReadOnly] 31 | public NativeArray VertexTexCoord7Buffer; 32 | 33 | public MeshSimplifierOptions Options; 34 | 35 | public NativeArray> SubMeshSmartLinkLists; 36 | 37 | public void Execute(int subMeshIndex) 38 | { 39 | ref var subMeshSmartLinkList = ref SubMeshSmartLinkLists.ElementAt(subMeshIndex); 40 | var subMeshSmartLinkIndex = 0; 41 | 42 | var squaredMaxColorDistance = Options.VertexLinkColorDistance * Options.VertexLinkColorDistance; 43 | var squaredMaxUvDistance = Options.VertexLinkUvDistance * Options.VertexLinkUvDistance; 44 | 45 | while (subMeshSmartLinkIndex < subMeshSmartLinkList.Length) 46 | { 47 | var link = subMeshSmartLinkList[subMeshSmartLinkIndex]; 48 | if ( 49 | (VertexNormalBuffer.Length == 0 || Options.VertexLinkMinNormalDot <= NormalDot(link)) 50 | && (VertexColorBuffer.Length == 0 || SquaredDistance(VertexColorBuffer, link) < squaredMaxColorDistance) 51 | && (VertexTexCoord0Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 52 | && (VertexTexCoord1Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 53 | && (VertexTexCoord2Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 54 | && (VertexTexCoord3Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 55 | && (VertexTexCoord4Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 56 | && (VertexTexCoord5Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 57 | && (VertexTexCoord6Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 58 | && (VertexTexCoord7Buffer.Length == 0 || SquaredDistance(VertexTexCoord0Buffer, link) < squaredMaxUvDistance) 59 | ) 60 | { 61 | subMeshSmartLinkIndex++; 62 | } 63 | else 64 | { 65 | subMeshSmartLinkList.RemoveAtSwapBack(subMeshSmartLinkIndex); 66 | } 67 | } 68 | } 69 | float NormalDot(int2 link) 70 | { 71 | return math.dot(VertexNormalBuffer[link.x].xyz, VertexNormalBuffer[link.y].xyz); 72 | } 73 | static float SquaredDistance(NativeArray buffer, int2 link) 74 | { 75 | return math.distancesq(buffer[link.x], buffer[link.y]); 76 | } 77 | } 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/RemoveHighCostSmartLinksJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60f51ad10463173448ab8b01c1d676e0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/SimplifyJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80d87a9720da34c4da1750954973cfcc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Jobs/WriteToMeshDataJob.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2f2bf90b6ce1d043b120aff3034252b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MergeFactory.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Collections.LowLevel.Unsafe; 4 | using Unity.Mathematics; 5 | using Unity.Profiling; 6 | namespace Meshia.MeshSimplification 7 | { 8 | struct MergeFactory 9 | { 10 | public NativeArray VertexPositions; 11 | public NativeArray VertexErrorQuadrics; 12 | public NativeParallelMultiHashMap VertexContainingTriangles; 13 | public NativeBitArray VertexIsBorderEdgeBits; 14 | public NativeArray TriangleNormals; 15 | public MeshSimplifierOptions Options; 16 | 17 | 18 | [BurstCompile] 19 | static class ProfilerMarkers 20 | { 21 | public static readonly ProfilerMarker TryComputeMerge = new(nameof(TryComputeMerge)); 22 | public static readonly ProfilerMarker ComputeCurvatureError = new(nameof(ComputeCurvatureError)); 23 | } 24 | 25 | public bool TryComputeMerge(int2 vertices, out float3 position, out float cost) 26 | { 27 | using (ProfilerMarkers.TryComputeMerge.Auto()) 28 | { 29 | var q = VertexErrorQuadrics[vertices.x] + VertexErrorQuadrics[vertices.y]; 30 | 31 | var xIsBorderEdge = VertexIsBorderEdgeBits.IsSet(vertices.x); 32 | var yIsBorderEdge = VertexIsBorderEdgeBits.IsSet(vertices.y); 33 | 34 | var positionX = VertexPositions[vertices.x]; 35 | var positionY = VertexPositions[vertices.y]; 36 | 37 | float vertexError; 38 | if (Options.PreserveBorderEdges) 39 | { 40 | if (xIsBorderEdge && yIsBorderEdge) 41 | { 42 | position = float.NaN; 43 | cost = float.PositiveInfinity; 44 | return false; 45 | } 46 | else if (xIsBorderEdge) 47 | { 48 | position = positionX; 49 | goto ComputeVertexError; 50 | } 51 | else if (yIsBorderEdge) 52 | { 53 | position = positionY; 54 | goto ComputeVertexError; 55 | } 56 | } 57 | 58 | var determinant = q.Determinant1(); 59 | if (determinant != 0) 60 | { 61 | position = new float3 62 | { 63 | x = -1 / determinant * q.Determinant2(), 64 | y = 1 / determinant * q.Determinant3(), 65 | z = -1 / determinant * q.Determinant4(), 66 | }; 67 | 68 | goto ComputeVertexError; 69 | } 70 | else 71 | { 72 | var positionZ = (positionX + positionY) * 0.5f; 73 | var errorX = q.ComputeError(positionX); 74 | var errorY = q.ComputeError(positionY); 75 | var errorZ = q.ComputeError(positionZ); 76 | 77 | if (errorX < errorY) 78 | { 79 | if (errorX < errorZ) 80 | { 81 | position = positionX; 82 | vertexError = errorX; 83 | 84 | } 85 | else 86 | { 87 | position = positionZ; 88 | vertexError = errorZ; 89 | } 90 | } 91 | else 92 | { 93 | if (errorY < errorZ) 94 | { 95 | position = positionY; 96 | vertexError = errorY; 97 | } 98 | else 99 | { 100 | position = positionZ; 101 | vertexError = errorZ; 102 | } 103 | } 104 | 105 | goto ApplyCurvatureError; 106 | } 107 | 108 | 109 | ComputeVertexError: 110 | vertexError = q.ComputeError(position); 111 | 112 | ApplyCurvatureError: 113 | var curvatureError = Options.PreserveSurfaceCurvature ? ComputeCurvatureError(vertices) : 0; 114 | 115 | cost = vertexError + curvatureError; 116 | return true; 117 | } 118 | 119 | } 120 | float ComputeCurvatureError(int2 vertices) 121 | { 122 | 123 | using (ProfilerMarkers.ComputeCurvatureError.Auto()) 124 | { 125 | var distance = math.distance(VertexPositions[vertices.x], VertexPositions[vertices.y]); 126 | using UnsafeHashSet vertexXContainingTriangles = new(8, Allocator.Temp); 127 | 128 | using UnsafeList vertexXOrYContainingTriangles = new(16, Allocator.Temp); 129 | 130 | 131 | foreach (var vertexXContainingTriangle in VertexContainingTriangles.GetValuesForKey(vertices.x)) 132 | { 133 | vertexXContainingTriangles.Add(vertexXContainingTriangle); 134 | vertexXOrYContainingTriangles.Add(vertexXContainingTriangle); 135 | } 136 | 137 | 138 | using UnsafeList vertexXAndYContainingTriangles = new(8, Allocator.Temp); 139 | 140 | foreach (var vertexYContainingTriangle in VertexContainingTriangles.GetValuesForKey(vertices.y)) 141 | { 142 | if (vertexXContainingTriangles.Contains(vertexYContainingTriangle)) 143 | { 144 | vertexXAndYContainingTriangles.Add(vertexYContainingTriangle); 145 | } 146 | else 147 | { 148 | vertexXOrYContainingTriangles.Add(vertexYContainingTriangle); 149 | } 150 | } 151 | 152 | vertexXContainingTriangles.Dispose(); 153 | 154 | var maxDot = 0f; 155 | 156 | foreach (var vertexXOrYContainingTriangle in vertexXOrYContainingTriangles) 157 | { 158 | var vertexXOrYContainingTriangleNormal = TriangleNormals[vertexXOrYContainingTriangle]; 159 | 160 | foreach (var vertexXAndYContainingTriangle in vertexXAndYContainingTriangles) 161 | { 162 | var vertexXAndYContainingTriangleNormal = TriangleNormals[vertexXAndYContainingTriangle]; 163 | var dot = math.dot(vertexXOrYContainingTriangleNormal, vertexXAndYContainingTriangleNormal); 164 | maxDot = math.max(dot, maxDot); 165 | } 166 | } 167 | return distance * maxDot; 168 | } 169 | } 170 | } 171 | } 172 | 173 | 174 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MergeFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c37acb66e9d7fd34c87e8accc7290c73 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshDataHelpers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fe9e10961acab2e4e93f69881d9239ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplificationTarget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Meshia.MeshSimplification 5 | { 6 | /// 7 | /// Represents a target for mesh simplification. 8 | /// 9 | [Serializable] 10 | public struct MeshSimplificationTarget : IEquatable 11 | { 12 | /// 13 | /// Represents what actually means. 14 | /// 15 | public MeshSimplificationTargetKind Kind; 16 | 17 | /// 18 | /// The target value for mesh simplification. determines what this value represents. 19 | /// 20 | /// 21 | [Min(0)] 22 | public float Value; 23 | 24 | public override readonly bool Equals(object obj) 25 | { 26 | return obj is MeshSimplificationTarget target && Equals(target); 27 | } 28 | 29 | public readonly bool Equals(MeshSimplificationTarget other) 30 | { 31 | return Kind == other.Kind && 32 | Value == other.Value; 33 | } 34 | 35 | public override readonly int GetHashCode() 36 | { 37 | return HashCode.Combine(Kind, Value); 38 | } 39 | 40 | public static bool operator ==(MeshSimplificationTarget left, MeshSimplificationTarget right) 41 | { 42 | return left.Equals(right); 43 | } 44 | 45 | public static bool operator !=(MeshSimplificationTarget left, MeshSimplificationTarget right) 46 | { 47 | return !(left == right); 48 | } 49 | } 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplificationTarget.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2213af585a55ab941b17992083993053 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplificationTargetKind.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Meshia.MeshSimplification 4 | { 5 | /// 6 | /// Represents what actually means. 7 | /// 8 | [Serializable] 9 | public enum MeshSimplificationTargetKind 10 | { 11 | /// 12 | /// The value is the target vertex count relative to the original mesh. 13 | /// 14 | RelativeVertexCount, 15 | /// 16 | /// The value is the target vertex count as an absolute number. 17 | /// 18 | AbsoluteVertexCount, 19 | /// 20 | /// The value is the max total error scaled by the original mesh's bounding box size and vertex count. 21 | /// 22 | ScaledTotalError, 23 | /// 24 | /// The value is the max total error as an absolute number. 25 | /// 26 | AbsoluteTotalError, 27 | /// 28 | /// The value is the target triangle count relative to the original mesh. 29 | /// 30 | RelativeTriangleCount, 31 | /// 32 | /// The value is the target triangle count as an absolute number. 33 | /// 34 | AbsoluteTriangleCount, 35 | } 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplificationTargetKind.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 263fdbc792081c14f992584361cb5d2a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cbfe4333622e3964d9effe3d95023d8a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplifierOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | namespace Meshia.MeshSimplification 4 | { 5 | [Serializable] 6 | public struct MeshSimplifierOptions : IEquatable 7 | { 8 | public static MeshSimplifierOptions Default => new() 9 | { 10 | PreserveBorderEdges = false, 11 | PreserveSurfaceCurvature = false, 12 | UseBarycentricCoordinateInterpolation = false, 13 | MinNormalDot = 0.2f, 14 | EnableSmartLink = true, 15 | VertexLinkDistance = 0.0001f, 16 | VertexLinkMinNormalDot = 0.95f, 17 | VertexLinkColorDistance = 0.01f, 18 | VertexLinkUvDistance = 0.001f, 19 | }; 20 | 21 | /// 22 | /// If you want to suppress hole generation during simplification, enable this option. 23 | /// 24 | [Tooltip("If you want to suppress hole generation during simplification, enable this option.")] 25 | public bool PreserveBorderEdges; 26 | public bool PreserveSurfaceCurvature; 27 | /// 28 | /// If you find that the texture is distorted, try toggling this option. 29 | /// 30 | [Tooltip("If you find that the texture is distorted, try toggling this option.")] 31 | public bool UseBarycentricCoordinateInterpolation; 32 | /// 33 | /// If this option is enabled, vertices that are not originally connected but are close to each other will be included in the first merge candidates.
34 | /// Increases the initialization cost. 35 | ///
36 | [Tooltip("If this option is enabled, vertices that are not originally connected but are close to each other will be included in the first merge candidates. \n" + 37 | "Increases the initialization cost.")] 38 | public bool EnableSmartLink; 39 | [Range(-1, 1)] 40 | public float MinNormalDot; 41 | /// 42 | /// When smart link is enabled, this is used to select candidates for merging vertices that are not originally connected to each other.
43 | /// Increasing this value also increases the initialization cost. 44 | ///
45 | [Tooltip("When smart link is enabled, this is used to select candidates for merging vertices that are not originally connected to each other. \n" + 46 | "Increasing this value also increases the initialization cost.")] 47 | public float VertexLinkDistance; 48 | [Range(-1, 1)] 49 | public float VertexLinkMinNormalDot; 50 | // This could be HDR color, so there is no Range. 51 | public float VertexLinkColorDistance; 52 | [Range(0, 1.41421356237f)] 53 | public float VertexLinkUvDistance; 54 | 55 | 56 | 57 | public readonly override bool Equals(object obj) 58 | { 59 | return obj is MeshSimplifierOptions options && Equals(options); 60 | } 61 | 62 | public readonly bool Equals(MeshSimplifierOptions other) 63 | { 64 | return PreserveBorderEdges == other.PreserveBorderEdges && 65 | PreserveSurfaceCurvature == other.PreserveSurfaceCurvature && 66 | UseBarycentricCoordinateInterpolation == other.UseBarycentricCoordinateInterpolation && 67 | EnableSmartLink == other.EnableSmartLink && 68 | MinNormalDot == other.MinNormalDot && 69 | VertexLinkDistance == other.VertexLinkDistance && 70 | VertexLinkMinNormalDot == other.VertexLinkMinNormalDot && 71 | VertexLinkColorDistance == other.VertexLinkColorDistance && 72 | VertexLinkUvDistance == other.VertexLinkUvDistance; 73 | } 74 | 75 | public readonly override int GetHashCode() 76 | { 77 | return HashCode.Combine(PreserveBorderEdges, PreserveSurfaceCurvature, MinNormalDot); 78 | } 79 | 80 | public static bool operator ==(MeshSimplifierOptions left, MeshSimplifierOptions right) 81 | { 82 | return left.Equals(right); 83 | } 84 | 85 | public static bool operator !=(MeshSimplifierOptions left, MeshSimplifierOptions right) 86 | { 87 | return !(left == right); 88 | } 89 | } 90 | } 91 | 92 | 93 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/MeshSimplifierOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88fc94f0047565745a51e8de6a1ebd87 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Meshia.MeshSimplification.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Meshia.MeshSimplification.Runtime", 3 | "rootNamespace": "Meshia.MeshSimplification", 4 | "references": [ 5 | "Unity.Burst", 6 | "Unity.Mathematics", 7 | "Unity.Collections" 8 | ], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": true, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Meshia.MeshSimplification.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2badc7067c4f2f74ebf5e33b79399358 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/NativeMinPriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fe0cdf05ee730945b86eea9ee5c2c26 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5b17ff445ee2bd4ea89880c2f041754 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Tests/MeshSimplifierTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Meshia.MeshSimplification; 5 | using NUnit.Framework; 6 | using Unity.Collections; 7 | using Unity.Jobs; 8 | using UnityEngine; 9 | using UnityEngine.TestTools; 10 | 11 | namespace Meshia.MeshSimplification.Tests 12 | { 13 | public class MeshSimplifierTests 14 | { 15 | static Mesh GetPrimitiveMesh(PrimitiveType type) 16 | { 17 | var gameObject = GameObject.CreatePrimitive(type); 18 | var mesh = gameObject.GetComponent().sharedMesh; 19 | Object.Destroy(gameObject); 20 | return mesh; 21 | } 22 | [TestCase(PrimitiveType.Sphere)] 23 | [TestCase(PrimitiveType.Capsule)] 24 | [TestCase(PrimitiveType.Cylinder)] 25 | public async Task ShouldSimplifyPrimitive(PrimitiveType type) 26 | { 27 | var mesh = GetPrimitiveMesh(type); 28 | 29 | MeshSimplificationTarget target = new() 30 | { 31 | Kind = MeshSimplificationTargetKind.RelativeVertexCount, 32 | Value = 0.5f, 33 | }; 34 | Mesh simplifiedMesh = new(); 35 | await MeshSimplifier.SimplifyAsync(mesh, target, MeshSimplifierOptions.Default, simplifiedMesh); 36 | Assert.LessOrEqual(simplifiedMesh.vertexCount, mesh.vertexCount * 0.5f); 37 | Object.Destroy(simplifiedMesh); 38 | } 39 | [TestCase(PrimitiveType.Sphere)] 40 | [TestCase(PrimitiveType.Capsule)] 41 | [TestCase(PrimitiveType.Cylinder)] 42 | public async Task ShouldSimplifyPrimitiveIncrementally(PrimitiveType type) 43 | { 44 | var allocator = Allocator.Persistent; 45 | var mesh = GetPrimitiveMesh(type); 46 | using var blendShapes = BlendShapeData.GetMeshBlendShapes(mesh, allocator); 47 | 48 | Assert.Zero(blendShapes.Length, "Primitive meshes should not have blend shapes by default."); 49 | var meshDataArray = Mesh.AcquireReadOnlyMeshData(mesh); 50 | var meshData = meshDataArray[0]; 51 | 52 | using MeshSimplifier meshSimplifier = new(allocator); 53 | 54 | var load = meshSimplifier.ScheduleLoadMeshData(meshData, MeshSimplifierOptions.Default); 55 | 56 | while (!load.IsCompleted) 57 | { 58 | await Task.Yield(); 59 | } 60 | 61 | load.Complete(); 62 | 63 | Mesh simplifiedMesh1 = await SimplifyToTarget(new() 64 | { 65 | Kind = MeshSimplificationTargetKind.RelativeVertexCount, 66 | Value = 0.5f, 67 | }); 68 | 69 | Assert.LessOrEqual(simplifiedMesh1.vertexCount, mesh.vertexCount * 0.5f); 70 | 71 | Object.Destroy(simplifiedMesh1); 72 | Mesh simplifiedMesh2 = await SimplifyToTarget(new() 73 | { 74 | Kind = MeshSimplificationTargetKind.RelativeVertexCount, 75 | Value = 0.3f, 76 | }); 77 | 78 | Assert.LessOrEqual(simplifiedMesh2.vertexCount, mesh.vertexCount * 0.3f); 79 | Object.Destroy(simplifiedMesh2); 80 | 81 | async Task SimplifyToTarget(MeshSimplificationTarget target) 82 | { 83 | var destinationMeshDataArray = Mesh.AllocateWritableMeshData(1); 84 | var destinationMeshData = destinationMeshDataArray[0]; 85 | 86 | Mesh simplifiedMesh = new(); 87 | var simplify = meshSimplifier.ScheduleSimplify(meshData, blendShapes, target, new JobHandle()); 88 | 89 | using NativeList destinationBlendShapes = new(allocator); 90 | var write = meshSimplifier.ScheduleWriteMeshData(meshData, blendShapes, destinationMeshData, destinationBlendShapes, simplify); 91 | 92 | while (!write.IsCompleted) 93 | { 94 | await Task.Yield(); 95 | } 96 | 97 | write.Complete(); 98 | 99 | Assert.Zero(destinationBlendShapes.Length, "Primitive meshes should not have blend shapes after simplification."); 100 | 101 | Mesh.ApplyAndDisposeWritableMeshData(destinationMeshDataArray, simplifiedMesh); 102 | return simplifiedMesh; 103 | } 104 | } 105 | [TestCase(PrimitiveType.Sphere)] 106 | [TestCase(PrimitiveType.Capsule)] 107 | [TestCase(PrimitiveType.Cylinder)] 108 | public async Task ShouldSimplifyPrimitiveWithDuplicatedSubMeshes(PrimitiveType type) 109 | { 110 | var mesh = Object.Instantiate(GetPrimitiveMesh(type)); 111 | var originalSubMeshCount = mesh.subMeshCount; 112 | mesh.subMeshCount += 1; 113 | mesh.SetTriangles(mesh.GetTriangles(originalSubMeshCount - 1), originalSubMeshCount); 114 | 115 | MeshSimplificationTarget target = new() 116 | { 117 | Kind = MeshSimplificationTargetKind.RelativeVertexCount, 118 | Value = 0.5f, 119 | }; 120 | Mesh simplifiedMesh = new(); 121 | await MeshSimplifier.SimplifyAsync(mesh, target, MeshSimplifierOptions.Default, simplifiedMesh); 122 | Assert.LessOrEqual(simplifiedMesh.vertexCount, mesh.vertexCount * 0.5f); 123 | Object.Destroy(mesh); 124 | Object.Destroy(simplifiedMesh); 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Tests/MeshSimplifierTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75e7244afb02f4445b70e948f3c885fd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Tests/Meshia.MeshSimplification.Runtime.Tests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Meshia.MeshSimplification.Runtime.Tests", 3 | "rootNamespace": "Meshia.MeshSimplification.Tests", 4 | "references": [ 5 | "UnityEngine.TestRunner", 6 | "UnityEditor.TestRunner", 7 | "Meshia.MeshSimplification.Runtime", 8 | "Unity.Collections" 9 | ], 10 | "includePlatforms": [], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": true, 14 | "precompiledReferences": [ 15 | "nunit.framework.dll" 16 | ], 17 | "autoReferenced": false, 18 | "defineConstraints": [ 19 | "UNITY_INCLUDE_TESTS" 20 | ], 21 | "versionDefines": [], 22 | "noEngineReferences": false 23 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/Tests/Meshia.MeshSimplification.Runtime.Tests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 246bf0d708e22f141966ce8fa7aa7c34 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/UnityCollectionsHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Burst.CompilerServices; 3 | using Unity.Collections; 4 | using Unity.Collections.LowLevel.Unsafe; 5 | namespace Meshia.MeshSimplification 6 | { 7 | internal static class UnityCollectionsHelpers 8 | { 9 | public static unsafe ref T ElementAt(this NativeArray array, int i) 10 | where T : unmanaged 11 | { 12 | if (Hint.Likely((uint)i < (uint)array.Length)) 13 | { 14 | 15 | return ref ((T*)array.GetUnsafePtr())[i]; 16 | } 17 | else 18 | { 19 | throw new IndexOutOfRangeException(); 20 | } 21 | } 22 | 23 | public static unsafe Span AsSpan(this UnsafeList list) 24 | where T : unmanaged 25 | { 26 | return new Span(list.Ptr, list.Length); 27 | } 28 | 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/UnityCollectionsHelpers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df3ae641bdebebe42a61a14e5951516b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/UnsafeKdTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Unity.Burst.CompilerServices; 4 | using Unity.Collections; 5 | using Unity.Collections.LowLevel.Unsafe; 6 | using Unity.Jobs; 7 | using Unity.Mathematics; 8 | 9 | namespace Meshia.MeshSimplification 10 | { 11 | struct UnsafeKdTree : INativeDisposable 12 | { 13 | struct Node 14 | { 15 | public int PointIndex; 16 | public int Component; 17 | public int2 ChildNodeIndices; 18 | } 19 | UnsafeList Nodes; 20 | public UnsafeKdTree(AllocatorManager.AllocatorHandle allocator) 21 | { 22 | Nodes = new(0, allocator); 23 | } 24 | public void Initialize(ReadOnlySpan points) 25 | { 26 | Nodes.Clear(); 27 | 28 | if (Nodes.Capacity < points.Length) 29 | { 30 | Nodes.Capacity = points.Length; 31 | } 32 | 33 | UnsafeList indices = new(points.Length, Allocator.Temp); 34 | indices.Resize(points.Length); 35 | for (int i = 0; i < indices.Length; i++) 36 | { 37 | indices[i] = i; 38 | } 39 | 40 | var rootNodeIndex = AllocateNode(); 41 | InitializeNode(points, rootNodeIndex, indices, 0); 42 | indices.Dispose(); 43 | } 44 | unsafe static void Split(UnsafeList list, int mid, out UnsafeList first, out UnsafeList second) 45 | where T : unmanaged 46 | { 47 | if (mid == 0) 48 | { 49 | first = new(null, 0); 50 | second = new(null, 0); 51 | 52 | } 53 | else 54 | { 55 | first = new(list.Ptr, mid - 1); 56 | 57 | second = new(list.Ptr + mid + 1, list.Length - mid - 1); 58 | } 59 | } 60 | [return: AssumeRange(0, int.MaxValue - 1)] 61 | int AllocateNode() => Nodes.Length++; 62 | void InitializeNode(ReadOnlySpan points, int nodeIndex, UnsafeList indices, int nodeDepth) 63 | { 64 | if (nodeIndex == -1) 65 | { 66 | return; 67 | } 68 | var component = nodeDepth % 3; 69 | 70 | var mid = indices.Length >> 1; 71 | unsafe 72 | { 73 | fixed (float3* pointsPtr = points) 74 | { 75 | indices.Sort(new PointsIndexComparer 76 | { 77 | List = new(pointsPtr, points.Length), 78 | Component = component, 79 | }); 80 | } 81 | } 82 | 83 | 84 | Split(indices, mid, out var first, out var second); 85 | 86 | var firstChildNodeIndex = first.IsEmpty ? -1 : AllocateNode(); 87 | 88 | var secondChiildNodeIndex = second.IsEmpty ? -1 : AllocateNode(); 89 | Nodes[nodeIndex] = new() 90 | { 91 | PointIndex = indices[mid], 92 | Component = component, 93 | ChildNodeIndices = new(firstChildNodeIndex, secondChiildNodeIndex), 94 | }; 95 | 96 | InitializeNode(points, firstChildNodeIndex, first, nodeDepth + 1); 97 | InitializeNode(points, secondChiildNodeIndex, second, nodeDepth + 1); 98 | 99 | 100 | 101 | } 102 | 103 | public void QueryPointsInSphere(ReadOnlySpan points, float3 center, float radius, ref UnsafeList results) 104 | { 105 | QueryPointsInSphere(points, 0, center, radius, ref results); 106 | } 107 | void QueryPointsInSphere(ReadOnlySpan points, int nodeIndex, float3 center, float radius, ref UnsafeList results) 108 | { 109 | if (nodeIndex == -1) 110 | { 111 | return; 112 | } 113 | var node = Nodes[nodeIndex]; 114 | var nodePoint = points[node.PointIndex]; 115 | var squaredDistance = math.distancesq(center, nodePoint); 116 | 117 | if (squaredDistance < radius * radius) 118 | { 119 | results.Add(node.PointIndex); 120 | } 121 | 122 | var component = node.Component; 123 | var componentDifference = center[component] - nodePoint[component]; 124 | var searchDirection = math.select(new int2(0, 1), new int2(1, 0), componentDifference > 0); 125 | QueryPointsInSphere(points, node.ChildNodeIndices[searchDirection.x], center, radius, ref results); 126 | if (math.abs(componentDifference) < radius) 127 | { 128 | QueryPointsInSphere(points, node.ChildNodeIndices[searchDirection.y], center, radius, ref results); 129 | } 130 | } 131 | 132 | public JobHandle Dispose(JobHandle inputDeps) 133 | { 134 | return Nodes.Dispose(inputDeps); 135 | } 136 | 137 | public void Dispose() 138 | { 139 | Nodes.Dispose(); 140 | } 141 | struct PointsIndexComparer : IComparer 142 | 143 | { 144 | public UnsafeList List; 145 | 146 | public int Component; 147 | 148 | public int Compare(int x, int y) => List[x][Component].CompareTo(List[y][Component]); 149 | } 150 | } 151 | 152 | 153 | 154 | } 155 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/UnsafeKdTree.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1ca1022905ab0a439bbe83fa74297f8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/UnsafeMinPriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e996c7507fc79fe44a1bd2106d796247 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/VertexMerge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Mathematics; 3 | namespace Meshia.MeshSimplification 4 | { 5 | struct VertexMerge : IComparable 6 | { 7 | public int VertexAIndex, VertexBIndex; 8 | public int VertexAVersion, VertexBVersion; 9 | public float3 Position; 10 | public float Cost; 11 | 12 | public int CompareTo(VertexMerge other) 13 | { 14 | return Cost.CompareTo(other.Cost); 15 | } 16 | } 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/Runtime/VertexMerge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8288c7f18be0fa24c833155c44e4ce08 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6127e339900773e49826f55b30de6000 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat/Worlds.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15f0256ffad83d749959067cfe0a8e99 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat/Worlds/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d90c6eae3ab7714da54708e3a5290b5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat/Worlds/Editor/BuildWorldMeshSimplificationHook.cs: -------------------------------------------------------------------------------- 1 | using Meshia.MeshSimplification; 2 | using Meshia.MeshSimplification.Ndmf; 3 | using System; 4 | using System.Collections.Generic; 5 | using UnityEditor; 6 | using UnityEngine; 7 | using VRC.SDKBase.Editor; 8 | using VRC.SDK3.Editor; 9 | 10 | public class BuildWorldMeshSimplificationHook 11 | { 12 | [InitializeOnLoadMethod] 13 | public static void RegisterSdkCallback() 14 | { 15 | VRCSdkControlPanel.OnSdkPanelEnable += OnSdkPanelEnable; 16 | } 17 | 18 | private static void OnSdkPanelEnable(object sender, EventArgs e) 19 | { 20 | if(VRCSdkControlPanel.TryGetBuilder(out var builder)) 21 | { 22 | builder.OnSdkBuildStateChange += OnSdkBuildStateChange; 23 | } 24 | } 25 | static Dictionary SimplifiedMeshToOriginalMesh { get; } = new(); 26 | private static void OnSdkBuildStateChange(object sender, SdkBuildState e) 27 | { 28 | switch (e) 29 | { 30 | case SdkBuildState.Building: 31 | { 32 | try 33 | { 34 | BackupOriginalMeshesAndSetSimplifiedMeshes(); 35 | } 36 | catch (Exception) 37 | { 38 | RestoreOriginalMeshes(); 39 | throw; 40 | } 41 | } 42 | break; 43 | case SdkBuildState.Success: 44 | case SdkBuildState.Failure: 45 | { 46 | RestoreOriginalMeshes(); 47 | } 48 | break; 49 | } 50 | } 51 | 52 | private static void RestoreOriginalMeshes() 53 | { 54 | foreach (var ndmfMeshSimplifier in VRC.Tools.FindSceneObjectsOfTypeAll()) 55 | { 56 | if (ndmfMeshSimplifier.TryGetComponent(out var meshFilter) && meshFilter.sharedMesh != null) 57 | { 58 | meshFilter.sharedMesh = SimplifiedMeshToOriginalMesh[meshFilter.sharedMesh.name]; 59 | } 60 | else if (ndmfMeshSimplifier.TryGetComponent(out var skinnedMeshRenderer) && skinnedMeshRenderer.sharedMesh != null) 61 | { 62 | skinnedMeshRenderer.sharedMesh = SimplifiedMeshToOriginalMesh[skinnedMeshRenderer.sharedMesh.name]; 63 | } 64 | } 65 | SimplifiedMeshToOriginalMesh.Clear(); 66 | } 67 | 68 | private static void BackupOriginalMeshesAndSetSimplifiedMeshes() 69 | { 70 | foreach (var ndmfMeshSimplifier in VRC.Tools.FindSceneObjectsOfTypeAll()) 71 | { 72 | if (ndmfMeshSimplifier.TryGetComponent(out var meshFilter) && meshFilter.sharedMesh != null) 73 | { 74 | var originalMesh = meshFilter.sharedMesh; 75 | Mesh simplifiedMesh = new(); 76 | 77 | 78 | MeshSimplifier.Simplify(originalMesh, ndmfMeshSimplifier.target, ndmfMeshSimplifier.options, simplifiedMesh); 79 | 80 | var key = Guid.NewGuid().ToString(); 81 | 82 | simplifiedMesh.name = key; 83 | SimplifiedMeshToOriginalMesh.Add(key, originalMesh); 84 | meshFilter.sharedMesh = simplifiedMesh; 85 | } 86 | else if (ndmfMeshSimplifier.TryGetComponent(out var skinnedMeshRenderer) && skinnedMeshRenderer.sharedMesh != null) 87 | { 88 | var originalMesh = skinnedMeshRenderer.sharedMesh; 89 | Mesh simplifiedMesh = new(); 90 | 91 | 92 | MeshSimplifier.Simplify(originalMesh, ndmfMeshSimplifier.target, ndmfMeshSimplifier.options, simplifiedMesh); 93 | 94 | 95 | var key = Guid.NewGuid().ToString(); 96 | 97 | simplifiedMesh.name = key; 98 | 99 | SimplifiedMeshToOriginalMesh.Add(key, originalMesh); 100 | skinnedMeshRenderer.sharedMesh = simplifiedMesh; 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat/Worlds/Editor/BuildWorldMeshSimplificationHook.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e39dc3c1ec607444815036b1ea07c5a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat/Worlds/Editor/Meshia.MeshSimplification.VRChat.Worlds.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Meshia.MeshSimplification.VRChat.Worlds.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:1b3abf7e59395d84c84b48d69677daaa", 6 | "GUID:6e9c6119ac4eb334284fb7b4bc6d1f05", 7 | "GUID:0b7227f38ccc85a47b25d2736821d761", 8 | "GUID:2badc7067c4f2f74ebf5e33b79399358" 9 | ], 10 | "includePlatforms": [ 11 | "Editor" 12 | ], 13 | "excludePlatforms": [], 14 | "allowUnsafeCode": false, 15 | "overrideReferences": true, 16 | "precompiledReferences": [ 17 | "VRCCore-Editor.dll" 18 | ], 19 | "autoReferenced": false, 20 | "defineConstraints": [ 21 | "ENABLE_VRCHAT_WORLDS" 22 | ], 23 | "versionDefines": [ 24 | { 25 | "name": "com.vrchat.worlds", 26 | "expression": "", 27 | "define": "ENABLE_VRCHAT_WORLDS" 28 | } 29 | ], 30 | "noEngineReferences": false 31 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/VRChat/Worlds/Editor/Meshia.MeshSimplification.VRChat.Worlds.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0a9017e46b5c0f43951c700f2b5d839 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.ramtype0.meshia.mesh-simplification", 3 | "displayName": "Meshia Mesh Simplification", 4 | "version": "3.0.0-pre.1", 5 | "unity": "2022.3", 6 | "description": "Burst accelerated mesh simplification", 7 | "vrchatVersion": "2022.1.1", 8 | "author": { 9 | "name": "Ram.Type-0", 10 | "url": "https://github.com/RamType0" 11 | }, 12 | "dependencies": { 13 | "com.unity.burst": "1.8.21", 14 | "com.unity.collections": "2.5.7", 15 | "com.unity.mathematics": "1.3.2" 16 | } 17 | } -------------------------------------------------------------------------------- /Packages/com.ramtype0.meshia.mesh-simplification/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bee4a228e8ba6c4f8583f9d4e5ce041 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ee5eebf1b35bbd49ae7983db316180a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/Editor/Bootstrap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text.RegularExpressions; 5 | using System.Threading.Tasks; 6 | using UnityEditor; 7 | using UnityEngine; 8 | 9 | namespace VRC.PackageManagement.Core 10 | { 11 | public class Bootstrap 12 | { 13 | // JSON property names in Project Manifest 14 | public const string UNITY_PACKAGES_FOLDER = "Packages"; 15 | public const string UNITY_MANIFEST_FILENAME = "manifest.json"; 16 | 17 | // VRC Values 18 | public const string VRC_CONFIG = "https://api.vrchat.cloud/api/1/config"; 19 | public const string VRC_AGENT = "VCCBootstrap 1.0"; 20 | public const string VRC_RESOLVER_PACKAGE = "com.vrchat.core.vpm-resolver"; 21 | 22 | // Finds url for bootstrap package without using JSON 23 | private static Regex _bootstrapRegex = new Regex("\"bootstrap\"\\s*:\\s*\"(.+?(?=\"))\""); 24 | public static string ManifestPath => Path.Combine(Directory.GetCurrentDirectory(), UNITY_PACKAGES_FOLDER, UNITY_MANIFEST_FILENAME); 25 | 26 | // Path where we expect the target package to exist 27 | public static string ResolverPath => 28 | Path.Combine(Directory.GetCurrentDirectory(), UNITY_PACKAGES_FOLDER, VRC_RESOLVER_PACKAGE); 29 | 30 | [InitializeOnLoadMethod] 31 | public static async void CheckForRestore() 32 | { 33 | if (!new DirectoryInfo(ResolverPath).Exists) 34 | { 35 | try 36 | { 37 | await AddResolver(); 38 | } 39 | catch (Exception e) 40 | { 41 | Debug.LogError($"Could not download and install the VPM Package Resolver - you may be missing packages. Exception: {e.Message}"); 42 | } 43 | } 44 | } 45 | 46 | public static async Task AddResolver() 47 | { 48 | var configData = await GetRemoteString(VRC_CONFIG); 49 | if (string.IsNullOrWhiteSpace(configData)) 50 | { 51 | Debug.LogWarning($"Could not get VPM libraries, try again later"); 52 | return; 53 | } 54 | var bootstrapMatch = _bootstrapRegex.Match(configData); 55 | if (!bootstrapMatch.Success || bootstrapMatch.Groups.Count < 2) 56 | { 57 | Debug.LogError($"Could not find bootstrap in config, try again later"); 58 | return; 59 | } 60 | 61 | var url = bootstrapMatch.Groups[1].Value; 62 | 63 | var targetFile = Path.Combine(Path.GetTempPath(), $"resolver-{DateTime.Now.ToString("yyyyMMddTHHmmss")}.unitypackage"); 64 | 65 | // Download to dir 66 | using (var client = new WebClient()) 67 | { 68 | // Add User Agent or else CloudFlare will return 1020 69 | client.Headers.Add(HttpRequestHeader.UserAgent, VRC_AGENT); 70 | 71 | await client.DownloadFileTaskAsync(url, targetFile); 72 | 73 | if (File.Exists(targetFile)) 74 | { 75 | Debug.Log($"Downloaded Resolver to {targetFile}"); 76 | AssetDatabase.ImportPackage(targetFile, false); 77 | } 78 | } 79 | return; 80 | } 81 | 82 | public static async Task GetRemoteString(string url) 83 | { 84 | using (var client = new WebClient()) 85 | { 86 | // Add User Agent or else CloudFlare will return 1020 87 | client.Headers.Add(HttpRequestHeader.UserAgent, VRC_AGENT); 88 | return await client.DownloadStringTaskAsync(url); 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/Editor/Bootstrap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eea11c44cabdaaa43ac0a21dbbbd9824 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/Editor/VRChat.Bootstrapper.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "VRChat.Bootstrapper.Editor", 3 | "references": [], 4 | "includePlatforms": [ 5 | "Editor" 6 | ], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/Editor/VRChat.Bootstrapper.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0d8a3ed977bd0948b99f4bce8e56a07 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/License.md: -------------------------------------------------------------------------------- 1 | # VRCHAT INC. 2 | ### VRCHAT DISTRO LICENSE FILE 3 | Version: February 24, 2022 4 | 5 | **SUMMARY OF TERMS:** Any materials subject to this Distro Asset License may be distributed by you, with or without modifications, on a non-commercial basis (i.e., at no charge), in accordance with the full terms of the Materials License Agreement. 6 | 7 | This Distro License File is a "License File" as defined in the VRChat Materials License Agreement, found at https://hello.vrchat.com/legal/sdk (or any successor link designated by VRChat) (as may be revised from time to time, the "Materials License Agreement"). 8 | 9 | This Distro License File applies to all the files in the Folder containing this Distro License File and those in all Child Folders within that Folder (except with respect to files in any Child Folder that contains a different License File) (such files, other than this Distro License File, the "Covered Files"). All capitalized terms used but not otherwise defined in this Distro License File have the meanings provided in the Materials License Agreement. 10 | 11 | This Distro License File only provides a summary of the terms applicable to the Covered Files. To understand your rights and obligations and the full set of terms that apply to use of the Covered Files, please see the relevant sections of the Materials License Agreement, including terms applicable to Distro Materials. -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/License.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a84f4a071b4a7fa49985f447a0ce2fe2 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "com.vrchat.core.bootstrap", 3 | "displayName" : "VRChat Package Bootstrapper", 4 | "version" : "0.1.15", 5 | "unity" : "2019.4", 6 | "description" : "Tool to Download VPM Packages", 7 | "vrchatVersion" : "2022.1.1", 8 | "author" : { 9 | "name" : "VRChat", 10 | "email" : "developer@vrchat.com", 11 | "url" : "https://github.com/vrchat/packages" 12 | }, 13 | "url" : "", 14 | "dependencies" : { 15 | "com.unity.nuget.newtonsoft-json" : "2.0.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.bootstrap/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c5fffb4815ba9046ad0a2e878396439 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1058b5946fb23674cad310b1f4bd5b61 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4e8a9c940ed84943bb0433246ec42bb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/ICSharpCode.SharpZipLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/ICSharpCode.SharpZipLib.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/ICSharpCode.SharpZipLib.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec897c206a99abe41b093d5cc5ddc3fe 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 1 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/SemanticVersioning.License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Adam Reeve 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/SemanticVersioning.License.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1417544c34d9a4f4aacebf76247940a9 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/SemanticVersioning.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/SemanticVersioning.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/SemanticVersioning.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65d82c6541a90644390df2caa29c2209 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.License.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a7454bc513adb84d9ae85ed7e7268ba 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.File.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.File.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.File.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0c56563958a156145b708466db0e35cc 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.File.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca344e99cdd379947ab3e8e5b346428c 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.Unity3D.License.md: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2020 Kurai András 5 | Copyright (c) 2022-Present VRChat Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.Unity3D.License.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 598e678340a8c6e4e9a3debcdc6a9579 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.Unity3D.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.Unity3D.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.Sinks.Unity3D.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfc1421f162f0354d8a64d569417d9c9 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 1 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/Serilog.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 702a5a2579f8edf43b5e7bfb2f52e2c6 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/YamlDotNet.License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Antoine Aubry and contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/YamlDotNet.License.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3547422b181c5af49901e93c1122bbdd 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/YamlDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/YamlDotNet.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/YamlDotNet.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fd667e0ec0d1d84c9e17dad407f2272 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/vpm-core-lib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamType0/Meshia.MeshSimplification/1b308f0827c1c3fab2d9920a3ba18a90c4e239c1/Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/vpm-core-lib.dll -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Dependencies/vpm-core-lib.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 140aba2a5b760e94cb3ed9f39a52610a 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 1 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/PackageMaker.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5da3ddd939264fc40a113d615f3ca77a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/PackageMaker/PackageMakerWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d75fcaecb8b9e7f4bbe783e5f4c9838a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/PackageMaker/PackageMakerWindowData.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using VRC.PackageManagement.PackageMaker; 5 | 6 | public class PackageMakerWindowData : ScriptableObject 7 | { 8 | public static string defaultAssetPath = Path.Combine("Assets", "PackageMakerWindowData.asset"); 9 | public string targetAssetFolder; 10 | public string packageID; 11 | 12 | public string authorName; 13 | public string authorEmail; 14 | public string authorUrl; 15 | public PackageMakerWindow.VRCPackageEnum relatedPackage; 16 | 17 | public static PackageMakerWindowData GetOrCreate() 18 | { 19 | var existingData = AssetDatabase.AssetPathToGUID(defaultAssetPath); 20 | if (string.IsNullOrWhiteSpace(existingData)) 21 | { 22 | return Create(); 23 | } 24 | else 25 | { 26 | var saveData = AssetDatabase.LoadAssetAtPath(defaultAssetPath); 27 | if (saveData == null) 28 | { 29 | Debug.LogError($"Could not load saved data but the save file exists. Resetting."); 30 | return Create(); 31 | } 32 | return saveData; 33 | } 34 | } 35 | 36 | public static PackageMakerWindowData Create() 37 | { 38 | var saveData = CreateInstance(); 39 | AssetDatabase.CreateAsset(saveData, defaultAssetPath); 40 | AssetDatabase.SaveAssets(); 41 | return saveData; 42 | } 43 | 44 | public void Save() 45 | { 46 | AssetDatabase.SaveAssets(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/PackageMaker/PackageMakerWindowData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0adae93375f5d5840a30b6e47f324172 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resolver.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0aa72fa778aef5b4cb5fa177c19d3636 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Threading.Tasks; 7 | using Serilog; 8 | using Serilog.Sinks.Unity3D; 9 | using UnityEditor; 10 | using UnityEngine; 11 | using VRC.PackageManagement.Core; 12 | using VRC.PackageManagement.Core.Types; 13 | using VRC.PackageManagement.Core.Types.Packages; 14 | using Version = VRC.PackageManagement.Core.Types.VPMVersion.Version; 15 | 16 | namespace VRC.PackageManagement.Resolver 17 | { 18 | 19 | [InitializeOnLoad] 20 | public class Resolver 21 | { 22 | private const string _projectLoadedKey = "PROJECT_LOADED"; 23 | 24 | private static string _projectDir; 25 | public static string ProjectDir 26 | { 27 | get 28 | { 29 | if (_projectDir != null) 30 | { 31 | return _projectDir; 32 | } 33 | 34 | try 35 | { 36 | _projectDir = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent.Parent.Parent 37 | .FullName; 38 | return _projectDir; 39 | } 40 | catch (Exception) 41 | { 42 | return ""; 43 | } 44 | } 45 | } 46 | 47 | static Resolver() 48 | { 49 | SetupLogging(); 50 | if (!SessionState.GetBool(_projectLoadedKey, false)) 51 | { 52 | #pragma warning disable 4014 53 | CheckResolveNeeded(); 54 | #pragma warning restore 4014 55 | } 56 | } 57 | 58 | private static void SetupLogging() 59 | { 60 | VRCLibLogger.SetLoggerDirectly( 61 | new LoggerConfiguration() 62 | .MinimumLevel.Information() 63 | .WriteTo.Unity3D() 64 | .CreateLogger() 65 | ); 66 | } 67 | 68 | private static async Task CheckResolveNeeded() 69 | { 70 | SessionState.SetBool(_projectLoadedKey, true); 71 | 72 | //Wait for project to finish compiling 73 | while (EditorApplication.isCompiling || EditorApplication.isUpdating) 74 | { 75 | await Task.Delay(250); 76 | } 77 | 78 | try 79 | { 80 | 81 | if (string.IsNullOrWhiteSpace(ProjectDir)) 82 | { 83 | return; 84 | } 85 | 86 | if (VPMProjectManifest.ResolveIsNeeded(ProjectDir)) 87 | { 88 | Debug.Log($"Resolve needed."); 89 | var result = EditorUtility.DisplayDialog("VRChat Package Management", 90 | $"This project requires some VRChat Packages which are not in the project yet.\n\nPress OK to download and install them.", 91 | "OK", "Show Me What's Missing"); 92 | if (result) 93 | { 94 | ResolveStatic(ProjectDir); 95 | } 96 | else 97 | { 98 | ResolverWindow.ShowWindow(); 99 | } 100 | } 101 | } 102 | catch (Exception) 103 | { 104 | // Unity says we can't open windows from this function so it throws an exception but also works fine. 105 | } 106 | } 107 | 108 | public static bool VPMManifestExists() 109 | { 110 | return VPMProjectManifest.Exists(ProjectDir, out _); 111 | } 112 | 113 | public static void CreateManifest() 114 | { 115 | VPMProjectManifest.Load(ProjectDir); 116 | ResolverWindow.Refresh().ConfigureAwait(false); 117 | } 118 | 119 | public static void ResolveManifest() 120 | { 121 | ResolveStatic(ProjectDir); 122 | } 123 | 124 | public static void ResolveStatic(string dir) 125 | { 126 | // Todo: calculate and show actual progress 127 | EditorUtility.DisplayProgressBar($"Getting all VRChat Packages", "Downloading and Installing...", 0.5f); 128 | VPMProjectManifest.Resolve(ProjectDir); 129 | EditorUtility.ClearProgressBar(); 130 | ForceRefresh(); 131 | } 132 | 133 | public static List GetAllVersionsOf(string id) 134 | { 135 | var project = new UnityProject(ProjectDir); 136 | 137 | var versions = new List(); 138 | foreach (var provider in Repos.GetAll) 139 | { 140 | var packagesWithVersions = provider.GetAllWithVersions(); 141 | 142 | foreach (var packageVersionList in packagesWithVersions) 143 | { 144 | foreach (var package in packageVersionList.Value.VersionsDescending) 145 | { 146 | if (package.Id != id) 147 | continue; 148 | if (Version.TryParse(package.Version, out var result)) 149 | { 150 | if (!versions.Contains(package.Version)) 151 | versions.Add(package.Version); 152 | } 153 | } 154 | } 155 | } 156 | 157 | // Sort packages in project to the top 158 | var sorted = from entry in versions orderby project.VPMProvider.HasPackage(entry) descending select entry; 159 | 160 | return sorted.ToList(); 161 | } 162 | 163 | public static List GetAffectedPackageList(IVRCPackage package) 164 | { 165 | List list = new List(); 166 | 167 | var project = new UnityProject(ProjectDir); 168 | 169 | if (Repos.GetAllDependencies(package, out Dictionary dependencies, null)) 170 | { 171 | foreach (KeyValuePair item in dependencies) 172 | { 173 | project.VPMProvider.Refresh(); 174 | if (project.VPMProvider.GetPackage(item.Key, item.Value) == null) 175 | { 176 | IVRCPackage d = Repos.GetPackageWithVersionMatch(item.Key, item.Value); 177 | if (d != null) 178 | { 179 | list.Add(d.Id + " " + d.Version + "\n"); 180 | } 181 | } 182 | } 183 | 184 | return list; 185 | } 186 | 187 | return null; 188 | } 189 | 190 | public static void ForceRefresh () 191 | { 192 | UnityEditor.PackageManager.Client.Resolve(); 193 | AssetDatabase.Refresh(); 194 | } 195 | 196 | } 197 | } -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f872e3586f8b4f06bab3c9facd14f6e6 3 | timeCreated: 1659048476 -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/ResolverWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32d2636186ee0834fa1dc2287750dd32 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8700b619eebc09545b4aaf4f69a2bf79 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resources/PackageMakerWindowStyle.uss: -------------------------------------------------------------------------------- 1 | .unity-box { 2 | margin: 2px; 3 | padding: 10px; 4 | flex-shrink: 0; 5 | } 6 | 7 | .unity-box #description { 8 | margin: 10px 0 10px 0; 9 | white-space: normal; 10 | } 11 | 12 | #action-button { 13 | font-size: 20px; 14 | -unity-font-style: bold; 15 | padding: 10px; 16 | margin:10px; 17 | } -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resources/PackageMakerWindowStyle.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8dfe8fb3b6d0f3e4693553ecc1cb23dd 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resources/ResolverWindowStyle.uss: -------------------------------------------------------------------------------- 1 | .unity-box { 2 | margin: 2px; 3 | padding: 10px; 4 | border-width: 0; 5 | flex-shrink: 0; 6 | } 7 | 8 | 9 | #package-box { 10 | margin: 2px; 11 | border-width: 0; 12 | flex-direction:row; 13 | padding: 6px; 14 | justify-content: center; 15 | align-items: center; 16 | } 17 | 18 | #package-row { 19 | padding: 0; 20 | margin: 0; 21 | flex-direction: row; 22 | background-color: rgba(0,0,0,0); 23 | } 24 | 25 | #manifest-header { 26 | font-size: 20px; 27 | margin-bottom: 10px; 28 | } -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/Resources/ResolverWindowStyle.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 346f7a547766ecb4396d15f585a15133 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/com.vrchat.core.vpm-resolver.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.vrchat.core.vpm-resolver.Editor", 3 | "references": [], 4 | "includePlatforms": [ 5 | "Editor" 6 | ], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/Editor/com.vrchat.core.vpm-resolver.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1e8c2ba944807d4a9213e2de6930a0b 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/License.md: -------------------------------------------------------------------------------- 1 | # VRCHAT INC. 2 | ### VRCHAT DISTRO LICENSE FILE 3 | Version: February 24, 2022 4 | 5 | **SUMMARY OF TERMS:** Any materials subject to this Distro Asset License may be distributed by you, with or without modifications, on a non-commercial basis (i.e., at no charge), in accordance with the full terms of the Materials License Agreement. 6 | 7 | This Distro License File is a "License File" as defined in the VRChat Materials License Agreement, found at https://hello.vrchat.com/legal/sdk (or any successor link designated by VRChat) (as may be revised from time to time, the "Materials License Agreement"). 8 | 9 | This Distro License File applies to all the files in the Folder containing this Distro License File and those in all Child Folders within that Folder (except with respect to files in any Child Folder that contains a different License File) (such files, other than this Distro License File, the "Covered Files"). All capitalized terms used but not otherwise defined in this Distro License File have the meanings provided in the Materials License Agreement. 10 | 11 | This Distro License File only provides a summary of the terms applicable to the Covered Files. To understand your rights and obligations and the full set of terms that apply to use of the Covered Files, please see the relevant sections of the Materials License Agreement, including terms applicable to Distro Materials. -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/License.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7727f888edf4714448d5a0287deec6dd 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "com.vrchat.core.vpm-resolver", 3 | "displayName" : "VRChat Package Resolver Tool", 4 | "version" : "0.1.29", 5 | "unity" : "2022.3", 6 | "description" : "Tool to Download VPM Packages", 7 | "vrchatVersion" : "2022.3.3", 8 | "author" : { 9 | "name" : "VRChat", 10 | "email" : "developer@vrchat.com", 11 | "url" : "https://github.com/vrchat/packages" 12 | }, 13 | "url" : "", 14 | "dependencies" : { 15 | "com.unity.nuget.newtonsoft-json" : "3.0.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Packages/com.vrchat.core.vpm-resolver/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b02e2915ebf04e4ea94e503d73e7411 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.ai.navigation": "1.1.5", 4 | "com.unity.ide.rider": "3.0.28", 5 | "com.unity.ide.visualstudio": "2.0.22", 6 | "com.unity.ide.vscode": "1.2.5", 7 | "com.unity.test-framework": "1.1.33", 8 | "com.unity.textmeshpro": "3.0.6", 9 | "com.unity.timeline": "1.7.6", 10 | "com.unity.ugui": "1.0.0", 11 | "com.unity.modules.ai": "1.0.0", 12 | "com.unity.modules.androidjni": "1.0.0", 13 | "com.unity.modules.animation": "1.0.0", 14 | "com.unity.modules.assetbundle": "1.0.0", 15 | "com.unity.modules.audio": "1.0.0", 16 | "com.unity.modules.cloth": "1.0.0", 17 | "com.unity.modules.director": "1.0.0", 18 | "com.unity.modules.imageconversion": "1.0.0", 19 | "com.unity.modules.imgui": "1.0.0", 20 | "com.unity.modules.jsonserialize": "1.0.0", 21 | "com.unity.modules.particlesystem": "1.0.0", 22 | "com.unity.modules.physics": "1.0.0", 23 | "com.unity.modules.physics2d": "1.0.0", 24 | "com.unity.modules.screencapture": "1.0.0", 25 | "com.unity.modules.terrain": "1.0.0", 26 | "com.unity.modules.terrainphysics": "1.0.0", 27 | "com.unity.modules.tilemap": "1.0.0", 28 | "com.unity.modules.ui": "1.0.0", 29 | "com.unity.modules.uielements": "1.0.0", 30 | "com.unity.modules.umbra": "1.0.0", 31 | "com.unity.modules.unityanalytics": "1.0.0", 32 | "com.unity.modules.unitywebrequest": "1.0.0", 33 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 34 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 35 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 36 | "com.unity.modules.unitywebrequestwww": "1.0.0", 37 | "com.unity.modules.vehicles": "1.0.0", 38 | "com.unity.modules.video": "1.0.0", 39 | "com.unity.modules.vr": "1.0.0", 40 | "com.unity.modules.wind": "1.0.0", 41 | "com.unity.modules.xr": "1.0.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Packages/vpm-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.vrchat.core.vpm-resolver": { 4 | "version": "0.1.29" 5 | }, 6 | "com.vrchat.base": { 7 | "version": "3.8.0" 8 | }, 9 | "nadena.dev.ndmf": { 10 | "version": "1.7.9" 11 | } 12 | }, 13 | "locked": { 14 | "com.vrchat.core.vpm-resolver": { 15 | "version": "0.1.29", 16 | "dependencies": {} 17 | }, 18 | "com.vrchat.base": { 19 | "version": "3.8.0", 20 | "dependencies": {} 21 | }, 22 | "nadena.dev.ndmf": { 23 | "version": "1.7.9", 24 | "dependencies": {} 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Volume: 1 8 | Rolloff Scale: 1 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_SampleRate: 48000 12 | m_DSPBufferSize: 1024 13 | m_VirtualVoiceCount: 64 14 | m_RealVoiceCount: 32 15 | m_EnableOutputSuspension: 1 16 | m_SpatializerPlugin: 17 | m_AmbisonicDecoderPlugin: 18 | m_DisableAudio: 0 19 | m_VirtualizeEffects: 1 20 | m_RequestedDSPBufferSize: 0 21 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | m_DefaultMaxAngluarSpeed: 7 35 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: [] 8 | m_configObjects: 9 | com.unity.xr.management.loader_settings: {fileID: 11400000, guid: 020a8548008ca1d4187144c766fd3ccb, 10 | type: 2} 11 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 0 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 0 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 15 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_DepthNormals: 17 | m_Mode: 1 18 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 19 | m_MotionVectors: 20 | m_Mode: 1 21 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 22 | m_LightHalo: 23 | m_Mode: 1 24 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LensFlare: 26 | m_Mode: 1 27 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 28 | m_VideoShadersIncludeMode: 2 29 | m_AlwaysIncludedShaders: [] 30 | m_PreloadedShaders: [] 31 | m_PreloadShadersBatchTimeLimit: -1 32 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 33 | type: 0} 34 | m_CustomRenderPipeline: {fileID: 0} 35 | m_TransparencySortMode: 0 36 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 37 | m_DefaultRenderingPath: 1 38 | m_DefaultMobileRenderingPath: 1 39 | m_TierSettings: [] 40 | m_LightmapStripping: 0 41 | m_FogStripping: 0 42 | m_InstancingStripping: 0 43 | m_BrgStripping: 0 44 | m_LightmapKeepPlain: 1 45 | m_LightmapKeepDirCombined: 1 46 | m_LightmapKeepDynamicPlain: 1 47 | m_LightmapKeepDynamicDirCombined: 1 48 | m_LightmapKeepShadowMask: 1 49 | m_LightmapKeepSubtractive: 1 50 | m_FogKeepLinear: 1 51 | m_FogKeepExp: 1 52 | m_FogKeepExp2: 1 53 | m_AlbedoSwatchInfos: [] 54 | m_LightsUseLinearIntensity: 1 55 | m_LightsUseColorTemperature: 1 56 | m_DefaultRenderingLayerMask: 1 57 | m_LogWhenShaderIsCompiled: 0 58 | m_SRPDefaultSettings: {} 59 | m_LightProbeOutsideHullStrategy: 0 60 | m_CameraRelativeLightCulling: 0 61 | m_CameraRelativeShadowCulling: 0 62 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/MemorySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!387306366 &1 4 | MemorySettings: 5 | m_ObjectHideFlags: 0 6 | m_EditorMemorySettings: 7 | m_MainAllocatorBlockSize: -1 8 | m_ThreadAllocatorBlockSize: -1 9 | m_MainGfxBlockSize: -1 10 | m_ThreadGfxBlockSize: -1 11 | m_CacheBlockSize: -1 12 | m_TypetreeBlockSize: -1 13 | m_ProfilerBlockSize: -1 14 | m_ProfilerEditorBlockSize: -1 15 | m_BucketAllocatorGranularity: -1 16 | m_BucketAllocatorBucketsCount: -1 17 | m_BucketAllocatorBlockSize: -1 18 | m_BucketAllocatorBlockCount: -1 19 | m_ProfilerBucketAllocatorGranularity: -1 20 | m_ProfilerBucketAllocatorBucketsCount: -1 21 | m_ProfilerBucketAllocatorBlockSize: -1 22 | m_ProfilerBucketAllocatorBlockCount: -1 23 | m_TempAllocatorSizeMain: -1 24 | m_JobTempAllocatorBlockSize: -1 25 | m_BackgroundJobTempAllocatorBlockSize: -1 26 | m_JobTempAllocatorReducedBlockSize: -1 27 | m_TempAllocatorSizeGIBakingWorker: -1 28 | m_TempAllocatorSizeNavMeshWorker: -1 29 | m_TempAllocatorSizeAudioWorker: -1 30 | m_TempAllocatorSizeCloudWorker: -1 31 | m_TempAllocatorSizeGfx: -1 32 | m_TempAllocatorSizeJobWorker: -1 33 | m_TempAllocatorSizeBackgroundWorker: -1 34 | m_TempAllocatorSizePreloadManager: -1 35 | m_PlatformMemorySettings: {} 36 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_ScopedRegistriesSettingsExpanded: 1 16 | oneTimeWarningShown: 0 17 | m_Registries: 18 | - m_Id: main 19 | m_Name: 20 | m_Url: https://packages.unity.com 21 | m_Scopes: [] 22 | m_IsDefault: 1 23 | m_UserSelectedRegistryName: 24 | m_UserAddingNewScopedRegistry: 0 25 | m_RegistryInfoDraft: 26 | m_ErrorMessage: 27 | m_Original: 28 | m_Id: 29 | m_Name: 30 | m_Url: 31 | m_Scopes: [] 32 | m_IsDefault: 0 33 | m_Modified: 0 34 | m_Name: 35 | m_Url: 36 | m_Scopes: 37 | - 38 | m_SelectedScopeIndex: 0 39 | -------------------------------------------------------------------------------- /ProjectSettings/Packages/com.vrchat.base/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "samplesImported": false, 3 | "allowVRCPackageChanges": false, 4 | "samplesHintCreated": false, 5 | "debugVCCConnection": false, 6 | "dpidMipmaps": false, 7 | "dpidConservative": true 8 | } -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2022.3.22f1 2 | m_EditorVersionWithRevision: 2022.3.22f1 (887be4894c44) 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 2 8 | m_QualitySettings: 9 | - serializedVersion: 3 10 | name: VRC Low 11 | pixelLightCount: 4 12 | shadows: 2 13 | shadowResolution: 1 14 | shadowProjection: 1 15 | shadowCascades: 2 16 | shadowDistance: 75 17 | shadowNearPlaneOffset: 2 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | skinWeights: 4 22 | globalTextureMipmapLimit: 0 23 | textureMipmapLimitSettings: [] 24 | anisotropicTextures: 2 25 | antiAliasing: 0 26 | softParticles: 1 27 | softVegetation: 1 28 | realtimeReflectionProbes: 1 29 | billboardsFaceCameraPosition: 1 30 | useLegacyDetailDistribution: 1 31 | vSyncCount: 0 32 | realtimeGICPUUsage: 25 33 | lodBias: 1 34 | maximumLODLevel: 0 35 | enableLODCrossFade: 1 36 | streamingMipmapsActive: 0 37 | streamingMipmapsAddAllCameras: 1 38 | streamingMipmapsMemoryBudget: 512 39 | streamingMipmapsRenderersPerFrame: 512 40 | streamingMipmapsMaxLevelReduction: 2 41 | streamingMipmapsMaxFileIORequests: 1024 42 | particleRaycastBudget: 1024 43 | asyncUploadTimeSlice: 2 44 | asyncUploadBufferSize: 64 45 | asyncUploadPersistentBuffer: 1 46 | resolutionScalingFixedDPIFactor: 1 47 | customRenderPipeline: {fileID: 0} 48 | terrainQualityOverrides: 0 49 | terrainPixelError: 1 50 | terrainDetailDensityScale: 1 51 | terrainBasemapDistance: 1000 52 | terrainDetailDistance: 80 53 | terrainTreeDistance: 5000 54 | terrainBillboardStart: 50 55 | terrainFadeLength: 5 56 | terrainMaxTrees: 50 57 | excludedTargetPlatforms: 58 | - Android 59 | - serializedVersion: 3 60 | name: VRC Medium 61 | pixelLightCount: 4 62 | shadows: 2 63 | shadowResolution: 2 64 | shadowProjection: 1 65 | shadowCascades: 2 66 | shadowDistance: 75 67 | shadowNearPlaneOffset: 2 68 | shadowCascade2Split: 0.33333334 69 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 70 | shadowmaskMode: 0 71 | skinWeights: 4 72 | globalTextureMipmapLimit: 0 73 | textureMipmapLimitSettings: [] 74 | anisotropicTextures: 2 75 | antiAliasing: 2 76 | softParticles: 1 77 | softVegetation: 1 78 | realtimeReflectionProbes: 1 79 | billboardsFaceCameraPosition: 1 80 | useLegacyDetailDistribution: 1 81 | vSyncCount: 0 82 | realtimeGICPUUsage: 25 83 | lodBias: 1.5 84 | maximumLODLevel: 0 85 | enableLODCrossFade: 1 86 | streamingMipmapsActive: 0 87 | streamingMipmapsAddAllCameras: 1 88 | streamingMipmapsMemoryBudget: 512 89 | streamingMipmapsRenderersPerFrame: 512 90 | streamingMipmapsMaxLevelReduction: 2 91 | streamingMipmapsMaxFileIORequests: 1024 92 | particleRaycastBudget: 2048 93 | asyncUploadTimeSlice: 2 94 | asyncUploadBufferSize: 64 95 | asyncUploadPersistentBuffer: 1 96 | resolutionScalingFixedDPIFactor: 1 97 | customRenderPipeline: {fileID: 0} 98 | terrainQualityOverrides: 0 99 | terrainPixelError: 1 100 | terrainDetailDensityScale: 1 101 | terrainBasemapDistance: 1000 102 | terrainDetailDistance: 80 103 | terrainTreeDistance: 5000 104 | terrainBillboardStart: 50 105 | terrainFadeLength: 5 106 | terrainMaxTrees: 50 107 | excludedTargetPlatforms: 108 | - Android 109 | - serializedVersion: 3 110 | name: VRC High 111 | pixelLightCount: 8 112 | shadows: 2 113 | shadowResolution: 3 114 | shadowProjection: 1 115 | shadowCascades: 4 116 | shadowDistance: 150 117 | shadowNearPlaneOffset: 2 118 | shadowCascade2Split: 0.33333334 119 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 120 | shadowmaskMode: 0 121 | skinWeights: 4 122 | globalTextureMipmapLimit: 0 123 | textureMipmapLimitSettings: [] 124 | anisotropicTextures: 2 125 | antiAliasing: 4 126 | softParticles: 1 127 | softVegetation: 1 128 | realtimeReflectionProbes: 1 129 | billboardsFaceCameraPosition: 1 130 | useLegacyDetailDistribution: 1 131 | vSyncCount: 0 132 | realtimeGICPUUsage: 25 133 | lodBias: 2 134 | maximumLODLevel: 0 135 | enableLODCrossFade: 1 136 | streamingMipmapsActive: 0 137 | streamingMipmapsAddAllCameras: 1 138 | streamingMipmapsMemoryBudget: 512 139 | streamingMipmapsRenderersPerFrame: 512 140 | streamingMipmapsMaxLevelReduction: 2 141 | streamingMipmapsMaxFileIORequests: 1024 142 | particleRaycastBudget: 4096 143 | asyncUploadTimeSlice: 2 144 | asyncUploadBufferSize: 128 145 | asyncUploadPersistentBuffer: 1 146 | resolutionScalingFixedDPIFactor: 1 147 | customRenderPipeline: {fileID: 0} 148 | terrainQualityOverrides: 0 149 | terrainPixelError: 1 150 | terrainDetailDensityScale: 1 151 | terrainBasemapDistance: 1000 152 | terrainDetailDistance: 80 153 | terrainTreeDistance: 5000 154 | terrainBillboardStart: 50 155 | terrainFadeLength: 5 156 | terrainMaxTrees: 50 157 | excludedTargetPlatforms: 158 | - Android 159 | - serializedVersion: 3 160 | name: VRC Mobile 161 | pixelLightCount: 4 162 | shadows: 0 163 | shadowResolution: 1 164 | shadowProjection: 1 165 | shadowCascades: 1 166 | shadowDistance: 50 167 | shadowNearPlaneOffset: 2 168 | shadowCascade2Split: 0.33333334 169 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 170 | shadowmaskMode: 0 171 | skinWeights: 4 172 | globalTextureMipmapLimit: 0 173 | textureMipmapLimitSettings: [] 174 | anisotropicTextures: 2 175 | antiAliasing: 2 176 | softParticles: 0 177 | softVegetation: 0 178 | realtimeReflectionProbes: 0 179 | billboardsFaceCameraPosition: 1 180 | useLegacyDetailDistribution: 1 181 | vSyncCount: 0 182 | realtimeGICPUUsage: 50 183 | lodBias: 2 184 | maximumLODLevel: 0 185 | enableLODCrossFade: 1 186 | streamingMipmapsActive: 0 187 | streamingMipmapsAddAllCameras: 1 188 | streamingMipmapsMemoryBudget: 512 189 | streamingMipmapsRenderersPerFrame: 512 190 | streamingMipmapsMaxLevelReduction: 2 191 | streamingMipmapsMaxFileIORequests: 1024 192 | particleRaycastBudget: 1024 193 | asyncUploadTimeSlice: 1 194 | asyncUploadBufferSize: 32 195 | asyncUploadPersistentBuffer: 1 196 | resolutionScalingFixedDPIFactor: 1 197 | customRenderPipeline: {fileID: 0} 198 | terrainQualityOverrides: 0 199 | terrainPixelError: 1 200 | terrainDetailDensityScale: 1 201 | terrainBasemapDistance: 1000 202 | terrainDetailDistance: 80 203 | terrainTreeDistance: 5000 204 | terrainBillboardStart: 50 205 | terrainFadeLength: 5 206 | terrainMaxTrees: 50 207 | excludedTargetPlatforms: 208 | - Standalone 209 | m_TextureMipmapLimitGroupNames: [] 210 | m_PerPlatformDefaultQuality: 211 | Android: 2 212 | Lumin: 5 213 | Nintendo 3DS: 5 214 | Nintendo Switch: 5 215 | PS4: 5 216 | PSP2: 2 217 | Stadia: 5 218 | Standalone: 5 219 | WebGL: 3 220 | Windows Store Apps: 5 221 | XboxOne: 5 222 | iPhone: 2 223 | tvOS: 2 224 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_RenderPipeSettingsPath: 11 | m_FixedTimeStep: 0.016666668 12 | m_MaxDeltaTime: 0.05 13 | -------------------------------------------------------------------------------- /ProjectSettings/VersionControlSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!890905787 &1 4 | VersionControlSettings: 5 | m_ObjectHideFlags: 0 6 | m_Mode: Visible Meta Files 7 | m_CollabEditorSettings: 8 | inProgressEnabled: 1 9 | -------------------------------------------------------------------------------- /ProjectSettings/XRPackageSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_Settings": [ 3 | "RemoveLegacyInputHelpersForReload" 4 | ] 5 | } -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Meshia Mesh Simplification 2 | 3 | 4 | - [English](#english) 5 | - [日本語](#日本語) 6 | 7 | [Documents](https://ramtype0.github.io/Meshia.MeshSimplification/) 8 | 9 | ## English 10 | Mesh simplification tool/library for Unity, VRChat. 11 | 12 | Based on Unity Job System, and Burst. 13 | Provides fast, asynchronous mesh simplification. 14 | 15 | Can be executed at runtime or in the editor. 16 | 17 | ### Installation 18 | 19 | ### VPM 20 | 21 | Add [my VPM repository](https://ramtype0.github.io/VpmRepository/) to VCC, then add Meshia Mesh Simplification package to your projects. 22 | 23 | 24 | ### How to use 25 | 26 | #### NDMF integration 27 | 28 | Attach `MeshiaMeshSimplifier` to your models. 29 | 30 | You can preview the result in EditMode. 31 | 32 | 33 | #### Call from C# 34 | 35 | ```csharp 36 | 37 | using Meshia.MeshSimplification; 38 | 39 | Mesh simplifiedMesh = new(); 40 | 41 | // Asynchronous API 42 | 43 | await MeshSimplifier.SimplifyAsync(originalMesh, target, options, simplifiedMesh); 44 | 45 | // Synchronous API 46 | 47 | MeshSimplifier.Simplify(originalMesh, target, options, simplifiedMesh); 48 | 49 | ``` 50 | 51 | ## 日本語 52 | 53 | Unity、VRChat向けのメッシュ軽量化ツールです。 54 | Unity Job Systemで動作するため、Burstと合わせて高速、かつ非同期で処理ができるのが特徴です。 55 | ランタイム、エディターの双方で動作します。 56 | 57 | ### インストール 58 | 59 | ### VPM 60 | 61 | [VPM repository](https://ramtype0.github.io/VpmRepository/)をVCCに追加してから、Manage Project > Manage PackagesからMeshia Mesh Simplificationをプロジェクトに追加してください。 62 | 63 | ### 使い方 64 | 65 | #### NDMF統合 66 | 67 | NDMFがプロジェクトにインポートされている場合、`MeshiaMeshSimplifier`が使えます。 68 | エディターで軽量化結果をプレビューしながらパラメーターの調整ができます。 69 | 70 | #### C#から呼び出す 71 | 72 | ```csharp 73 | 74 | using Meshia.MeshSimplification; 75 | 76 | Mesh simplifiedMesh = new(); 77 | 78 | // 非同期API 79 | 80 | await MeshSimplifier.SimplifyAsync(originalMesh, target, options, simplifiedMesh); 81 | 82 | // 同期API 83 | 84 | MeshSimplifier.Simplify(originalMesh, target, options, simplifiedMesh); 85 | 86 | ``` 87 | 88 | 89 | -------------------------------------------------------------------------------- /UserSettings/EditorUserSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!162 &1 4 | EditorUserSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_ConfigSettings: 8 | vcSharedLogLevel: 9 | value: 0d5e400f0650 10 | flags: 0 11 | m_VCAutomaticAdd: 1 12 | m_VCDebugCom: 0 13 | m_VCDebugCmd: 0 14 | m_VCDebugOut: 0 15 | m_SemanticMergeMode: 2 16 | m_DesiredImportWorkerCount: 4 17 | m_StandbyImportWorkerCount: 2 18 | m_IdleImportWorkerShutdownDelay: 60000 19 | m_VCShowFailedCheckout: 1 20 | m_VCOverwriteFailedCheckoutAssets: 1 21 | m_VCProjectOverlayIcons: 1 22 | m_VCHierarchyOverlayIcons: 1 23 | m_VCOtherOverlayIcons: 1 24 | m_VCAllowAsyncUpdate: 1 25 | m_ArtifactGarbageCollection: 1 26 | -------------------------------------------------------------------------------- /UserSettings/Search.settings: -------------------------------------------------------------------------------- 1 | {} --------------------------------------------------------------------------------