Repository: LGhassen/Scatterer Branch: master Commit: c2d0b0f2a879 Files: 3995 Total size: 21.3 MB Directory structure: gitextract_hn92p19d/ ├── .gitignore ├── Readme.md ├── license.md └── scatterer/ ├── CelestialBodySortableByDistance.cs ├── DataSerialization/ │ ├── ConfigPoint.cs │ ├── ConfigReader.cs │ ├── MainSettingsReadWrite.cs │ ├── PlanetshineSource.cs │ ├── PluginDataReadWrite.cs │ ├── QualityPresetsLoader.cs │ └── ScattererCelestialBody.cs ├── Effects/ │ ├── AntiAliasing/ │ │ ├── GenericAntiAliasing.cs │ │ ├── SubpixelMorphologicalAntialiasing.cs │ │ ├── TemporalAntiAliasing.cs │ │ └── Utils/ │ │ └── HaltonSeq.cs │ ├── PlanetShine/ │ │ ├── PlanetShineLight.cs │ │ └── PlanetshineManager.cs │ ├── Proland/ │ │ ├── Atmosphere/ │ │ │ ├── Godrays/ │ │ │ │ └── LegacyGodraysRenderer.cs │ │ │ ├── Preprocessing/ │ │ │ │ └── AtmoPreprocessor.cs │ │ │ ├── SkyNode.cs │ │ │ └── Utils/ │ │ │ ├── AtmospherePQS.cs │ │ │ ├── AtmosphereProjectorContainer.cs │ │ │ ├── AtmosphereUtils.cs │ │ │ ├── GenericLocalAtmosphereContainer.cs │ │ │ ├── ScaledScatteringContainer.cs │ │ │ ├── ScreenSpaceScatteringContainer.cs │ │ │ └── SkySphereContainer.cs │ │ ├── Ocean/ │ │ │ ├── Caustics/ │ │ │ │ ├── CausticsLightRaysRenderer.cs │ │ │ │ └── CausticsShadowMaskModulate.cs │ │ │ ├── FourierCPU.cs │ │ │ ├── FourierGPU.cs │ │ │ ├── GPUWaveInteractionHandler.cs │ │ │ ├── OceanCameraUpdateHook.cs │ │ │ ├── OceanFFTcpu.cs │ │ │ ├── OceanFFTgpu.cs │ │ │ ├── OceanNode.cs │ │ │ ├── OceanRenderingHook.cs │ │ │ ├── OceanWhiteCaps.cs │ │ │ ├── UnderwaterDimmingHook.cs │ │ │ └── Utils/ │ │ │ ├── CBUtility.cs │ │ │ ├── FakeOceanPQS.cs │ │ │ ├── OceanUtils.cs │ │ │ ├── RTUtility.cs │ │ │ └── WriteFloat.cs │ │ └── ProlandManager.cs │ ├── ScattererCelestialBodiesManager.cs │ ├── SunFlare/ │ │ ├── SunFlare.cs │ │ ├── SunflareCameraHook.cs │ │ ├── SunflareManager.cs │ │ ├── SunflareSettingsV1.cs │ │ └── SunflareSettingsV2.cs │ ├── SunlightModulator/ │ │ ├── SunlightModulator.cs │ │ ├── SunlightModulatorPostRenderHook.cs │ │ └── SunlightModulatorPreRenderHook.cs │ └── Tonemapping/ │ └── HableCurve.cs ├── GUI/ │ ├── AtmoGUI.cs │ ├── ConfigPointGUI.cs │ ├── GUIhandler.cs │ ├── MainOptionsGUI.cs │ ├── ModularGUI/ │ │ ├── AbstractGUIModule.cs │ │ ├── GUIModuleBool.cs │ │ ├── GUIModuleFloat.cs │ │ ├── GUIModuleInt.cs │ │ ├── GUIModuleLabel.cs │ │ ├── GUIModuleString.cs │ │ ├── GUIModuleVector2.cs │ │ ├── GUIModuleVector3.cs │ │ ├── GUIModuleVector4.cs │ │ └── ModularGUI.cs │ ├── OceanGUI.cs │ ├── SunflareGUI.cs │ └── ToolbarButton.cs ├── OldShaders/ │ ├── readme.md.txt │ └── scattererShaders/ │ ├── .vs/ │ │ └── scattererShaders/ │ │ ├── DesignTimeBuild/ │ │ │ └── .dtbcache │ │ ├── v14/ │ │ │ └── .suo │ │ └── v15/ │ │ ├── .suo │ │ └── Server/ │ │ └── sqlite3/ │ │ ├── storage.ide │ │ ├── storage.ide-shm │ │ └── storage.ide-wal │ ├── Assembly-CSharp-Editor.csproj │ ├── Assembly-CSharp-Editor.csproj.orig │ ├── Assembly-CSharp.csproj │ ├── Assembly-CSharp.csproj.orig │ ├── Assembly-UnityScript.unityproj │ ├── Assets/ │ │ ├── AssetBundles/ │ │ │ ├── AssetBundles │ │ │ └── AssetBundles.meta │ │ ├── AssetBundles.meta │ │ ├── Editor/ │ │ │ ├── ExportAssetBundle.cs │ │ │ ├── ExportAssetBundle.cs.meta │ │ │ ├── KSPCurveEditor.cs │ │ │ └── KSPCurveEditor.cs.meta │ │ ├── Editor.meta │ │ ├── Shaders/ │ │ │ ├── AA/ │ │ │ │ ├── AreaTex.tga │ │ │ │ ├── AreaTex.tga.meta │ │ │ │ ├── CustomTAA.shader │ │ │ │ ├── CustomTAA.shader.meta │ │ │ │ ├── SMAA.cginc │ │ │ │ ├── SMAA.cginc.meta │ │ │ │ ├── SMAA.shader │ │ │ │ ├── SMAA.shader.meta │ │ │ │ ├── SMAABridge.cginc │ │ │ │ ├── SMAABridge.cginc.meta │ │ │ │ ├── SearchTex.tga │ │ │ │ └── SearchTex.tga.meta │ │ │ ├── AA.meta │ │ │ ├── Atmo/ │ │ │ │ ├── CompositeDownscaledScattering.shader │ │ │ │ ├── CompositeDownscaledScattering.shader.meta │ │ │ │ ├── DepthBufferScattering.shader │ │ │ │ ├── DepthBufferScattering.shader.meta │ │ │ │ ├── Godrays/ │ │ │ │ │ ├── ComputeInverseShadowMatrices.compute │ │ │ │ │ ├── ComputeInverseShadowMatrices.compute.meta │ │ │ │ │ ├── GodraysCommon.cginc │ │ │ │ │ ├── GodraysCommon.cginc.meta │ │ │ │ │ ├── ShadowVolumeUtils.cginc │ │ │ │ │ ├── ShadowVolumeUtils.cginc.meta │ │ │ │ │ ├── VolumeDepth - Copy.shader.BAK │ │ │ │ │ ├── VolumeDepth - Copy.shader.BAK.meta │ │ │ │ │ ├── VolumeDepth.shader │ │ │ │ │ └── VolumeDepth.shader.meta │ │ │ │ ├── Godrays.meta │ │ │ │ ├── Preprocessing.meta │ │ │ │ ├── ProjectorScattering.shader │ │ │ │ ├── ProjectorScattering.shader.meta │ │ │ │ ├── ScaledPlanetScattering.shader │ │ │ │ ├── ScaledPlanetScattering.shader.meta │ │ │ │ ├── SkySphere.shader │ │ │ │ └── SkySphere.shader.meta │ │ │ ├── Atmo.meta │ │ │ ├── ClippingUtils.cginc │ │ │ ├── ClippingUtils.cginc.meta │ │ │ ├── CommonAtmosphere.cginc │ │ │ ├── CommonAtmosphere.cginc.meta │ │ │ ├── DecodeEncode/ │ │ │ │ ├── DecodedToFloat.shader │ │ │ │ ├── DecodedToFloat.shader.meta │ │ │ │ ├── WriteToFloat.shader │ │ │ │ └── WriteToFloat.shader.meta │ │ │ ├── DecodeEncode.meta │ │ │ ├── Depth/ │ │ │ │ ├── CopyCameraDepth.shader │ │ │ │ ├── CopyCameraDepth.shader.meta │ │ │ │ ├── DepthToDistance.shader │ │ │ │ ├── DepthToDistance.shader.meta │ │ │ │ ├── DownscaleDepth.shader │ │ │ │ └── DownscaleDepth.shader.meta │ │ │ ├── Depth.meta │ │ │ ├── DepthCommon.cginc │ │ │ ├── DepthCommon.cginc.meta │ │ │ ├── EVE/ │ │ │ │ ├── CloudVolumeParticle.shader │ │ │ │ ├── CloudVolumeParticle.shader.meta │ │ │ │ ├── EVEUtils.cginc │ │ │ │ ├── EVEUtils.cginc.meta │ │ │ │ ├── GeometryCloudVolumeParticle.shader │ │ │ │ ├── GeometryCloudVolumeParticle.shader.meta │ │ │ │ ├── GeometryCloudVolumeParticleToTexture.shader │ │ │ │ ├── GeometryCloudVolumeParticleToTexture.shader.meta │ │ │ │ ├── SphereCloud.shader │ │ │ │ ├── SphereCloud.shader.meta │ │ │ │ ├── SphereCloudShadowMap.shader │ │ │ │ ├── SphereCloudShadowMap.shader.meta │ │ │ │ ├── alphaMap.cginc │ │ │ │ ├── alphaMap.cginc.meta │ │ │ │ ├── cubeMap.cginc │ │ │ │ ├── cubeMap.cginc.meta │ │ │ │ ├── noiseSimplex.cginc │ │ │ │ └── noiseSimplex.cginc.meta │ │ │ ├── EVE.meta │ │ │ ├── EclipseCommon.cginc │ │ │ ├── EclipseCommon.cginc.meta │ │ │ ├── IntersectCommon.cginc │ │ │ ├── IntersectCommon.cginc.meta │ │ │ ├── Misc.meta │ │ │ ├── Ocean/ │ │ │ │ ├── Caustics/ │ │ │ │ │ ├── 0042-underwater-beach-sand-texture-seamless.jpg.meta │ │ │ │ │ ├── CausticsFinal.png.meta │ │ │ │ │ ├── CausticsGodrays.mat │ │ │ │ │ ├── CausticsGodrays.mat.meta │ │ │ │ │ ├── CausticsGodraysRaymarch.shader │ │ │ │ │ ├── CausticsGodraysRaymarch.shader.meta │ │ │ │ │ ├── CausticsOcclusion.shader │ │ │ │ │ ├── CausticsOcclusion.shader.meta │ │ │ │ │ ├── CausticsScene.unity │ │ │ │ │ ├── CausticsScene.unity.meta │ │ │ │ │ ├── CausticsShadowMask.mat │ │ │ │ │ ├── CausticsShadowMask.mat.meta │ │ │ │ │ ├── CompositeCausticsGodrays.shader │ │ │ │ │ ├── CompositeCausticsGodrays.shader.meta │ │ │ │ │ ├── ModulateShadowMask.cs │ │ │ │ │ ├── ModulateShadowMask.cs.meta │ │ │ │ │ ├── SeaFloor.mat │ │ │ │ │ ├── SeaFloor.mat.meta │ │ │ │ │ └── WhiteTexture.png.meta │ │ │ │ ├── Caustics.meta │ │ │ │ ├── FindHeights.compute │ │ │ │ ├── FindHeights.compute.meta │ │ │ │ ├── Fourier.shader │ │ │ │ ├── Fourier.shader.meta │ │ │ │ ├── InitDisplacement.shader │ │ │ │ ├── InitDisplacement.shader.meta │ │ │ │ ├── InitJacobians.shader │ │ │ │ ├── InitJacobians.shader.meta │ │ │ │ ├── InitSpectrum.shader │ │ │ │ ├── InitSpectrum.shader.meta │ │ │ │ ├── InvisibleOcean.shader │ │ │ │ ├── InvisibleOcean.shader.meta │ │ │ │ ├── OceanBRDF.cginc │ │ │ │ ├── OceanBRDF.cginc.meta │ │ │ │ ├── OceanDisplacement3.cginc │ │ │ │ ├── OceanDisplacement3.cginc.meta │ │ │ │ ├── OceanLight.cginc │ │ │ │ ├── OceanLight.cginc.meta │ │ │ │ ├── OceanShadows.cginc │ │ │ │ ├── OceanShadows.cginc.meta │ │ │ │ ├── OceanUtils.cginc │ │ │ │ ├── OceanUtils.cginc.meta │ │ │ │ ├── OceanWhiteCapsModProj3.shader │ │ │ │ ├── OceanWhiteCapsModProj3.shader.meta │ │ │ │ ├── OceanWhiteCapsModProj3PixelLights.shader │ │ │ │ ├── OceanWhiteCapsModProj3PixelLights.shader.meta │ │ │ │ ├── OceanWhiteCapsModProj3VertexSearch.shader │ │ │ │ ├── OceanWhiteCapsModProj3VertexSearch.shader.meta │ │ │ │ ├── ReadData.compute │ │ │ │ ├── ReadData.compute.meta │ │ │ │ ├── SlopeVariance.compute │ │ │ │ ├── SlopeVariance.compute.meta │ │ │ │ ├── UnderwaterDepthBuffer.shader │ │ │ │ ├── UnderwaterDepthBuffer.shader.meta │ │ │ │ ├── UnderwaterProjector.shader │ │ │ │ ├── UnderwaterProjector.shader.meta │ │ │ │ ├── WhiteCapsPrecompute0.shader │ │ │ │ └── WhiteCapsPrecompute0.shader.meta │ │ │ ├── Ocean.meta │ │ │ ├── RingCommon.cginc │ │ │ ├── RingCommon.cginc.meta │ │ │ ├── RingCommon.cgincBAK │ │ │ ├── RingCommon.cgincBAK.meta │ │ │ ├── Shadows/ │ │ │ │ ├── DoublePrecisionEmulation.cginc │ │ │ │ ├── DoublePrecisionEmulation.cginc.meta │ │ │ │ ├── FixedScreenSpaceShadows.cginc │ │ │ │ ├── FixedScreenSpaceShadows.cginc.meta │ │ │ │ ├── FixedScreenSpaceShadows.shader │ │ │ │ ├── FixedScreenSpaceShadows.shader.meta │ │ │ │ ├── LongDistanceScreenSpaceShadows.shader │ │ │ │ └── LongDistanceScreenSpaceShadows.shader.meta │ │ │ ├── Shadows.meta │ │ │ ├── ShadowsCommon.cginc │ │ │ ├── ShadowsCommon.cginc.meta │ │ │ ├── SunFlare/ │ │ │ │ ├── SunFlare.shader │ │ │ │ ├── SunFlare.shader.meta │ │ │ │ ├── SunFlareExtinction.shader │ │ │ │ └── SunFlareExtinction.shader.meta │ │ │ ├── SunFlare.meta │ │ │ ├── Utility.cginc │ │ │ └── Utility.cginc.meta │ │ ├── TestScenes.meta │ │ └── shaders.meta │ ├── Library/ │ │ ├── APIUpdater/ │ │ │ └── project-dependencies.graph │ │ ├── AnnotationManager │ │ ├── AssetImportState │ │ ├── AssetServerCacheV3 │ │ ├── BuildPlayer.prefs │ │ ├── BuildSettings.asset │ │ ├── CurrentLayout-default.dwlt │ │ ├── CurrentLayout.dwlt │ │ ├── CurrentMaximizeLayout.dwlt │ │ ├── EditorOnlyScriptingSettings.json │ │ ├── EditorOnlyScriptingUserSettings.json │ │ ├── EditorSnapSettings.asset │ │ ├── EditorUserBuildSettings.asset │ │ ├── EditorUserSettings.asset │ │ ├── InspectorExpandedItems.asset │ │ ├── LastBuild.buildreport │ │ ├── LastSceneManagerSetup.txt │ │ ├── LibraryFormatVersion.txt │ │ ├── MonoManager.asset │ │ ├── PackageCache/ │ │ │ ├── com.unity.collab-proxy@1.2.16/ │ │ │ │ ├── .npmignore │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CHANGELOG.md.meta │ │ │ │ ├── DEPENDENCIES.md │ │ │ │ ├── DEPENDENCIES.md.meta │ │ │ │ ├── Documentation~/ │ │ │ │ │ └── collab-proxy.md │ │ │ │ ├── Editor/ │ │ │ │ │ ├── AssemblyInfo.cs │ │ │ │ │ ├── AssemblyInfo.cs.meta │ │ │ │ │ ├── Collab/ │ │ │ │ │ │ ├── Bootstrap.cs │ │ │ │ │ │ ├── Bootstrap.cs.meta │ │ │ │ │ │ ├── CollabAnalytics.cs │ │ │ │ │ │ ├── CollabAnalytics.cs.meta │ │ │ │ │ │ ├── CollabHistoryWindow.cs │ │ │ │ │ │ ├── CollabHistoryWindow.cs.meta │ │ │ │ │ │ ├── CollabToolbarButton.cs │ │ │ │ │ │ ├── CollabToolbarButton.cs.meta │ │ │ │ │ │ ├── CollabToolbarWindow.cs │ │ │ │ │ │ ├── CollabToolbarWindow.cs.meta │ │ │ │ │ │ ├── Presenters/ │ │ │ │ │ │ │ ├── CollabHistoryPresenter.cs │ │ │ │ │ │ │ └── CollabHistoryPresenter.cs.meta │ │ │ │ │ │ ├── Presenters.meta │ │ │ │ │ │ ├── Views/ │ │ │ │ │ │ │ ├── BuildStatusButton.cs │ │ │ │ │ │ │ ├── BuildStatusButton.cs.meta │ │ │ │ │ │ │ ├── CollabHistoryDropDown.cs │ │ │ │ │ │ │ ├── CollabHistoryDropDown.cs.meta │ │ │ │ │ │ │ ├── CollabHistoryDropDownItem.cs │ │ │ │ │ │ │ ├── CollabHistoryDropDownItem.cs.meta │ │ │ │ │ │ │ ├── CollabHistoryItem.cs │ │ │ │ │ │ │ ├── CollabHistoryItem.cs.meta │ │ │ │ │ │ │ ├── CollabHistoryItemFactory.cs │ │ │ │ │ │ │ ├── CollabHistoryItemFactory.cs.meta │ │ │ │ │ │ │ ├── CollabHistoryRevisionLine.cs │ │ │ │ │ │ │ ├── CollabHistoryRevisionLine.cs.meta │ │ │ │ │ │ │ ├── HistoryProgressSpinner.cs │ │ │ │ │ │ │ ├── HistoryProgressSpinner.cs.meta │ │ │ │ │ │ │ ├── ICollabHistoryItemFactory.cs │ │ │ │ │ │ │ ├── ICollabHistoryItemFactory.cs.meta │ │ │ │ │ │ │ ├── PagedListView.cs │ │ │ │ │ │ │ ├── PagedListView.cs.meta │ │ │ │ │ │ │ ├── StatusView.cs │ │ │ │ │ │ │ └── StatusView.cs.meta │ │ │ │ │ │ └── Views.meta │ │ │ │ │ ├── Collab.meta │ │ │ │ │ ├── Resources/ │ │ │ │ │ │ ├── Styles/ │ │ │ │ │ │ │ ├── CollabHistoryCommon.uss │ │ │ │ │ │ │ ├── CollabHistoryCommon.uss.meta │ │ │ │ │ │ │ ├── CollabHistoryDark.uss │ │ │ │ │ │ │ ├── CollabHistoryDark.uss.meta │ │ │ │ │ │ │ ├── CollabHistoryLight.uss │ │ │ │ │ │ │ └── CollabHistoryLight.uss.meta │ │ │ │ │ │ └── Styles.meta │ │ │ │ │ ├── Resources.meta │ │ │ │ │ ├── Unity.CollabProxy.Editor.asmdef │ │ │ │ │ └── Unity.CollabProxy.Editor.asmdef.meta │ │ │ │ ├── Editor.meta │ │ │ │ ├── LICENSE.md │ │ │ │ ├── LICENSE.md.meta │ │ │ │ ├── README.md │ │ │ │ ├── README.md.meta │ │ │ │ ├── Tests/ │ │ │ │ │ ├── Editor/ │ │ │ │ │ │ ├── HistoryTests.cs │ │ │ │ │ │ ├── HistoryTests.cs.meta │ │ │ │ │ │ ├── Unity.CollabProxy.EditorTests.asmdef │ │ │ │ │ │ └── Unity.CollabProxy.EditorTests.asmdef.meta │ │ │ │ │ └── Editor.meta │ │ │ │ ├── Tests.meta │ │ │ │ ├── package.json │ │ │ │ └── package.json.meta │ │ │ ├── com.unity.ext.nunit@1.0.0/ │ │ │ │ ├── .gitlab-ci.yml │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CHANGELOG.md.meta │ │ │ │ ├── Documentation~/ │ │ │ │ │ └── ext.nunit.md │ │ │ │ ├── LICENSE.md │ │ │ │ ├── LICENSE.md.meta │ │ │ │ ├── README.md │ │ │ │ ├── README.md.meta │ │ │ │ ├── net35/ │ │ │ │ │ ├── unity-custom/ │ │ │ │ │ │ ├── This is a custom build DONT include.txt │ │ │ │ │ │ ├── This is a custom build DONT include.txt.meta │ │ │ │ │ │ ├── nunit.framework.dll.mdb │ │ │ │ │ │ ├── nunit.framework.dll.mdb.meta │ │ │ │ │ │ ├── nunit.framework.dll.meta │ │ │ │ │ │ ├── nunit.framework.pdb │ │ │ │ │ │ ├── nunit.framework.pdb.meta │ │ │ │ │ │ ├── nunit.framework.xml │ │ │ │ │ │ └── nunit.framework.xml.meta │ │ │ │ │ └── unity-custom.meta │ │ │ │ ├── net35.meta │ │ │ │ ├── package.json │ │ │ │ └── package.json.meta │ │ │ ├── com.unity.ide.rider@1.1.0/ │ │ │ │ ├── .editorconfig │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CHANGELOG.md.meta │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── CONTRIBUTING.md.meta │ │ │ │ ├── Documentation~/ │ │ │ │ │ └── README.md │ │ │ │ ├── LICENSE.md │ │ │ │ ├── LICENSE.md.meta │ │ │ │ ├── Rider/ │ │ │ │ │ ├── Editor/ │ │ │ │ │ │ ├── Discovery.cs │ │ │ │ │ │ ├── Discovery.cs.meta │ │ │ │ │ │ ├── EditorPluginInterop.cs │ │ │ │ │ │ ├── EditorPluginInterop.cs.meta │ │ │ │ │ │ ├── LoggingLevel.cs │ │ │ │ │ │ ├── LoggingLevel.cs.meta │ │ │ │ │ │ ├── PluginSettings.cs │ │ │ │ │ │ ├── PluginSettings.cs.meta │ │ │ │ │ │ ├── ProjectGeneration.cs │ │ │ │ │ │ ├── ProjectGeneration.cs.meta │ │ │ │ │ │ ├── RiderInitializer.cs │ │ │ │ │ │ ├── RiderInitializer.cs.meta │ │ │ │ │ │ ├── RiderScriptEditor.cs │ │ │ │ │ │ ├── RiderScriptEditor.cs.meta │ │ │ │ │ │ ├── RiderScriptEditorData.cs │ │ │ │ │ │ ├── RiderScriptEditorData.cs.meta │ │ │ │ │ │ ├── Util/ │ │ │ │ │ │ │ ├── FileSystemUtil.cs │ │ │ │ │ │ │ ├── FileSystemUtil.cs.meta │ │ │ │ │ │ │ ├── LibcNativeInterop.cs │ │ │ │ │ │ │ ├── LibcNativeInterop.cs.meta │ │ │ │ │ │ │ ├── UnityUtils.cs │ │ │ │ │ │ │ └── UnityUtils.cs.meta │ │ │ │ │ │ ├── Util.meta │ │ │ │ │ │ ├── com.unity.ide.rider.asmdef │ │ │ │ │ │ └── com.unity.ide.rider.asmdef.meta │ │ │ │ │ └── Editor.meta │ │ │ │ ├── Rider.meta │ │ │ │ ├── package.json │ │ │ │ └── package.json.meta │ │ │ ├── com.unity.ide.vscode@1.1.3/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CHANGELOG.md.meta │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── CONTRIBUTING.md.meta │ │ │ │ ├── Documentation~/ │ │ │ │ │ └── README.md │ │ │ │ ├── Editor/ │ │ │ │ │ ├── ProjectGeneration/ │ │ │ │ │ │ ├── AssemblyNameProvider.cs │ │ │ │ │ │ ├── AssemblyNameProvider.cs.meta │ │ │ │ │ │ ├── FileIO.cs │ │ │ │ │ │ ├── FileIO.cs.meta │ │ │ │ │ │ ├── GUIDGenerator.cs │ │ │ │ │ │ ├── GUIDGenerator.cs.meta │ │ │ │ │ │ ├── ProjectGeneration.cs │ │ │ │ │ │ └── ProjectGeneration.cs.meta │ │ │ │ │ ├── ProjectGeneration.meta │ │ │ │ │ ├── Unity.com.unity.vscode.Editor.asmdef │ │ │ │ │ ├── Unity.com.unity.vscode.Editor.asmdef.meta │ │ │ │ │ ├── Utility.cs │ │ │ │ │ ├── Utility.cs.meta │ │ │ │ │ ├── VSCodeDiscovery.cs │ │ │ │ │ ├── VSCodeDiscovery.cs.meta │ │ │ │ │ ├── VSCodeScriptEditor.cs │ │ │ │ │ └── VSCodeScriptEditor.cs.meta │ │ │ │ ├── Editor.meta │ │ │ │ ├── LICENSE.md │ │ │ │ ├── LICENSE.md.meta │ │ │ │ ├── package.json │ │ │ │ └── package.json.meta │ │ │ ├── com.unity.test-framework@1.0.13/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CHANGELOG.md.meta │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── CONTRIBUTING.md.meta │ │ │ │ ├── Documentation~/ │ │ │ │ │ ├── PlaymodeTestFramework.md │ │ │ │ │ └── com.unity.test-framework.md │ │ │ │ ├── LICENSE.md │ │ │ │ ├── LICENSE.md.meta │ │ │ │ ├── UnityEditor.TestRunner/ │ │ │ │ │ ├── Api/ │ │ │ │ │ │ ├── CallbacksDelegator.cs │ │ │ │ │ │ ├── CallbacksDelegator.cs.meta │ │ │ │ │ │ ├── CallbacksDelegatorListener.cs │ │ │ │ │ │ ├── CallbacksDelegatorListener.cs.meta │ │ │ │ │ │ ├── CallbacksHolder.cs │ │ │ │ │ │ ├── CallbacksHolder.cs.meta │ │ │ │ │ │ ├── ExecutionSettings.cs │ │ │ │ │ │ ├── ExecutionSettings.cs.meta │ │ │ │ │ │ ├── Filter.cs │ │ │ │ │ │ ├── Filter.cs.meta │ │ │ │ │ │ ├── ICallbacks.cs │ │ │ │ │ │ ├── ICallbacks.cs.meta │ │ │ │ │ │ ├── ITestAdaptor.cs │ │ │ │ │ │ ├── ITestAdaptor.cs.meta │ │ │ │ │ │ ├── ITestAdaptorFactory.cs │ │ │ │ │ │ ├── ITestAdaptorFactory.cs.meta │ │ │ │ │ │ ├── ITestResultAdaptor.cs │ │ │ │ │ │ ├── ITestResultAdaptor.cs.meta │ │ │ │ │ │ ├── ITestRunSettings.cs │ │ │ │ │ │ ├── ITestRunSettings.cs.meta │ │ │ │ │ │ ├── ITestRunnerApi.cs │ │ │ │ │ │ ├── ITestRunnerApi.cs.meta │ │ │ │ │ │ ├── RunState.cs │ │ │ │ │ │ ├── RunState.cs.meta │ │ │ │ │ │ ├── TestAdaptor.cs │ │ │ │ │ │ ├── TestAdaptor.cs.meta │ │ │ │ │ │ ├── TestAdaptorFactory.cs │ │ │ │ │ │ ├── TestAdaptorFactory.cs.meta │ │ │ │ │ │ ├── TestLauncherFactory.cs │ │ │ │ │ │ ├── TestLauncherFactory.cs.meta │ │ │ │ │ │ ├── TestMode.cs │ │ │ │ │ │ ├── TestMode.cs.meta │ │ │ │ │ │ ├── TestResultAdaptor.cs │ │ │ │ │ │ ├── TestResultAdaptor.cs.meta │ │ │ │ │ │ ├── TestRunData.cs │ │ │ │ │ │ ├── TestRunData.cs.meta │ │ │ │ │ │ ├── TestRunnerApi.cs │ │ │ │ │ │ ├── TestRunnerApi.cs.meta │ │ │ │ │ │ ├── TestStatus.cs │ │ │ │ │ │ └── TestStatus.cs.meta │ │ │ │ │ ├── Api.meta │ │ │ │ │ ├── AssemblyInfo.cs │ │ │ │ │ ├── AssemblyInfo.cs.meta │ │ │ │ │ ├── CommandLineParser/ │ │ │ │ │ │ ├── CommandLineOption.cs │ │ │ │ │ │ ├── CommandLineOption.cs.meta │ │ │ │ │ │ ├── CommandLineOptionSet.cs │ │ │ │ │ │ ├── CommandLineOptionSet.cs.meta │ │ │ │ │ │ ├── ICommandLineOption.cs │ │ │ │ │ │ └── ICommandLineOption.cs.meta │ │ │ │ │ ├── CommandLineParser.meta │ │ │ │ │ ├── CommandLineTest/ │ │ │ │ │ │ ├── Executer.cs │ │ │ │ │ │ ├── Executer.cs.meta │ │ │ │ │ │ ├── ExecutionSettings.cs │ │ │ │ │ │ ├── ExecutionSettings.cs.meta │ │ │ │ │ │ ├── ExitCallbacks.cs │ │ │ │ │ │ ├── ExitCallbacks.cs.meta │ │ │ │ │ │ ├── ISettingsBuilder.cs │ │ │ │ │ │ ├── ISettingsBuilder.cs.meta │ │ │ │ │ │ ├── LogSavingCallbacks.cs │ │ │ │ │ │ ├── LogSavingCallbacks.cs.meta │ │ │ │ │ │ ├── LogWriter.cs │ │ │ │ │ │ ├── LogWriter.cs.meta │ │ │ │ │ │ ├── ResultsSavingCallbacks.cs │ │ │ │ │ │ ├── ResultsSavingCallbacks.cs.meta │ │ │ │ │ │ ├── ResultsWriter.cs │ │ │ │ │ │ ├── ResultsWriter.cs.meta │ │ │ │ │ │ ├── RunData.cs │ │ │ │ │ │ ├── RunData.cs.meta │ │ │ │ │ │ ├── RunSettings.cs │ │ │ │ │ │ ├── RunSettings.cs.meta │ │ │ │ │ │ ├── SettingsBuilder.cs │ │ │ │ │ │ ├── SettingsBuilder.cs.meta │ │ │ │ │ │ ├── SetupException.cs │ │ │ │ │ │ ├── SetupException.cs.meta │ │ │ │ │ │ ├── TestStarter.cs │ │ │ │ │ │ ├── TestStarter.cs.meta │ │ │ │ │ │ ├── TimeoutCallbacks.cs │ │ │ │ │ │ └── TimeoutCallbacks.cs.meta │ │ │ │ │ ├── CommandLineTest.meta │ │ │ │ │ ├── GUI/ │ │ │ │ │ │ ├── AssetsDatabaseHelper.cs │ │ │ │ │ │ ├── AssetsDatabaseHelper.cs.meta │ │ │ │ │ │ ├── GuiHelper.cs │ │ │ │ │ │ ├── GuiHelper.cs.meta │ │ │ │ │ │ ├── IAssetsDatabaseHelper.cs │ │ │ │ │ │ ├── IAssetsDatabaseHelper.cs.meta │ │ │ │ │ │ ├── IGuiHelper.cs │ │ │ │ │ │ ├── IGuiHelper.cs.meta │ │ │ │ │ │ ├── TestListBuilder/ │ │ │ │ │ │ │ ├── RenderingOptions.cs │ │ │ │ │ │ │ ├── RenderingOptions.cs.meta │ │ │ │ │ │ │ ├── ResultSummarizer.cs │ │ │ │ │ │ │ ├── ResultSummarizer.cs.meta │ │ │ │ │ │ │ ├── TestFilterSettings.cs │ │ │ │ │ │ │ ├── TestFilterSettings.cs.meta │ │ │ │ │ │ │ ├── TestTreeViewBuilder.cs │ │ │ │ │ │ │ └── TestTreeViewBuilder.cs.meta │ │ │ │ │ │ ├── TestListBuilder.meta │ │ │ │ │ │ ├── TestListGuiHelper.cs │ │ │ │ │ │ ├── TestListGuiHelper.cs.meta │ │ │ │ │ │ ├── TestListTreeView/ │ │ │ │ │ │ │ ├── Icons.cs │ │ │ │ │ │ │ ├── Icons.cs.meta │ │ │ │ │ │ │ ├── TestListTreeViewDataSource.cs │ │ │ │ │ │ │ ├── TestListTreeViewDataSource.cs.meta │ │ │ │ │ │ │ ├── TestListTreeViewGUI.cs │ │ │ │ │ │ │ ├── TestListTreeViewGUI.cs.meta │ │ │ │ │ │ │ ├── TestTreeViewItem.cs │ │ │ │ │ │ │ └── TestTreeViewItem.cs.meta │ │ │ │ │ │ ├── TestListTreeView.meta │ │ │ │ │ │ ├── TestRunnerResult.cs │ │ │ │ │ │ ├── TestRunnerResult.cs.meta │ │ │ │ │ │ ├── TestRunnerUIFilter.cs │ │ │ │ │ │ ├── TestRunnerUIFilter.cs.meta │ │ │ │ │ │ ├── Views/ │ │ │ │ │ │ │ ├── EditModeTestListGUI.cs │ │ │ │ │ │ │ ├── EditModeTestListGUI.cs.meta │ │ │ │ │ │ │ ├── PlayModeTestListGUI.cs │ │ │ │ │ │ │ ├── PlayModeTestListGUI.cs.meta │ │ │ │ │ │ │ ├── TestListGUIBase.cs │ │ │ │ │ │ │ └── TestListGUIBase.cs.meta │ │ │ │ │ │ └── Views.meta │ │ │ │ │ ├── GUI.meta │ │ │ │ │ ├── NUnitExtension/ │ │ │ │ │ │ ├── Attributes/ │ │ │ │ │ │ │ ├── AssetPipelineIgnore.cs │ │ │ │ │ │ │ └── AssetPipelineIgnore.cs.meta │ │ │ │ │ │ ├── Attributes.meta │ │ │ │ │ │ ├── TestRunnerStateSerializer.cs │ │ │ │ │ │ └── TestRunnerStateSerializer.cs.meta │ │ │ │ │ ├── NUnitExtension.meta │ │ │ │ │ ├── RequireApiProfileAttribute.cs │ │ │ │ │ ├── RequireApiProfileAttribute.cs.meta │ │ │ │ │ ├── RequirePlatformSupportAttribute.cs │ │ │ │ │ ├── RequirePlatformSupportAttribute.cs.meta │ │ │ │ │ ├── TestBuildAssemblyFilter.cs │ │ │ │ │ ├── TestBuildAssemblyFilter.cs.meta │ │ │ │ │ ├── TestLaunchers/ │ │ │ │ │ │ ├── AttributeFinderBase.cs │ │ │ │ │ │ ├── AttributeFinderBase.cs.meta │ │ │ │ │ │ ├── EditModeLauncher.cs │ │ │ │ │ │ ├── EditModeLauncher.cs.meta │ │ │ │ │ │ ├── EditModeLauncherContextSettings.cs │ │ │ │ │ │ ├── EditModeLauncherContextSettings.cs.meta │ │ │ │ │ │ ├── PlatformSetup/ │ │ │ │ │ │ │ ├── AndroidPlatformSetup.cs │ │ │ │ │ │ │ ├── AndroidPlatformSetup.cs.meta │ │ │ │ │ │ │ ├── ApplePlatformSetup.cs │ │ │ │ │ │ │ ├── ApplePlatformSetup.cs.meta │ │ │ │ │ │ │ ├── IPlatformSetup.cs │ │ │ │ │ │ │ ├── IPlatformSetup.cs.meta │ │ │ │ │ │ │ ├── LuminPlatformSetup.cs │ │ │ │ │ │ │ ├── LuminPlatformSetup.cs.meta │ │ │ │ │ │ │ ├── PlatformSpecificSetup.cs │ │ │ │ │ │ │ ├── PlatformSpecificSetup.cs.meta │ │ │ │ │ │ │ ├── SwitchPlatformSetup.cs │ │ │ │ │ │ │ ├── SwitchPlatformSetup.cs.meta │ │ │ │ │ │ │ ├── UwpPlatformSetup.cs │ │ │ │ │ │ │ ├── UwpPlatformSetup.cs.meta │ │ │ │ │ │ │ ├── XboxOnePlatformSetup.cs │ │ │ │ │ │ │ └── XboxOnePlatformSetup.cs.meta │ │ │ │ │ │ ├── PlatformSetup.meta │ │ │ │ │ │ ├── PlayerLauncher.cs │ │ │ │ │ │ ├── PlayerLauncher.cs.meta │ │ │ │ │ │ ├── PlayerLauncherBuildOptions.cs │ │ │ │ │ │ ├── PlayerLauncherBuildOptions.cs.meta │ │ │ │ │ │ ├── PlayerLauncherContextSettings.cs │ │ │ │ │ │ ├── PlayerLauncherContextSettings.cs.meta │ │ │ │ │ │ ├── PlaymodeLauncher.cs │ │ │ │ │ │ ├── PlaymodeLauncher.cs.meta │ │ │ │ │ │ ├── PostbuildCleanupAttributeFinder.cs │ │ │ │ │ │ ├── PostbuildCleanupAttributeFinder.cs.meta │ │ │ │ │ │ ├── PrebuildSetupAttributeFinder.cs │ │ │ │ │ │ ├── PrebuildSetupAttributeFinder.cs.meta │ │ │ │ │ │ ├── RemotePlayerLogController.cs │ │ │ │ │ │ ├── RemotePlayerLogController.cs.meta │ │ │ │ │ │ ├── RemotePlayerTestController.cs │ │ │ │ │ │ ├── RemotePlayerTestController.cs.meta │ │ │ │ │ │ ├── RemoteTestResultReciever.cs │ │ │ │ │ │ ├── RemoteTestResultReciever.cs.meta │ │ │ │ │ │ ├── RuntimeTestLauncherBase.cs │ │ │ │ │ │ ├── RuntimeTestLauncherBase.cs.meta │ │ │ │ │ │ ├── TestLauncherBase.cs │ │ │ │ │ │ └── TestLauncherBase.cs.meta │ │ │ │ │ ├── TestLaunchers.meta │ │ │ │ │ ├── TestResultSerializer.cs │ │ │ │ │ ├── TestResultSerializer.cs.meta │ │ │ │ │ ├── TestRunner/ │ │ │ │ │ │ ├── Callbacks/ │ │ │ │ │ │ │ ├── EditModeRunnerCallback.cs │ │ │ │ │ │ │ ├── EditModeRunnerCallback.cs.meta │ │ │ │ │ │ │ ├── RerunCallback.cs │ │ │ │ │ │ │ ├── RerunCallback.cs.meta │ │ │ │ │ │ │ ├── RerunCallbackData.cs │ │ │ │ │ │ │ ├── RerunCallbackData.cs.meta │ │ │ │ │ │ │ ├── RerunCallbackInitializer.cs │ │ │ │ │ │ │ ├── RerunCallbackInitializer.cs.meta │ │ │ │ │ │ │ ├── TestRunnerCallback.cs │ │ │ │ │ │ │ ├── TestRunnerCallback.cs.meta │ │ │ │ │ │ │ ├── WindowResultUpdater.cs │ │ │ │ │ │ │ └── WindowResultUpdater.cs.meta │ │ │ │ │ │ ├── Callbacks.meta │ │ │ │ │ │ ├── EditModePCHelper.cs │ │ │ │ │ │ ├── EditModePCHelper.cs.meta │ │ │ │ │ │ ├── EditModeRunner.cs │ │ │ │ │ │ ├── EditModeRunner.cs.meta │ │ │ │ │ │ ├── EditmodeWorkItemFactory.cs │ │ │ │ │ │ ├── EditmodeWorkItemFactory.cs.meta │ │ │ │ │ │ ├── EditorEnumeratorTestWorkItem.cs │ │ │ │ │ │ ├── EditorEnumeratorTestWorkItem.cs.meta │ │ │ │ │ │ ├── EnumeratorStepHelper.cs │ │ │ │ │ │ ├── EnumeratorStepHelper.cs.meta │ │ │ │ │ │ ├── Messages/ │ │ │ │ │ │ │ ├── EnterPlayMode.cs │ │ │ │ │ │ │ ├── EnterPlayMode.cs.meta │ │ │ │ │ │ │ ├── ExitPlayMode.cs │ │ │ │ │ │ │ ├── ExitPlayMode.cs.meta │ │ │ │ │ │ │ ├── RecompileScripts.cs │ │ │ │ │ │ │ ├── RecompileScripts.cs.meta │ │ │ │ │ │ │ ├── WaitForDomainReload.cs │ │ │ │ │ │ │ └── WaitForDomainReload.cs.meta │ │ │ │ │ │ ├── Messages.meta │ │ │ │ │ │ ├── TestFileCleanupVerifier.cs │ │ │ │ │ │ ├── TestFileCleanupVerifier.cs.meta │ │ │ │ │ │ ├── Utils/ │ │ │ │ │ │ │ ├── CachingTestListProvider.cs │ │ │ │ │ │ │ ├── CachingTestListProvider.cs.meta │ │ │ │ │ │ │ ├── EditorAssembliesProxy.cs │ │ │ │ │ │ │ ├── EditorAssembliesProxy.cs.meta │ │ │ │ │ │ │ ├── EditorAssemblyWrapper.cs │ │ │ │ │ │ │ ├── EditorAssemblyWrapper.cs.meta │ │ │ │ │ │ │ ├── EditorCompilationInterfaceProxy.cs │ │ │ │ │ │ │ ├── EditorCompilationInterfaceProxy.cs.meta │ │ │ │ │ │ │ ├── EditorLoadedTestAssemblyProvider.cs │ │ │ │ │ │ │ ├── EditorLoadedTestAssemblyProvider.cs.meta │ │ │ │ │ │ │ ├── IEditorAssembliesProxy.cs │ │ │ │ │ │ │ ├── IEditorAssembliesProxy.cs.meta │ │ │ │ │ │ │ ├── IEditorCompilationInterfaceProxy.cs │ │ │ │ │ │ │ ├── IEditorCompilationInterfaceProxy.cs.meta │ │ │ │ │ │ │ ├── ITestListCache.cs │ │ │ │ │ │ │ ├── ITestListCache.cs.meta │ │ │ │ │ │ │ ├── ITestListCacheData.cs │ │ │ │ │ │ │ ├── ITestListCacheData.cs.meta │ │ │ │ │ │ │ ├── ITestListProvider.cs │ │ │ │ │ │ │ ├── ITestListProvider.cs.meta │ │ │ │ │ │ │ ├── TestListCache.cs │ │ │ │ │ │ │ ├── TestListCache.cs.meta │ │ │ │ │ │ │ ├── TestListCacheData.cs │ │ │ │ │ │ │ ├── TestListCacheData.cs.meta │ │ │ │ │ │ │ ├── TestListJob.cs │ │ │ │ │ │ │ ├── TestListJob.cs.meta │ │ │ │ │ │ │ ├── TestListProvider.cs │ │ │ │ │ │ │ └── TestListProvider.cs.meta │ │ │ │ │ │ └── Utils.meta │ │ │ │ │ ├── TestRunner.meta │ │ │ │ │ ├── TestRunnerWindow.cs │ │ │ │ │ ├── TestRunnerWindow.cs.meta │ │ │ │ │ ├── TestRunnerWindowSettings.cs │ │ │ │ │ ├── TestRunnerWindowSettings.cs.meta │ │ │ │ │ ├── TestSettings/ │ │ │ │ │ │ ├── ITestSettings.cs │ │ │ │ │ │ ├── ITestSettings.cs.meta │ │ │ │ │ │ ├── ITestSettingsDeserializer.cs │ │ │ │ │ │ ├── ITestSettingsDeserializer.cs.meta │ │ │ │ │ │ ├── TestSettings.cs │ │ │ │ │ │ ├── TestSettings.cs.meta │ │ │ │ │ │ ├── TestSettingsDeserializer.cs │ │ │ │ │ │ └── TestSettingsDeserializer.cs.meta │ │ │ │ │ ├── TestSettings.meta │ │ │ │ │ ├── UnityEditor.TestRunner.asmdef │ │ │ │ │ ├── UnityEditor.TestRunner.asmdef.meta │ │ │ │ │ ├── UnityTestProtocol/ │ │ │ │ │ │ ├── AssemblyCompilationErrorsMessage.cs │ │ │ │ │ │ ├── AssemblyCompilationErrorsMessage.cs.meta │ │ │ │ │ │ ├── ITestRunnerApiMapper.cs │ │ │ │ │ │ ├── ITestRunnerApiMapper.cs.meta │ │ │ │ │ │ ├── IUtpLogger.cs │ │ │ │ │ │ ├── IUtpLogger.cs.meta │ │ │ │ │ │ ├── IUtpMessageReporter.cs │ │ │ │ │ │ ├── IUtpMessageReporter.cs.meta │ │ │ │ │ │ ├── Message.cs │ │ │ │ │ │ ├── Message.cs.meta │ │ │ │ │ │ ├── TestFinishedMessage.cs │ │ │ │ │ │ ├── TestFinishedMessage.cs.meta │ │ │ │ │ │ ├── TestPlanMessage.cs │ │ │ │ │ │ ├── TestPlanMessage.cs.meta │ │ │ │ │ │ ├── TestRunnerApiMapper.cs │ │ │ │ │ │ ├── TestRunnerApiMapper.cs.meta │ │ │ │ │ │ ├── TestStartedMessage.cs │ │ │ │ │ │ ├── TestStartedMessage.cs.meta │ │ │ │ │ │ ├── TestState.cs │ │ │ │ │ │ ├── TestState.cs.meta │ │ │ │ │ │ ├── UnityTestProtocolListener.cs │ │ │ │ │ │ ├── UnityTestProtocolListener.cs.meta │ │ │ │ │ │ ├── UnityTestProtocolStarter.cs │ │ │ │ │ │ ├── UnityTestProtocolStarter.cs.meta │ │ │ │ │ │ ├── UtpDebuglogger.cs │ │ │ │ │ │ ├── UtpDebuglogger.cs.meta │ │ │ │ │ │ ├── UtpMessageReporter.cs │ │ │ │ │ │ └── UtpMessageReporter.cs.meta │ │ │ │ │ └── UnityTestProtocol.meta │ │ │ │ ├── UnityEditor.TestRunner.meta │ │ │ │ ├── UnityEngine.TestRunner/ │ │ │ │ │ ├── AssemblyInfo.cs │ │ │ │ │ ├── AssemblyInfo.cs.meta │ │ │ │ │ ├── Assertions/ │ │ │ │ │ │ ├── AllocatingGCMemoryConstraint.cs │ │ │ │ │ │ ├── AllocatingGCMemoryConstraint.cs.meta │ │ │ │ │ │ ├── ConstraintsExtensions.cs │ │ │ │ │ │ ├── ConstraintsExtensions.cs.meta │ │ │ │ │ │ ├── InvalidSignatureException.cs │ │ │ │ │ │ ├── InvalidSignatureException.cs.meta │ │ │ │ │ │ ├── Is.cs │ │ │ │ │ │ ├── Is.cs.meta │ │ │ │ │ │ ├── LogAssert.cs │ │ │ │ │ │ ├── LogAssert.cs.meta │ │ │ │ │ │ ├── LogScope/ │ │ │ │ │ │ │ ├── ILogScope.cs │ │ │ │ │ │ │ ├── ILogScope.cs.meta │ │ │ │ │ │ │ ├── LogEvent.cs │ │ │ │ │ │ │ ├── LogEvent.cs.meta │ │ │ │ │ │ │ ├── LogMatch.cs │ │ │ │ │ │ │ ├── LogMatch.cs.meta │ │ │ │ │ │ │ ├── LogScope.cs │ │ │ │ │ │ │ └── LogScope.cs.meta │ │ │ │ │ │ ├── LogScope.meta │ │ │ │ │ │ ├── UnexpectedLogMessageException.cs │ │ │ │ │ │ ├── UnexpectedLogMessageException.cs.meta │ │ │ │ │ │ ├── UnhandledLogMessageException.cs │ │ │ │ │ │ ├── UnhandledLogMessageException.cs.meta │ │ │ │ │ │ ├── UnityTestTimeoutException.cs │ │ │ │ │ │ └── UnityTestTimeoutException.cs.meta │ │ │ │ │ ├── Assertions.meta │ │ │ │ │ ├── NUnitExtensions/ │ │ │ │ │ │ ├── ActionDelegator.cs │ │ │ │ │ │ ├── ActionDelegator.cs.meta │ │ │ │ │ │ ├── Attributes/ │ │ │ │ │ │ │ ├── TestEnumerator.cs │ │ │ │ │ │ │ ├── TestEnumerator.cs.meta │ │ │ │ │ │ │ ├── UnityCombinatorialStrategy.cs │ │ │ │ │ │ │ ├── UnityCombinatorialStrategy.cs.meta │ │ │ │ │ │ │ ├── UnityPlatformAttribute.cs │ │ │ │ │ │ │ ├── UnityPlatformAttribute.cs.meta │ │ │ │ │ │ │ ├── UnitySetUpAttribute.cs │ │ │ │ │ │ │ ├── UnitySetUpAttribute.cs.meta │ │ │ │ │ │ │ ├── UnityTearDownAttribute.cs │ │ │ │ │ │ │ ├── UnityTearDownAttribute.cs.meta │ │ │ │ │ │ │ ├── UnityTestAttribute.cs │ │ │ │ │ │ │ └── UnityTestAttribute.cs.meta │ │ │ │ │ │ ├── Attributes.meta │ │ │ │ │ │ ├── BaseDelegator.cs │ │ │ │ │ │ ├── BaseDelegator.cs.meta │ │ │ │ │ │ ├── Commands/ │ │ │ │ │ │ │ ├── BeforeAfterTestCommandBase.cs │ │ │ │ │ │ │ ├── BeforeAfterTestCommandBase.cs.meta │ │ │ │ │ │ │ ├── BeforeAfterTestCommandState.cs │ │ │ │ │ │ │ ├── BeforeAfterTestCommandState.cs.meta │ │ │ │ │ │ │ ├── EnumerableApplyChangesToContextCommand.cs │ │ │ │ │ │ │ ├── EnumerableApplyChangesToContextCommand.cs.meta │ │ │ │ │ │ │ ├── EnumerableSetUpTearDownCommand.cs │ │ │ │ │ │ │ ├── EnumerableSetUpTearDownCommand.cs.meta │ │ │ │ │ │ │ ├── EnumerableTestMethodCommand.cs │ │ │ │ │ │ │ ├── EnumerableTestMethodCommand.cs.meta │ │ │ │ │ │ │ ├── ImmediateEnumerableCommand.cs │ │ │ │ │ │ │ ├── ImmediateEnumerableCommand.cs.meta │ │ │ │ │ │ │ ├── OuterUnityTestActionCommand.cs │ │ │ │ │ │ │ ├── OuterUnityTestActionCommand.cs.meta │ │ │ │ │ │ │ ├── SetUpTearDownCommand.cs │ │ │ │ │ │ │ ├── SetUpTearDownCommand.cs.meta │ │ │ │ │ │ │ ├── TestActionCommand.cs │ │ │ │ │ │ │ ├── TestActionCommand.cs.meta │ │ │ │ │ │ │ ├── TestCommandPcHelper.cs │ │ │ │ │ │ │ └── TestCommandPcHelper.cs.meta │ │ │ │ │ │ ├── Commands.meta │ │ │ │ │ │ ├── ConstructDelegator.cs │ │ │ │ │ │ ├── ConstructDelegator.cs.meta │ │ │ │ │ │ ├── Filters/ │ │ │ │ │ │ │ ├── AssemblyNameFilter.cs │ │ │ │ │ │ │ ├── AssemblyNameFilter.cs.meta │ │ │ │ │ │ │ ├── CategoryFilterExtended.cs │ │ │ │ │ │ │ └── CategoryFilterExtended.cs.meta │ │ │ │ │ │ ├── Filters.meta │ │ │ │ │ │ ├── IStateSerializer.cs │ │ │ │ │ │ ├── IStateSerializer.cs.meta │ │ │ │ │ │ ├── Runner/ │ │ │ │ │ │ │ ├── CompositeWorkItem.cs │ │ │ │ │ │ │ ├── CompositeWorkItem.cs.meta │ │ │ │ │ │ │ ├── CoroutineTestWorkItem.cs │ │ │ │ │ │ │ ├── CoroutineTestWorkItem.cs.meta │ │ │ │ │ │ │ ├── DefaultTestWorkItem.cs │ │ │ │ │ │ │ ├── DefaultTestWorkItem.cs.meta │ │ │ │ │ │ │ ├── FailCommand.cs │ │ │ │ │ │ │ ├── FailCommand.cs.meta │ │ │ │ │ │ │ ├── IEnumerableTestMethodCommand.cs │ │ │ │ │ │ │ ├── IEnumerableTestMethodCommand.cs.meta │ │ │ │ │ │ │ ├── PlaymodeWorkItemFactory.cs │ │ │ │ │ │ │ ├── PlaymodeWorkItemFactory.cs.meta │ │ │ │ │ │ │ ├── RestoreTestContextAfterDomainReload.cs │ │ │ │ │ │ │ ├── RestoreTestContextAfterDomainReload.cs.meta │ │ │ │ │ │ │ ├── UnityLogCheckDelegatingCommand.cs │ │ │ │ │ │ │ ├── UnityLogCheckDelegatingCommand.cs.meta │ │ │ │ │ │ │ ├── UnityTestAssemblyRunner.cs │ │ │ │ │ │ │ ├── UnityTestAssemblyRunner.cs.meta │ │ │ │ │ │ │ ├── UnityTestExecutionContext.cs │ │ │ │ │ │ │ ├── UnityTestExecutionContext.cs.meta │ │ │ │ │ │ │ ├── UnityWorkItem.cs │ │ │ │ │ │ │ ├── UnityWorkItem.cs.meta │ │ │ │ │ │ │ ├── UnityWorkItemDataHolder.cs │ │ │ │ │ │ │ ├── UnityWorkItemDataHolder.cs.meta │ │ │ │ │ │ │ ├── WorkItemFactory.cs │ │ │ │ │ │ │ └── WorkItemFactory.cs.meta │ │ │ │ │ │ ├── Runner.meta │ │ │ │ │ │ ├── TestExtensions.cs │ │ │ │ │ │ ├── TestExtensions.cs.meta │ │ │ │ │ │ ├── TestResultExtensions.cs │ │ │ │ │ │ ├── TestResultExtensions.cs.meta │ │ │ │ │ │ ├── UnityTestAssemblyBuilder.cs │ │ │ │ │ │ └── UnityTestAssemblyBuilder.cs.meta │ │ │ │ │ ├── NUnitExtensions.meta │ │ │ │ │ ├── TestRunner/ │ │ │ │ │ │ ├── Callbacks/ │ │ │ │ │ │ │ ├── PlayModeRunnerCallback.cs │ │ │ │ │ │ │ ├── PlayModeRunnerCallback.cs.meta │ │ │ │ │ │ │ ├── RemoteTestResultSender.cs │ │ │ │ │ │ │ ├── RemoteTestResultSender.cs.meta │ │ │ │ │ │ │ ├── TestResultRenderer.cs │ │ │ │ │ │ │ ├── TestResultRenderer.cs.meta │ │ │ │ │ │ │ ├── TestResultRendererCallback.cs │ │ │ │ │ │ │ └── TestResultRendererCallback.cs.meta │ │ │ │ │ │ ├── Callbacks.meta │ │ │ │ │ │ ├── ITestRunnerListener.cs │ │ │ │ │ │ ├── ITestRunnerListener.cs.meta │ │ │ │ │ │ ├── Messages/ │ │ │ │ │ │ │ ├── IEditModeTestYieldInstruction.cs │ │ │ │ │ │ │ └── IEditModeTestYieldInstruction.cs.meta │ │ │ │ │ │ ├── Messages.meta │ │ │ │ │ │ ├── PlaymodeTestsController.cs │ │ │ │ │ │ ├── PlaymodeTestsController.cs.meta │ │ │ │ │ │ ├── PlaymodeTestsControllerSettings.cs │ │ │ │ │ │ ├── PlaymodeTestsControllerSettings.cs.meta │ │ │ │ │ │ ├── RemoteHelpers/ │ │ │ │ │ │ │ ├── IRemoteTestResultDataFactory.cs │ │ │ │ │ │ │ ├── IRemoteTestResultDataFactory.cs.meta │ │ │ │ │ │ │ ├── PlayerConnectionMessageIds.cs │ │ │ │ │ │ │ ├── PlayerConnectionMessageIds.cs.meta │ │ │ │ │ │ │ ├── RemoteTestData.cs │ │ │ │ │ │ │ ├── RemoteTestData.cs.meta │ │ │ │ │ │ │ ├── RemoteTestResultData.cs │ │ │ │ │ │ │ ├── RemoteTestResultData.cs.meta │ │ │ │ │ │ │ ├── RemoteTestResultDataFactory.cs │ │ │ │ │ │ │ ├── RemoteTestResultDataFactory.cs.meta │ │ │ │ │ │ │ ├── RemoteTestResultDataWithTestData.cs │ │ │ │ │ │ │ └── RemoteTestResultDataWithTestData.cs.meta │ │ │ │ │ │ ├── RemoteHelpers.meta │ │ │ │ │ │ ├── TestEnumeratorWrapper.cs │ │ │ │ │ │ ├── TestEnumeratorWrapper.cs.meta │ │ │ │ │ │ ├── TestListenerWrapper.cs │ │ │ │ │ │ ├── TestListenerWrapper.cs.meta │ │ │ │ │ │ ├── TestPlatform.cs │ │ │ │ │ │ ├── TestPlatform.cs.meta │ │ │ │ │ │ ├── TestRunnerFilter.cs │ │ │ │ │ │ └── TestRunnerFilter.cs.meta │ │ │ │ │ ├── TestRunner.meta │ │ │ │ │ ├── UnityEngine.TestRunner.asmdef │ │ │ │ │ ├── UnityEngine.TestRunner.asmdef.meta │ │ │ │ │ ├── Utils/ │ │ │ │ │ │ ├── AssemblyProvider/ │ │ │ │ │ │ │ ├── AssemblyLoadProxy.cs │ │ │ │ │ │ │ ├── AssemblyLoadProxy.cs.meta │ │ │ │ │ │ │ ├── AssemblyWrapper.cs │ │ │ │ │ │ │ ├── AssemblyWrapper.cs.meta │ │ │ │ │ │ │ ├── IAssemblyLoadProxy.cs │ │ │ │ │ │ │ ├── IAssemblyLoadProxy.cs.meta │ │ │ │ │ │ │ ├── IAssemblyWrapper.cs │ │ │ │ │ │ │ ├── IAssemblyWrapper.cs.meta │ │ │ │ │ │ │ ├── IScriptingRuntimeProxy.cs │ │ │ │ │ │ │ ├── IScriptingRuntimeProxy.cs.meta │ │ │ │ │ │ │ ├── ITestAssemblyProvider.cs │ │ │ │ │ │ │ ├── ITestAssemblyProvider.cs.meta │ │ │ │ │ │ │ ├── PlayerTestAssemblyProvider.cs │ │ │ │ │ │ │ ├── PlayerTestAssemblyProvider.cs.meta │ │ │ │ │ │ │ ├── ScriptingRuntimeProxy.cs │ │ │ │ │ │ │ └── ScriptingRuntimeProxy.cs.meta │ │ │ │ │ │ ├── AssemblyProvider.meta │ │ │ │ │ │ ├── AttributeHelper.cs │ │ │ │ │ │ ├── AttributeHelper.cs.meta │ │ │ │ │ │ ├── ColorEqualityComparer.cs │ │ │ │ │ │ ├── ColorEqualityComparer.cs.meta │ │ │ │ │ │ ├── CoroutineRunner.cs │ │ │ │ │ │ ├── CoroutineRunner.cs.meta │ │ │ │ │ │ ├── FloatEqualityComparer.cs │ │ │ │ │ │ ├── FloatEqualityComparer.cs.meta │ │ │ │ │ │ ├── IOuterUnityTestAction.cs │ │ │ │ │ │ ├── IOuterUnityTestAction.cs.meta │ │ │ │ │ │ ├── IPostBuildCleanup.cs │ │ │ │ │ │ ├── IPostBuildCleanup.cs.meta │ │ │ │ │ │ ├── IPrebuildSceneSetup.cs │ │ │ │ │ │ ├── IPrebuildSceneSetup.cs.meta │ │ │ │ │ │ ├── MonoBehaviourTest/ │ │ │ │ │ │ │ ├── IMonoBehaviourTest.cs │ │ │ │ │ │ │ ├── IMonoBehaviourTest.cs.meta │ │ │ │ │ │ │ ├── MonoBehaviourTest.cs │ │ │ │ │ │ │ └── MonoBehaviourTest.cs.meta │ │ │ │ │ │ ├── MonoBehaviourTest.meta │ │ │ │ │ │ ├── PostBuildCleanupAttribute.cs │ │ │ │ │ │ ├── PostBuildCleanupAttribute.cs.meta │ │ │ │ │ │ ├── PrebuildSceneSetupAttribute.cs │ │ │ │ │ │ ├── PrebuildSceneSetupAttribute.cs.meta │ │ │ │ │ │ ├── QuaternionEqualityComparer.cs │ │ │ │ │ │ ├── QuaternionEqualityComparer.cs.meta │ │ │ │ │ │ ├── StacktraceFilter.cs │ │ │ │ │ │ ├── StacktraceFilter.cs.meta │ │ │ │ │ │ ├── Utils.cs │ │ │ │ │ │ ├── Utils.cs.meta │ │ │ │ │ │ ├── Vector2ComparerWithEqualsOperator.cs │ │ │ │ │ │ ├── Vector2ComparerWithEqualsOperator.cs.meta │ │ │ │ │ │ ├── Vector2EqualityComparer.cs │ │ │ │ │ │ ├── Vector2EqualityComparer.cs.meta │ │ │ │ │ │ ├── Vector3ComparerWithEqualsOperator.cs │ │ │ │ │ │ ├── Vector3ComparerWithEqualsOperator.cs.meta │ │ │ │ │ │ ├── Vector3EqualityComparer.cs │ │ │ │ │ │ ├── Vector3EqualityComparer.cs.meta │ │ │ │ │ │ ├── Vector4ComparerWithEqualsOperator.cs │ │ │ │ │ │ ├── Vector4ComparerWithEqualsOperator.cs.meta │ │ │ │ │ │ ├── Vector4EqualityComparer.cs │ │ │ │ │ │ └── Vector4EqualityComparer.cs.meta │ │ │ │ │ └── Utils.meta │ │ │ │ ├── UnityEngine.TestRunner.meta │ │ │ │ ├── package.json │ │ │ │ └── package.json.meta │ │ │ └── com.unity.textmeshpro@2.0.1/ │ │ │ ├── .gitlab-ci.yml │ │ │ ├── CHANGELOG.md │ │ │ ├── CHANGELOG.md.meta │ │ │ ├── Documentation~/ │ │ │ │ ├── TextMeshPro.md │ │ │ │ └── TextMeshPro.md.meta │ │ │ ├── Editor Resources/ │ │ │ │ ├── Gizmos/ │ │ │ │ │ ├── TMP - Dropdown Icon.psd │ │ │ │ │ ├── TMP - Dropdown Icon.psd.meta │ │ │ │ │ ├── TMP - Font Asset Icon.psd │ │ │ │ │ ├── TMP - Font Asset Icon.psd.meta │ │ │ │ │ ├── TMP - Input Field Icon.psd │ │ │ │ │ ├── TMP - Input Field Icon.psd.meta │ │ │ │ │ ├── TMP - Sprite Asset Icon.psd │ │ │ │ │ ├── TMP - Sprite Asset Icon.psd.meta │ │ │ │ │ ├── TMP - Text Component Icon.psd │ │ │ │ │ └── TMP - Text Component Icon.psd.meta │ │ │ │ ├── Gizmos.meta │ │ │ │ ├── Shaders/ │ │ │ │ │ ├── TMP_Properties.cginc │ │ │ │ │ ├── TMP_Properties.cginc.meta │ │ │ │ │ ├── TMP_SDF Internal SSD.shader │ │ │ │ │ └── TMP_SDF Internal SSD.shader.meta │ │ │ │ ├── Shaders.meta │ │ │ │ ├── Textures/ │ │ │ │ │ ├── SectionHeader_Dark.psd │ │ │ │ │ ├── SectionHeader_Dark.psd.meta │ │ │ │ │ ├── SectionHeader_Light.psd │ │ │ │ │ ├── SectionHeader_Light.psd.meta │ │ │ │ │ ├── btn_AlignBaseLine.psd │ │ │ │ │ ├── btn_AlignBaseLine.psd.meta │ │ │ │ │ ├── btn_AlignBaseLine_Light.psd │ │ │ │ │ ├── btn_AlignBaseLine_Light.psd.meta │ │ │ │ │ ├── btn_AlignBottom.psd │ │ │ │ │ ├── btn_AlignBottom.psd.meta │ │ │ │ │ ├── btn_AlignBottom_Light.psd │ │ │ │ │ ├── btn_AlignBottom_Light.psd.meta │ │ │ │ │ ├── btn_AlignCapLine.psd │ │ │ │ │ ├── btn_AlignCapLine.psd.meta │ │ │ │ │ ├── btn_AlignCapLine_Light.psd │ │ │ │ │ ├── btn_AlignCapLine_Light.psd.meta │ │ │ │ │ ├── btn_AlignCenter.psd │ │ │ │ │ ├── btn_AlignCenter.psd.meta │ │ │ │ │ ├── btn_AlignCenterGeo.psd │ │ │ │ │ ├── btn_AlignCenterGeo.psd.meta │ │ │ │ │ ├── btn_AlignCenterGeo_Light.psd │ │ │ │ │ ├── btn_AlignCenterGeo_Light.psd.meta │ │ │ │ │ ├── btn_AlignCenter_Light.psd │ │ │ │ │ ├── btn_AlignCenter_Light.psd.meta │ │ │ │ │ ├── btn_AlignFlush.psd │ │ │ │ │ ├── btn_AlignFlush.psd.meta │ │ │ │ │ ├── btn_AlignFlush_Light.psd │ │ │ │ │ ├── btn_AlignFlush_Light.psd.meta │ │ │ │ │ ├── btn_AlignJustified.psd │ │ │ │ │ ├── btn_AlignJustified.psd.meta │ │ │ │ │ ├── btn_AlignJustified_Light.psd │ │ │ │ │ ├── btn_AlignJustified_Light.psd.meta │ │ │ │ │ ├── btn_AlignLeft.psd │ │ │ │ │ ├── btn_AlignLeft.psd.meta │ │ │ │ │ ├── btn_AlignLeft_Light.psd │ │ │ │ │ ├── btn_AlignLeft_Light.psd.meta │ │ │ │ │ ├── btn_AlignMidLine.psd │ │ │ │ │ ├── btn_AlignMidLine.psd.meta │ │ │ │ │ ├── btn_AlignMiddle.psd │ │ │ │ │ ├── btn_AlignMiddle.psd.meta │ │ │ │ │ ├── btn_AlignMiddle_Light.psd │ │ │ │ │ ├── btn_AlignMiddle_Light.psd.meta │ │ │ │ │ ├── btn_AlignMidline_Light.psd │ │ │ │ │ ├── btn_AlignMidline_Light.psd.meta │ │ │ │ │ ├── btn_AlignRight.psd │ │ │ │ │ ├── btn_AlignRight.psd.meta │ │ │ │ │ ├── btn_AlignRight_Light.psd │ │ │ │ │ ├── btn_AlignRight_Light.psd.meta │ │ │ │ │ ├── btn_AlignTop.psd │ │ │ │ │ ├── btn_AlignTop.psd.meta │ │ │ │ │ ├── btn_AlignTop_Light.psd │ │ │ │ │ └── btn_AlignTop_Light.psd.meta │ │ │ │ └── Textures.meta │ │ │ ├── Editor Resources.meta │ │ │ ├── LICENSE.md │ │ │ ├── LICENSE.md.meta │ │ │ ├── Package Resources/ │ │ │ │ ├── TMP Essential Resources.unitypackage │ │ │ │ ├── TMP Essential Resources.unitypackage.meta │ │ │ │ ├── TMP Examples & Extras.unitypackage │ │ │ │ └── TMP Examples & Extras.unitypackage.meta │ │ │ ├── Package Resources.meta │ │ │ ├── PackageConversionData.json │ │ │ ├── PackageConversionData.json.meta │ │ │ ├── PackageConversionData_Assets.json │ │ │ ├── PackageConversionData_Assets.json.meta │ │ │ ├── Scripts/ │ │ │ │ ├── Editor/ │ │ │ │ │ ├── DropdownOptionListDrawer.cs │ │ │ │ │ ├── DropdownOptionListDrawer.cs.meta │ │ │ │ │ ├── GlyphInfoDrawer.cs │ │ │ │ │ ├── GlyphInfoDrawer.cs.meta │ │ │ │ │ ├── GlyphMetricsPropertyDrawer.cs │ │ │ │ │ ├── GlyphMetricsPropertyDrawer.cs.meta │ │ │ │ │ ├── GlyphRectPropertyDrawer.cs │ │ │ │ │ ├── GlyphRectPropertyDrawer.cs.meta │ │ │ │ │ ├── TMP_BaseEditorPanel.cs │ │ │ │ │ ├── TMP_BaseEditorPanel.cs.meta │ │ │ │ │ ├── TMP_BaseShaderGUI.cs │ │ │ │ │ ├── TMP_BaseShaderGUI.cs.meta │ │ │ │ │ ├── TMP_BitmapShaderGUI.cs │ │ │ │ │ ├── TMP_BitmapShaderGUI.cs.meta │ │ │ │ │ ├── TMP_CharacterPropertyDrawer.cs │ │ │ │ │ ├── TMP_CharacterPropertyDrawer.cs.meta │ │ │ │ │ ├── TMP_ColorGradientAssetMenu.cs │ │ │ │ │ ├── TMP_ColorGradientAssetMenu.cs.meta │ │ │ │ │ ├── TMP_ColorGradientEditor.cs │ │ │ │ │ ├── TMP_ColorGradientEditor.cs.meta │ │ │ │ │ ├── TMP_DropdownEditor.cs │ │ │ │ │ ├── TMP_DropdownEditor.cs.meta │ │ │ │ │ ├── TMP_EditorCoroutine.cs │ │ │ │ │ ├── TMP_EditorCoroutine.cs.meta │ │ │ │ │ ├── TMP_EditorPanel.cs │ │ │ │ │ ├── TMP_EditorPanel.cs.meta │ │ │ │ │ ├── TMP_EditorUtility.cs │ │ │ │ │ ├── TMP_EditorUtility.cs.meta │ │ │ │ │ ├── TMP_FontAssetEditor.cs │ │ │ │ │ ├── TMP_FontAssetEditor.cs.meta │ │ │ │ │ ├── TMP_FontAsset_CreationMenu.cs │ │ │ │ │ ├── TMP_FontAsset_CreationMenu.cs.meta │ │ │ │ │ ├── TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs │ │ │ │ │ ├── TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs.meta │ │ │ │ │ ├── TMP_GlyphPropertyDrawer.cs │ │ │ │ │ ├── TMP_GlyphPropertyDrawer.cs.meta │ │ │ │ │ ├── TMP_InputFieldEditor.cs │ │ │ │ │ ├── TMP_InputFieldEditor.cs.meta │ │ │ │ │ ├── TMP_MeshRendererEditor.cs │ │ │ │ │ ├── TMP_MeshRendererEditor.cs.meta │ │ │ │ │ ├── TMP_PackageUtilities.cs │ │ │ │ │ ├── TMP_PackageUtilities.cs.meta │ │ │ │ │ ├── TMP_PostBuildProcessHandler.cs │ │ │ │ │ ├── TMP_PostBuildProcessHandler.cs.meta │ │ │ │ │ ├── TMP_ProjectTextSettings.cs │ │ │ │ │ ├── TMP_ProjectTextSettings.cs.meta │ │ │ │ │ ├── TMP_ResourcesLoader.cs │ │ │ │ │ ├── TMP_ResourcesLoader.cs.meta │ │ │ │ │ ├── TMP_SDFShaderGUI.cs │ │ │ │ │ ├── TMP_SDFShaderGUI.cs.meta │ │ │ │ │ ├── TMP_SerializedPropertyHolder.cs │ │ │ │ │ ├── TMP_SerializedPropertyHolder.cs.meta │ │ │ │ │ ├── TMP_SettingsEditor.cs │ │ │ │ │ ├── TMP_SettingsEditor.cs.meta │ │ │ │ │ ├── TMP_SpriteAssetEditor.cs │ │ │ │ │ ├── TMP_SpriteAssetEditor.cs.meta │ │ │ │ │ ├── TMP_SpriteAssetImporter.cs │ │ │ │ │ ├── TMP_SpriteAssetImporter.cs.meta │ │ │ │ │ ├── TMP_SpriteAssetMenu.cs │ │ │ │ │ ├── TMP_SpriteAssetMenu.cs.meta │ │ │ │ │ ├── TMP_SpriteCharacterPropertyDrawer.cs │ │ │ │ │ ├── TMP_SpriteCharacterPropertyDrawer.cs.meta │ │ │ │ │ ├── TMP_SpriteGlyphPropertyDrawer.cs │ │ │ │ │ ├── TMP_SpriteGlyphPropertyDrawer.cs.meta │ │ │ │ │ ├── TMP_StyleAssetMenu.cs │ │ │ │ │ ├── TMP_StyleAssetMenu.cs.meta │ │ │ │ │ ├── TMP_StyleSheetEditor.cs │ │ │ │ │ ├── TMP_StyleSheetEditor.cs.meta │ │ │ │ │ ├── TMP_SubMeshUI_Editor.cs │ │ │ │ │ ├── TMP_SubMeshUI_Editor.cs.meta │ │ │ │ │ ├── TMP_SubMesh_Editor.cs │ │ │ │ │ ├── TMP_SubMesh_Editor.cs.meta │ │ │ │ │ ├── TMP_TextAlignmentDrawer.cs │ │ │ │ │ ├── TMP_TextAlignmentDrawer.cs.meta │ │ │ │ │ ├── TMP_UIStyleManager.cs │ │ │ │ │ ├── TMP_UIStyleManager.cs.meta │ │ │ │ │ ├── TMP_UiEditorPanel.cs │ │ │ │ │ ├── TMP_UiEditorPanel.cs.meta │ │ │ │ │ ├── TMPro_ContextMenus.cs │ │ │ │ │ ├── TMPro_ContextMenus.cs.meta │ │ │ │ │ ├── TMPro_CreateObjectMenu.cs │ │ │ │ │ ├── TMPro_CreateObjectMenu.cs.meta │ │ │ │ │ ├── TMPro_EditorShaderUtilities.cs │ │ │ │ │ ├── TMPro_EditorShaderUtilities.cs.meta │ │ │ │ │ ├── TMPro_FontAssetCreatorWindow.cs │ │ │ │ │ ├── TMPro_FontAssetCreatorWindow.cs.meta │ │ │ │ │ ├── TMPro_FontPlugin.cs │ │ │ │ │ ├── TMPro_FontPlugin.cs.meta │ │ │ │ │ ├── TMPro_SortingLayerHelper.cs │ │ │ │ │ ├── TMPro_SortingLayerHelper.cs.meta │ │ │ │ │ ├── TMPro_TextContainerEditor.cs │ │ │ │ │ ├── TMPro_TextContainerEditor.cs.meta │ │ │ │ │ ├── TMPro_TexturePostProcessor.cs │ │ │ │ │ ├── TMPro_TexturePostProcessor.cs.meta │ │ │ │ │ ├── Unity.TextMeshPro.Editor.asmdef │ │ │ │ │ └── Unity.TextMeshPro.Editor.asmdef.meta │ │ │ │ ├── Editor.meta │ │ │ │ ├── Runtime/ │ │ │ │ │ ├── AssemblyInfo.cs.cs │ │ │ │ │ ├── AssemblyInfo.cs.cs.meta │ │ │ │ │ ├── FastAction.cs │ │ │ │ │ ├── FastAction.cs.meta │ │ │ │ │ ├── MaterialReferenceManager.cs │ │ │ │ │ ├── MaterialReferenceManager.cs.meta │ │ │ │ │ ├── TMP_Asset.cs │ │ │ │ │ ├── TMP_Asset.cs.meta │ │ │ │ │ ├── TMP_Character.cs │ │ │ │ │ ├── TMP_Character.cs.meta │ │ │ │ │ ├── TMP_CharacterInfo.cs │ │ │ │ │ ├── TMP_CharacterInfo.cs.meta │ │ │ │ │ ├── TMP_ColorGradient.cs │ │ │ │ │ ├── TMP_ColorGradient.cs.meta │ │ │ │ │ ├── TMP_CoroutineTween.cs │ │ │ │ │ ├── TMP_CoroutineTween.cs.meta │ │ │ │ │ ├── TMP_DefaultControls.cs │ │ │ │ │ ├── TMP_DefaultControls.cs.meta │ │ │ │ │ ├── TMP_Dropdown.cs │ │ │ │ │ ├── TMP_Dropdown.cs.meta │ │ │ │ │ ├── TMP_EditorResourceManager.cs │ │ │ │ │ ├── TMP_EditorResourceManager.cs.meta │ │ │ │ │ ├── TMP_FontAsset.cs │ │ │ │ │ ├── TMP_FontAsset.cs.meta │ │ │ │ │ ├── TMP_FontAssetCommon.cs │ │ │ │ │ ├── TMP_FontAssetCommon.cs.meta │ │ │ │ │ ├── TMP_FontAssetUtilities.cs │ │ │ │ │ ├── TMP_FontAssetUtilities.cs.meta │ │ │ │ │ ├── TMP_FontFeatureTable.cs │ │ │ │ │ ├── TMP_FontFeatureTable.cs.meta │ │ │ │ │ ├── TMP_FontFeaturesCommon.cs │ │ │ │ │ ├── TMP_FontFeaturesCommon.cs.meta │ │ │ │ │ ├── TMP_InputField.cs │ │ │ │ │ ├── TMP_InputField.cs.meta │ │ │ │ │ ├── TMP_InputValidator.cs │ │ │ │ │ ├── TMP_InputValidator.cs.meta │ │ │ │ │ ├── TMP_LineInfo.cs │ │ │ │ │ ├── TMP_LineInfo.cs.meta │ │ │ │ │ ├── TMP_ListPool.cs │ │ │ │ │ ├── TMP_ListPool.cs.meta │ │ │ │ │ ├── TMP_MaterialManager.cs │ │ │ │ │ ├── TMP_MaterialManager.cs.meta │ │ │ │ │ ├── TMP_MeshInfo.cs │ │ │ │ │ ├── TMP_MeshInfo.cs.meta │ │ │ │ │ ├── TMP_ObjectPool.cs │ │ │ │ │ ├── TMP_ObjectPool.cs.meta │ │ │ │ │ ├── TMP_PackageResourceImporter.cs │ │ │ │ │ ├── TMP_PackageResourceImporter.cs.meta │ │ │ │ │ ├── TMP_RichTextTagStack.cs │ │ │ │ │ ├── TMP_RichTextTagStack.cs.meta │ │ │ │ │ ├── TMP_RichTextTagsCommon.cs │ │ │ │ │ ├── TMP_RichTextTagsCommon.cs.meta │ │ │ │ │ ├── TMP_ScrollbarEventHandler.cs │ │ │ │ │ ├── TMP_ScrollbarEventHandler.cs.meta │ │ │ │ │ ├── TMP_SelectionCaret.cs │ │ │ │ │ ├── TMP_SelectionCaret.cs.meta │ │ │ │ │ ├── TMP_Settings.cs │ │ │ │ │ ├── TMP_Settings.cs.meta │ │ │ │ │ ├── TMP_ShaderUtilities.cs │ │ │ │ │ ├── TMP_ShaderUtilities.cs.meta │ │ │ │ │ ├── TMP_Sprite.cs │ │ │ │ │ ├── TMP_Sprite.cs.meta │ │ │ │ │ ├── TMP_SpriteAnimator.cs │ │ │ │ │ ├── TMP_SpriteAnimator.cs.meta │ │ │ │ │ ├── TMP_SpriteAsset.cs │ │ │ │ │ ├── TMP_SpriteAsset.cs.meta │ │ │ │ │ ├── TMP_SpriteAssetImportFormats.cs │ │ │ │ │ ├── TMP_SpriteAssetImportFormats.cs.meta │ │ │ │ │ ├── TMP_SpriteCharacter.cs │ │ │ │ │ ├── TMP_SpriteCharacter.cs.meta │ │ │ │ │ ├── TMP_SpriteGlyph.cs │ │ │ │ │ ├── TMP_SpriteGlyph.cs.meta │ │ │ │ │ ├── TMP_Style.cs │ │ │ │ │ ├── TMP_Style.cs.meta │ │ │ │ │ ├── TMP_StyleSheet.cs │ │ │ │ │ ├── TMP_StyleSheet.cs.meta │ │ │ │ │ ├── TMP_SubMesh.cs │ │ │ │ │ ├── TMP_SubMesh.cs.meta │ │ │ │ │ ├── TMP_SubMeshUI.cs │ │ │ │ │ ├── TMP_SubMeshUI.cs.meta │ │ │ │ │ ├── TMP_Text.cs │ │ │ │ │ ├── TMP_Text.cs.meta │ │ │ │ │ ├── TMP_TextElement.cs │ │ │ │ │ ├── TMP_TextElement.cs.meta │ │ │ │ │ ├── TMP_TextElement_Legacy.cs │ │ │ │ │ ├── TMP_TextElement_Legacy.cs.meta │ │ │ │ │ ├── TMP_TextInfo.cs │ │ │ │ │ ├── TMP_TextInfo.cs.meta │ │ │ │ │ ├── TMP_TextParsingUtilities.cs │ │ │ │ │ ├── TMP_TextParsingUtilities.cs.meta │ │ │ │ │ ├── TMP_TextUtilities.cs │ │ │ │ │ ├── TMP_TextUtilities.cs.meta │ │ │ │ │ ├── TMP_UpdateManager.cs │ │ │ │ │ ├── TMP_UpdateManager.cs.meta │ │ │ │ │ ├── TMP_UpdateRegistery.cs │ │ │ │ │ ├── TMP_UpdateRegistery.cs.meta │ │ │ │ │ ├── TMPro_EventManager.cs │ │ │ │ │ ├── TMPro_EventManager.cs.meta │ │ │ │ │ ├── TMPro_ExtensionMethods.cs │ │ │ │ │ ├── TMPro_ExtensionMethods.cs.meta │ │ │ │ │ ├── TMPro_MeshUtilities.cs │ │ │ │ │ ├── TMPro_MeshUtilities.cs.meta │ │ │ │ │ ├── TMPro_Private.cs │ │ │ │ │ ├── TMPro_Private.cs.meta │ │ │ │ │ ├── TMPro_UGUI_Private.cs │ │ │ │ │ ├── TMPro_UGUI_Private.cs.meta │ │ │ │ │ ├── TextContainer.cs │ │ │ │ │ ├── TextContainer.cs.meta │ │ │ │ │ ├── TextMeshPro.cs │ │ │ │ │ ├── TextMeshPro.cs.meta │ │ │ │ │ ├── TextMeshProUGUI.cs │ │ │ │ │ ├── TextMeshProUGUI.cs.meta │ │ │ │ │ ├── Unity.TextMeshPro.asmdef │ │ │ │ │ └── Unity.TextMeshPro.asmdef.meta │ │ │ │ └── Runtime.meta │ │ │ ├── Scripts.meta │ │ │ ├── Tests/ │ │ │ │ ├── Editor/ │ │ │ │ │ ├── TMP_EditorTests.cs │ │ │ │ │ ├── TMP_EditorTests.cs.meta │ │ │ │ │ ├── Unity.TextMeshPro.Editor.Tests.asmdef │ │ │ │ │ └── Unity.TextMeshPro.Editor.Tests.asmdef.meta │ │ │ │ ├── Editor.meta │ │ │ │ ├── Runtime/ │ │ │ │ │ ├── TMP_RuntimeTests.cs │ │ │ │ │ ├── TMP_RuntimeTests.cs.meta │ │ │ │ │ ├── Unity.TextMeshPro.Tests.asmdef │ │ │ │ │ └── Unity.TextMeshPro.Tests.asmdef.meta │ │ │ │ └── Runtime.meta │ │ │ ├── Tests.meta │ │ │ ├── package.json │ │ │ └── package.json.meta │ │ ├── ProjectSettings.asset │ │ ├── SceneVisibilityState.asset │ │ ├── ScriptAssemblies/ │ │ │ ├── Assembly-CSharp-Editor.pdb │ │ │ ├── Assembly-CSharp.pdb │ │ │ ├── BuiltinAssemblies.stamp │ │ │ ├── Unity.CollabProxy.Editor.pdb │ │ │ ├── Unity.Rider.Editor.pdb │ │ │ ├── Unity.TextMeshPro.Editor.pdb │ │ │ ├── Unity.TextMeshPro.pdb │ │ │ ├── Unity.Timeline.Editor.pdb │ │ │ ├── Unity.Timeline.pdb │ │ │ ├── Unity.VSCode.Editor.pdb │ │ │ ├── UnityEditor.TestRunner.pdb │ │ │ ├── UnityEditor.UI.pdb │ │ │ ├── UnityEngine.TestRunner.pdb │ │ │ └── UnityEngine.UI.pdb │ │ ├── ScriptMapper │ │ ├── SpriteAtlasDatabase.asset │ │ ├── StateCache/ │ │ │ ├── Hierarchy/ │ │ │ │ └── d2da7c-mainStage.json │ │ │ ├── LayerSettings/ │ │ │ │ └── LayerSettings.json │ │ │ └── SceneView/ │ │ │ └── e16c04-mainStage.json │ │ ├── Style.catalog │ │ ├── assetDatabase3 │ │ ├── expandedItems │ │ ├── metadata/ │ │ │ ├── 00/ │ │ │ │ ├── 00000000000000001000000000000000 │ │ │ │ ├── 00000000000000001000000000000000.info │ │ │ │ ├── 00000000000000002000000000000000 │ │ │ │ ├── 00000000000000002000000000000000.info │ │ │ │ ├── 00000000000000003000000000000000 │ │ │ │ ├── 00000000000000003000000000000000.info │ │ │ │ ├── 00000000000000004000000000000000 │ │ │ │ ├── 00000000000000004000000000000000.info │ │ │ │ ├── 00000000000000004100000000000000 │ │ │ │ ├── 00000000000000004100000000000000.info │ │ │ │ ├── 00000000000000005000000000000000 │ │ │ │ ├── 00000000000000005000000000000000.info │ │ │ │ ├── 00000000000000005100000000000000 │ │ │ │ ├── 00000000000000005100000000000000.info │ │ │ │ ├── 00000000000000006000000000000000 │ │ │ │ ├── 00000000000000006000000000000000.info │ │ │ │ ├── 00000000000000006100000000000000 │ │ │ │ ├── 00000000000000006100000000000000.info │ │ │ │ ├── 00000000000000007000000000000000 │ │ │ │ ├── 00000000000000007000000000000000.info │ │ │ │ ├── 00000000000000007100000000000000 │ │ │ │ ├── 00000000000000007100000000000000.info │ │ │ │ ├── 00000000000000008000000000000000 │ │ │ │ ├── 00000000000000008000000000000000.info │ │ │ │ ├── 00000000000000009000000000000000 │ │ │ │ ├── 00000000000000009000000000000000.info │ │ │ │ ├── 0000000000000000a100000000000000 │ │ │ │ ├── 0000000000000000a100000000000000.info │ │ │ │ ├── 0000000000000000b000000000000000 │ │ │ │ ├── 0000000000000000b000000000000000.info │ │ │ │ ├── 0000000000000000b100000000000000 │ │ │ │ ├── 0000000000000000b100000000000000.info │ │ │ │ ├── 0000000000000000c000000000000000 │ │ │ │ ├── 0000000000000000c000000000000000.info │ │ │ │ ├── 0000000000000000c100000000000000 │ │ │ │ ├── 0000000000000000c100000000000000.info │ │ │ │ ├── 00187582b67e7654b914b5a0d37daafb │ │ │ │ ├── 00187582b67e7654b914b5a0d37daafb.info │ │ │ │ ├── 006633c8a6f4ae94aa9babf72234e1a2 │ │ │ │ ├── 006633c8a6f4ae94aa9babf72234e1a2.info │ │ │ │ ├── 00f9a68859b850648902e0c98c25b590 │ │ │ │ └── 00f9a68859b850648902e0c98c25b590.info │ │ │ ├── 01/ │ │ │ │ ├── 01ada73c4792aba4c937ff5d92cce866 │ │ │ │ ├── 01ada73c4792aba4c937ff5d92cce866.info │ │ │ │ ├── 01cd96d8687272f4898cfd1562079dd7 │ │ │ │ ├── 01cd96d8687272f4898cfd1562079dd7.info │ │ │ │ ├── 01df650e1b86e9f4a8e2b5dc9782506f │ │ │ │ └── 01df650e1b86e9f4a8e2b5dc9782506f.info │ │ │ ├── 02/ │ │ │ │ ├── 020ee4c1798a3d243a4b8cbfee6cac2d │ │ │ │ ├── 020ee4c1798a3d243a4b8cbfee6cac2d.info │ │ │ │ ├── 0217a80286f79419daa202f69409f19b │ │ │ │ ├── 0217a80286f79419daa202f69409f19b.info │ │ │ │ ├── 0232a25926bfdf945abd3ccb4519aac3 │ │ │ │ ├── 0232a25926bfdf945abd3ccb4519aac3.info │ │ │ │ ├── 02893ffb522b490a9fa28eedd2584309 │ │ │ │ ├── 02893ffb522b490a9fa28eedd2584309.info │ │ │ │ ├── 02e1fe0a338b35545a5fed1345848332 │ │ │ │ ├── 02e1fe0a338b35545a5fed1345848332.info │ │ │ │ ├── 02e622e7baa59ac449d2c5f5bc992795 │ │ │ │ ├── 02e622e7baa59ac449d2c5f5bc992795.info │ │ │ │ ├── 02f771204943f4a40949438e873e3eff │ │ │ │ └── 02f771204943f4a40949438e873e3eff.info │ │ │ ├── 03/ │ │ │ │ ├── 030f85c3f73729f4f976f66ffb23b875 │ │ │ │ ├── 030f85c3f73729f4f976f66ffb23b875.info │ │ │ │ ├── 0336a32a79bfaed43a3fd2d88b91e974 │ │ │ │ ├── 0336a32a79bfaed43a3fd2d88b91e974.info │ │ │ │ ├── 033c884ba52437d49bc55935939ef1c6 │ │ │ │ ├── 033c884ba52437d49bc55935939ef1c6.info │ │ │ │ ├── 0386b6eb838c47138cd51d1c1b879a35 │ │ │ │ ├── 0386b6eb838c47138cd51d1c1b879a35.info │ │ │ │ ├── 03e4d63665d06f04c8a6cf68133c1592 │ │ │ │ └── 03e4d63665d06f04c8a6cf68133c1592.info │ │ │ ├── 04/ │ │ │ │ ├── 046c3854296c5ec48bac50da6ca248ec │ │ │ │ ├── 046c3854296c5ec48bac50da6ca248ec.info │ │ │ │ ├── 04cc958f40f350044a432c012f320305 │ │ │ │ └── 04cc958f40f350044a432c012f320305.info │ │ │ ├── 05/ │ │ │ │ ├── 056819c66570ca54cadb72330a354050 │ │ │ │ ├── 056819c66570ca54cadb72330a354050.info │ │ │ │ ├── 05778dd1de4433d418793b6f3d3c18cf │ │ │ │ ├── 05778dd1de4433d418793b6f3d3c18cf.info │ │ │ │ ├── 058cba836c1846c3aa1c5fd2e28aea77 │ │ │ │ ├── 058cba836c1846c3aa1c5fd2e28aea77.info │ │ │ │ ├── 05f582d4fbc8e0c40afccb76bbbe0935 │ │ │ │ ├── 05f582d4fbc8e0c40afccb76bbbe0935.info │ │ │ │ ├── 05f5bfd584002f948982a1498890f9a9 │ │ │ │ ├── 05f5bfd584002f948982a1498890f9a9.info │ │ │ │ ├── 05f7f519769978b79b31d063a7fc6fa1 │ │ │ │ ├── 05f7f519769978b79b31d063a7fc6fa1.info │ │ │ │ ├── 05f92e4a2414cb144a92157752dfa324 │ │ │ │ └── 05f92e4a2414cb144a92157752dfa324.info │ │ │ ├── 06/ │ │ │ │ ├── 066619c9c9c84f89acb1b48c11a7efe2 │ │ │ │ ├── 066619c9c9c84f89acb1b48c11a7efe2.info │ │ │ │ ├── 06ae1baf5524b314fa65b173b9eca869 │ │ │ │ ├── 06ae1baf5524b314fa65b173b9eca869.info │ │ │ │ ├── 06bfdc59aae5325499d5beef3aa3d013 │ │ │ │ └── 06bfdc59aae5325499d5beef3aa3d013.info │ │ │ ├── 07/ │ │ │ │ ├── 071c17858dc6c47ada7b2a1f1ded5402 │ │ │ │ ├── 071c17858dc6c47ada7b2a1f1ded5402.info │ │ │ │ ├── 077690d334440b044bdd51b26b3e9413 │ │ │ │ ├── 077690d334440b044bdd51b26b3e9413.info │ │ │ │ ├── 07994bfe8b0e4adb97d706de5dea48d5 │ │ │ │ ├── 07994bfe8b0e4adb97d706de5dea48d5.info │ │ │ │ ├── 07a967d2fca95324f8922df8394a5655 │ │ │ │ ├── 07a967d2fca95324f8922df8394a5655.info │ │ │ │ ├── 07ea0326ed848fb4489187cb58f96113 │ │ │ │ └── 07ea0326ed848fb4489187cb58f96113.info │ │ │ ├── 08/ │ │ │ │ ├── 083c6a3a5426382449369ddc12b691d8 │ │ │ │ ├── 083c6a3a5426382449369ddc12b691d8.info │ │ │ │ ├── 087cba9fa6ac867479a0b0fdc0a5864b │ │ │ │ ├── 087cba9fa6ac867479a0b0fdc0a5864b.info │ │ │ │ ├── 08d23c0b73905c148b525c3c93fff580 │ │ │ │ ├── 08d23c0b73905c148b525c3c93fff580.info │ │ │ │ ├── 08e9894bdf0834710b22d3c0aa245ac0 │ │ │ │ └── 08e9894bdf0834710b22d3c0aa245ac0.info │ │ │ ├── 09/ │ │ │ │ ├── 09e28640d754a611467eebfb261ed749 │ │ │ │ ├── 09e28640d754a611467eebfb261ed749.info │ │ │ │ ├── 09e68d8a529a36340b752b99a1b70f83 │ │ │ │ ├── 09e68d8a529a36340b752b99a1b70f83.info │ │ │ │ ├── 09f4db536a377bc40a9ac110af702bfa │ │ │ │ └── 09f4db536a377bc40a9ac110af702bfa.info │ │ │ ├── 0a/ │ │ │ │ ├── 0a017569bfe174e4890797b4d64cbabc │ │ │ │ ├── 0a017569bfe174e4890797b4d64cbabc.info │ │ │ │ ├── 0aaa057ce5566e940b18a0ccd0344693 │ │ │ │ ├── 0aaa057ce5566e940b18a0ccd0344693.info │ │ │ │ ├── 0acc523941302664db1f4e527237feb3 │ │ │ │ └── 0acc523941302664db1f4e527237feb3.info │ │ │ ├── 0b/ │ │ │ │ ├── 0b2706df6fdff50448f84a3f6629b40f │ │ │ │ ├── 0b2706df6fdff50448f84a3f6629b40f.info │ │ │ │ ├── 0bb74b1c097396c49b1691e6a938f814 │ │ │ │ └── 0bb74b1c097396c49b1691e6a938f814.info │ │ │ ├── 0c/ │ │ │ │ ├── 0c04c8cb23b78e04492e0f310cdee93e │ │ │ │ ├── 0c04c8cb23b78e04492e0f310cdee93e.info │ │ │ │ ├── 0c56471f08a0f6846afc792f0b4205b9 │ │ │ │ ├── 0c56471f08a0f6846afc792f0b4205b9.info │ │ │ │ ├── 0ca2545d76d1fb34fa45a9f1e432d259 │ │ │ │ ├── 0ca2545d76d1fb34fa45a9f1e432d259.info │ │ │ │ ├── 0ca81982e37e893498abf804c12a22c7 │ │ │ │ ├── 0ca81982e37e893498abf804c12a22c7.info │ │ │ │ ├── 0cb14878543cf3d4f8472b15f7ecf0e3 │ │ │ │ ├── 0cb14878543cf3d4f8472b15f7ecf0e3.info │ │ │ │ ├── 0cd44c1031e13a943bb63640046fad76 │ │ │ │ └── 0cd44c1031e13a943bb63640046fad76.info │ │ │ ├── 0d/ │ │ │ │ ├── 0d0b652f32a2cc243917e4028fa0f046 │ │ │ │ ├── 0d0b652f32a2cc243917e4028fa0f046.info │ │ │ │ ├── 0d2d0f36e67d4518a07df76235e91f9a │ │ │ │ ├── 0d2d0f36e67d4518a07df76235e91f9a.info │ │ │ │ ├── 0d4fc309a0784294c8ab658b53b12320 │ │ │ │ ├── 0d4fc309a0784294c8ab658b53b12320.info │ │ │ │ ├── 0d60a406ab64c434e9d731914e11a51e │ │ │ │ ├── 0d60a406ab64c434e9d731914e11a51e.info │ │ │ │ ├── 0d9a36012a224080966c7b55896aa0f9 │ │ │ │ ├── 0d9a36012a224080966c7b55896aa0f9.info │ │ │ │ ├── 0dc62a5955cf04ec298a2c3ca4b2edf2 │ │ │ │ ├── 0dc62a5955cf04ec298a2c3ca4b2edf2.info │ │ │ │ ├── 0de03ebd74e2b474fa23d05ab42d0cd8 │ │ │ │ └── 0de03ebd74e2b474fa23d05ab42d0cd8.info │ │ │ ├── 0e/ │ │ │ │ ├── 0e0afa652c0031c48896a97b424d027b │ │ │ │ ├── 0e0afa652c0031c48896a97b424d027b.info │ │ │ │ ├── 0e751e877ed14d71a6b8e63ac54949cf │ │ │ │ ├── 0e751e877ed14d71a6b8e63ac54949cf.info │ │ │ │ ├── 0efb23ecb373b6d4bbe5217485785138 │ │ │ │ └── 0efb23ecb373b6d4bbe5217485785138.info │ │ │ ├── 0f/ │ │ │ │ ├── 0f71aeefaa877ae4787e8356f25ad1e5 │ │ │ │ └── 0f71aeefaa877ae4787e8356f25ad1e5.info │ │ │ ├── 10/ │ │ │ │ ├── 102e512f651ee834f951a2516c1ea3b8 │ │ │ │ ├── 102e512f651ee834f951a2516c1ea3b8.info │ │ │ │ ├── 1048a87135154606808bf2030da32d18 │ │ │ │ ├── 1048a87135154606808bf2030da32d18.info │ │ │ │ ├── 105515c1653548242b4fe973c0f375f7 │ │ │ │ ├── 105515c1653548242b4fe973c0f375f7.info │ │ │ │ ├── 1091bc2ad06e3234aac2b2fa2841c09d │ │ │ │ ├── 1091bc2ad06e3234aac2b2fa2841c09d.info │ │ │ │ ├── 10ba9bc9317e315439b0223674162c52 │ │ │ │ └── 10ba9bc9317e315439b0223674162c52.info │ │ │ ├── 11/ │ │ │ │ ├── 110d5035a36a6a34580fb65bb40cd78f │ │ │ │ ├── 110d5035a36a6a34580fb65bb40cd78f.info │ │ │ │ ├── 1158e311a3101950348dcecb1bebc42d │ │ │ │ ├── 1158e311a3101950348dcecb1bebc42d.info │ │ │ │ ├── 11a6a034ab84493cbed6af5ae7aae78b │ │ │ │ └── 11a6a034ab84493cbed6af5ae7aae78b.info │ │ │ ├── 12/ │ │ │ │ ├── 124533853216377448d786fd7c725701 │ │ │ │ ├── 124533853216377448d786fd7c725701.info │ │ │ │ ├── 127023922adddf744b59fa7b0b0c3030 │ │ │ │ ├── 127023922adddf744b59fa7b0b0c3030.info │ │ │ │ ├── 12736c98af174f91827a26b66d2b01b9 │ │ │ │ ├── 12736c98af174f91827a26b66d2b01b9.info │ │ │ │ ├── 12c42068351bb084abde965d725b9887 │ │ │ │ ├── 12c42068351bb084abde965d725b9887.info │ │ │ │ ├── 12dfd4bdbb5c8e6419432fbc54ef25d9 │ │ │ │ └── 12dfd4bdbb5c8e6419432fbc54ef25d9.info │ │ │ ├── 13/ │ │ │ │ ├── 1336690ece4db2740b4ba38873e00dfb │ │ │ │ ├── 1336690ece4db2740b4ba38873e00dfb.info │ │ │ │ ├── 1344c3c82d62a2a41a3576d8abb8e3ea │ │ │ │ ├── 1344c3c82d62a2a41a3576d8abb8e3ea.info │ │ │ │ ├── 1369382d2c5e64dc5b2ec0b6b0a94531 │ │ │ │ ├── 1369382d2c5e64dc5b2ec0b6b0a94531.info │ │ │ │ ├── 1385bc74f3945c943be16ecbb1381063 │ │ │ │ ├── 1385bc74f3945c943be16ecbb1381063.info │ │ │ │ ├── 1389c6be1c6e80b4eb8604aabdda8255 │ │ │ │ ├── 1389c6be1c6e80b4eb8604aabdda8255.info │ │ │ │ ├── 138dbec4f8742654fbceb0a19d68b9c5 │ │ │ │ ├── 138dbec4f8742654fbceb0a19d68b9c5.info │ │ │ │ ├── 139c5eac101a4dc4fb3098e30c29f15e │ │ │ │ ├── 139c5eac101a4dc4fb3098e30c29f15e.info │ │ │ │ ├── 13a9c1b4df2e489e8eb9cacca7429596 │ │ │ │ ├── 13a9c1b4df2e489e8eb9cacca7429596.info │ │ │ │ ├── 13cd966480ec3354bb318ee1aeccff6f │ │ │ │ ├── 13cd966480ec3354bb318ee1aeccff6f.info │ │ │ │ ├── 13d161b14bb3ab74e8a9634e26fb7a5e │ │ │ │ ├── 13d161b14bb3ab74e8a9634e26fb7a5e.info │ │ │ │ ├── 13eb80ce50ac9c43cdbaf2109c0ec7db │ │ │ │ └── 13eb80ce50ac9c43cdbaf2109c0ec7db.info │ │ │ ├── 14/ │ │ │ │ ├── 14427eecd0bccea468addc3492aaef57 │ │ │ │ ├── 14427eecd0bccea468addc3492aaef57.info │ │ │ │ ├── 1489c7cdbe26c444b86705280ebdff02 │ │ │ │ ├── 1489c7cdbe26c444b86705280ebdff02.info │ │ │ │ ├── 14d748c963c7b3549bed45457cc92c4f │ │ │ │ └── 14d748c963c7b3549bed45457cc92c4f.info │ │ │ ├── 15/ │ │ │ │ ├── 1511ccae7919cfc46b603b9b337fdc94 │ │ │ │ ├── 1511ccae7919cfc46b603b9b337fdc94.info │ │ │ │ ├── 15225778e2107e44bb700adf9df97a60 │ │ │ │ ├── 15225778e2107e44bb700adf9df97a60.info │ │ │ │ ├── 15c38f6fa1940124db1ab7f6fe7268d1 │ │ │ │ ├── 15c38f6fa1940124db1ab7f6fe7268d1.info │ │ │ │ ├── 15e0374501f39d54eb30235764636e0e │ │ │ │ ├── 15e0374501f39d54eb30235764636e0e.info │ │ │ │ ├── 15f870c6975ad6449b5b52514b90dc2b │ │ │ │ └── 15f870c6975ad6449b5b52514b90dc2b.info │ │ │ ├── 16/ │ │ │ │ ├── 16388ae022a89264b84107f0c1b44680 │ │ │ │ ├── 16388ae022a89264b84107f0c1b44680.info │ │ │ │ ├── 164c9b1458eaab743a4b45c37a4d720d │ │ │ │ ├── 164c9b1458eaab743a4b45c37a4d720d.info │ │ │ │ ├── 16548db454f7a3344b41ca2e5cdb52b2 │ │ │ │ ├── 16548db454f7a3344b41ca2e5cdb52b2.info │ │ │ │ ├── 167329c8289a3a14a9e342df49fc4104 │ │ │ │ ├── 167329c8289a3a14a9e342df49fc4104.info │ │ │ │ ├── 16950289b516d6747868e0f7bf7b37a0 │ │ │ │ ├── 16950289b516d6747868e0f7bf7b37a0.info │ │ │ │ ├── 16c6414b77a90ff4098767dce485c495 │ │ │ │ └── 16c6414b77a90ff4098767dce485c495.info │ │ │ ├── 17/ │ │ │ │ ├── 178008567c08e6d84014fa87825d10bb │ │ │ │ └── 178008567c08e6d84014fa87825d10bb.info │ │ │ ├── 18/ │ │ │ │ ├── 1852920dca83b454c8e49493d9ead74c │ │ │ │ ├── 1852920dca83b454c8e49493d9ead74c.info │ │ │ │ ├── 18775b51e3bd42299fd30bd036ea982f │ │ │ │ ├── 18775b51e3bd42299fd30bd036ea982f.info │ │ │ │ ├── 18a4fadfef534684d5af39ca8dc48fe9 │ │ │ │ └── 18a4fadfef534684d5af39ca8dc48fe9.info │ │ │ ├── 19/ │ │ │ │ ├── 197c1114eb793d24c8ef31120a134e88 │ │ │ │ ├── 197c1114eb793d24c8ef31120a134e88.info │ │ │ │ ├── 1999349e7f492c947bb6eb70f624382e │ │ │ │ ├── 1999349e7f492c947bb6eb70f624382e.info │ │ │ │ ├── 19a6f000f81e24c4a826c1abd43e77c7 │ │ │ │ ├── 19a6f000f81e24c4a826c1abd43e77c7.info │ │ │ │ ├── 19c6f364c1e81cb4f829a057824639ad │ │ │ │ └── 19c6f364c1e81cb4f829a057824639ad.info │ │ │ ├── 1a/ │ │ │ │ ├── 1a26e19d51cbfac42a02631ad1f9e39e │ │ │ │ ├── 1a26e19d51cbfac42a02631ad1f9e39e.info │ │ │ │ ├── 1a34c77a67cf21c4b8523a435293645b │ │ │ │ ├── 1a34c77a67cf21c4b8523a435293645b.info │ │ │ │ ├── 1a4266815e998967becf686f9c71f0a6 │ │ │ │ ├── 1a4266815e998967becf686f9c71f0a6.info │ │ │ │ ├── 1a70a790a43cd0d4a96f75746841f764 │ │ │ │ ├── 1a70a790a43cd0d4a96f75746841f764.info │ │ │ │ ├── 1a7a541ac0259ac4e8570ac8c3510dfe │ │ │ │ ├── 1a7a541ac0259ac4e8570ac8c3510dfe.info │ │ │ │ ├── 1aa08ab6e0800fa44ae55d278d1423e3 │ │ │ │ ├── 1aa08ab6e0800fa44ae55d278d1423e3.info │ │ │ │ ├── 1ac58cb55fc8daf4abd3945a2bbbb0c5 │ │ │ │ ├── 1ac58cb55fc8daf4abd3945a2bbbb0c5.info │ │ │ │ ├── 1ac677c5ece15b443b2aaf7fae5842f7 │ │ │ │ ├── 1ac677c5ece15b443b2aaf7fae5842f7.info │ │ │ │ ├── 1ad55f5ad04d1d045a1f287409c650dd │ │ │ │ ├── 1ad55f5ad04d1d045a1f287409c650dd.info │ │ │ │ ├── 1adaa8dcc4fda3d4cb4d3c8e0cb65d12 │ │ │ │ ├── 1adaa8dcc4fda3d4cb4d3c8e0cb65d12.info │ │ │ │ ├── 1adad61bfb44214ee3e887b5febc4396 │ │ │ │ └── 1adad61bfb44214ee3e887b5febc4396.info │ │ │ ├── 1b/ │ │ │ │ ├── 1b0a41d64d4e9534481f804049080fbb │ │ │ │ ├── 1b0a41d64d4e9534481f804049080fbb.info │ │ │ │ ├── 1b199a26663a15b4db765ffb1df401f2 │ │ │ │ ├── 1b199a26663a15b4db765ffb1df401f2.info │ │ │ │ ├── 1b393f6b29a9ee84c803af1ab4944b71 │ │ │ │ ├── 1b393f6b29a9ee84c803af1ab4944b71.info │ │ │ │ ├── 1bbfba4363c8e1e4b8214b4004316ce5 │ │ │ │ ├── 1bbfba4363c8e1e4b8214b4004316ce5.info │ │ │ │ ├── 1bfe12aa306c0c74db4f4f1a1a0ae5ce │ │ │ │ └── 1bfe12aa306c0c74db4f4f1a1a0ae5ce.info │ │ │ ├── 1c/ │ │ │ │ ├── 1c147d10db452eb4b854a35f84472017 │ │ │ │ ├── 1c147d10db452eb4b854a35f84472017.info │ │ │ │ ├── 1c5afe945b715e149a70113a4be7b32a │ │ │ │ ├── 1c5afe945b715e149a70113a4be7b32a.info │ │ │ │ ├── 1c61a04a5b7737c4d16673d64be4194e │ │ │ │ ├── 1c61a04a5b7737c4d16673d64be4194e.info │ │ │ │ ├── 1cd98b0d17936ed43bed805e1a150a88 │ │ │ │ ├── 1cd98b0d17936ed43bed805e1a150a88.info │ │ │ │ ├── 1cddf785b0d07434d8e0607c97b09135 │ │ │ │ ├── 1cddf785b0d07434d8e0607c97b09135.info │ │ │ │ ├── 1cf2469083ffa484da4d78dd70d708e8 │ │ │ │ └── 1cf2469083ffa484da4d78dd70d708e8.info │ │ │ ├── 1d/ │ │ │ │ ├── 1d446e57147ca9b4183edfbbfa9bf206 │ │ │ │ ├── 1d446e57147ca9b4183edfbbfa9bf206.info │ │ │ │ ├── 1d93ffb668978f7488211a331977b73b │ │ │ │ ├── 1d93ffb668978f7488211a331977b73b.info │ │ │ │ ├── 1db879070d9a45f4c86cdf5e59616df5 │ │ │ │ ├── 1db879070d9a45f4c86cdf5e59616df5.info │ │ │ │ ├── 1ddb9e1c877ea80479d1eab4ddaa5d0d │ │ │ │ └── 1ddb9e1c877ea80479d1eab4ddaa5d0d.info │ │ │ ├── 1e/ │ │ │ │ ├── 1e5ee557da46d59498c484308be5067e │ │ │ │ ├── 1e5ee557da46d59498c484308be5067e.info │ │ │ │ ├── 1ea10891dd782154ca0fb67bce9e6f72 │ │ │ │ ├── 1ea10891dd782154ca0fb67bce9e6f72.info │ │ │ │ ├── 1ebc1994f9a3d5649a1201d3a84b38df │ │ │ │ ├── 1ebc1994f9a3d5649a1201d3a84b38df.info │ │ │ │ ├── 1ec4b8ec4b34f4344bac53c19288eaa2 │ │ │ │ ├── 1ec4b8ec4b34f4344bac53c19288eaa2.info │ │ │ │ ├── 1ef2923b9c5521948a04299da53ae750 │ │ │ │ └── 1ef2923b9c5521948a04299da53ae750.info │ │ │ ├── 1f/ │ │ │ │ ├── 1f2a7e0d1b6bbba408a41e206945c23c │ │ │ │ ├── 1f2a7e0d1b6bbba408a41e206945c23c.info │ │ │ │ ├── 1f3a562675833b4448299e4f627b0cec │ │ │ │ ├── 1f3a562675833b4448299e4f627b0cec.info │ │ │ │ ├── 1f5bbb88ca730434483440cbc0278ef6 │ │ │ │ ├── 1f5bbb88ca730434483440cbc0278ef6.info │ │ │ │ ├── 1fe0f539450e54dbc85bfb2fa6b466fb │ │ │ │ └── 1fe0f539450e54dbc85bfb2fa6b466fb.info │ │ │ ├── 20/ │ │ │ │ ├── 200617708f5b36a4da2e2a3f1ceacedd │ │ │ │ ├── 200617708f5b36a4da2e2a3f1ceacedd.info │ │ │ │ ├── 2011a59d3f76b3d4a85cb53f945fceee │ │ │ │ ├── 2011a59d3f76b3d4a85cb53f945fceee.info │ │ │ │ ├── 202d758d102b6854a9710c8b93db742c │ │ │ │ ├── 202d758d102b6854a9710c8b93db742c.info │ │ │ │ ├── 20793418366caf14293b29c55df5e9ec │ │ │ │ ├── 20793418366caf14293b29c55df5e9ec.info │ │ │ │ ├── 208e46d59ff6e304db0318377d20f5a1 │ │ │ │ ├── 208e46d59ff6e304db0318377d20f5a1.info │ │ │ │ ├── 20a9b557a46149dfbfa04a3a7080f5aa │ │ │ │ ├── 20a9b557a46149dfbfa04a3a7080f5aa.info │ │ │ │ ├── 20c8bb6b47a526c4c96ca73314fe2856 │ │ │ │ ├── 20c8bb6b47a526c4c96ca73314fe2856.info │ │ │ │ ├── 20cdb37e6fea6d946bbb84d2c923db85 │ │ │ │ ├── 20cdb37e6fea6d946bbb84d2c923db85.info │ │ │ │ ├── 20ff4283f687e044087714f82c4d6d3f │ │ │ │ └── 20ff4283f687e044087714f82c4d6d3f.info │ │ │ ├── 21/ │ │ │ │ ├── 212a65848ed53294788b2731538c9d66 │ │ │ │ ├── 212a65848ed53294788b2731538c9d66.info │ │ │ │ ├── 218eacd3a7686dd4d875c191fdaa058c │ │ │ │ ├── 218eacd3a7686dd4d875c191fdaa058c.info │ │ │ │ ├── 21bf7f712d84d26478ebe6a299f21738 │ │ │ │ ├── 21bf7f712d84d26478ebe6a299f21738.info │ │ │ │ ├── 21c0044a7f964773be90d197a78e4703 │ │ │ │ ├── 21c0044a7f964773be90d197a78e4703.info │ │ │ │ ├── 21d2d5d6901f2ca43a8015c60ada4e2c │ │ │ │ └── 21d2d5d6901f2ca43a8015c60ada4e2c.info │ │ │ ├── 22/ │ │ │ │ ├── 220e9325710f4235a43492dd1ee4980d │ │ │ │ ├── 220e9325710f4235a43492dd1ee4980d.info │ │ │ │ ├── 22464cf7ab0243a6bf9c79851183b002 │ │ │ │ ├── 22464cf7ab0243a6bf9c79851183b002.info │ │ │ │ ├── 22899211c24eeb248b22704499dd108f │ │ │ │ └── 22899211c24eeb248b22704499dd108f.info │ │ │ ├── 23/ │ │ │ │ ├── 2300e75732d74890b38a8ff257a3ae15 │ │ │ │ ├── 2300e75732d74890b38a8ff257a3ae15.info │ │ │ │ ├── 230f3ac09b9ef234cba81ade9bd0e32a │ │ │ │ ├── 230f3ac09b9ef234cba81ade9bd0e32a.info │ │ │ │ ├── 2347243c7aa3e224f9282dc94e6fc3b2 │ │ │ │ ├── 2347243c7aa3e224f9282dc94e6fc3b2.info │ │ │ │ ├── 2359c66dee10c454c97f6aea84e3fe22 │ │ │ │ ├── 2359c66dee10c454c97f6aea84e3fe22.info │ │ │ │ ├── 23884ce4c1de32846adafea2d53a4cee │ │ │ │ ├── 23884ce4c1de32846adafea2d53a4cee.info │ │ │ │ ├── 239dd6edc8e5cd14585c03e09e86a747 │ │ │ │ ├── 239dd6edc8e5cd14585c03e09e86a747.info │ │ │ │ ├── 23a562f2cac6401f9f91251c68a1a794 │ │ │ │ ├── 23a562f2cac6401f9f91251c68a1a794.info │ │ │ │ ├── 23a56a19774ed42b6b65646af08a003c │ │ │ │ └── 23a56a19774ed42b6b65646af08a003c.info │ │ │ ├── 24/ │ │ │ │ ├── 24a158219395ebf44a60547b97784ddc │ │ │ │ ├── 24a158219395ebf44a60547b97784ddc.info │ │ │ │ ├── 24a7ce8b48db53747a4e8abbda77eac4 │ │ │ │ ├── 24a7ce8b48db53747a4e8abbda77eac4.info │ │ │ │ ├── 24f430bcb0b5b8046adfc8065bffc5c9 │ │ │ │ └── 24f430bcb0b5b8046adfc8065bffc5c9.info │ │ │ ├── 25/ │ │ │ │ ├── 2537ddddebaa455409dec422eb08fd7e │ │ │ │ ├── 2537ddddebaa455409dec422eb08fd7e.info │ │ │ │ ├── 255b0c6d400fd964dab3029c8abc53f4 │ │ │ │ ├── 255b0c6d400fd964dab3029c8abc53f4.info │ │ │ │ ├── 256a0ca37fa972840bce7fca446e75e7 │ │ │ │ ├── 256a0ca37fa972840bce7fca446e75e7.info │ │ │ │ ├── 25a477c2f24db8778a4179421a32cc21 │ │ │ │ ├── 25a477c2f24db8778a4179421a32cc21.info │ │ │ │ ├── 25b01819c6e1649428db2a9b274cf364 │ │ │ │ └── 25b01819c6e1649428db2a9b274cf364.info │ │ │ ├── 26/ │ │ │ │ ├── 260b531edc40677429c0198d6961e448 │ │ │ │ ├── 260b531edc40677429c0198d6961e448.info │ │ │ │ ├── 26570be2af04195458e6f1ac1f5c48e0 │ │ │ │ ├── 26570be2af04195458e6f1ac1f5c48e0.info │ │ │ │ ├── 26721f9940339264fb14bdbfe1290e21 │ │ │ │ ├── 26721f9940339264fb14bdbfe1290e21.info │ │ │ │ ├── 26a4f29db434fd79025c91f6126382cc │ │ │ │ ├── 26a4f29db434fd79025c91f6126382cc.info │ │ │ │ ├── 26f3e7301af463c4ca72fa98d59b429e │ │ │ │ └── 26f3e7301af463c4ca72fa98d59b429e.info │ │ │ ├── 27/ │ │ │ │ ├── 2705215ac5b84b70bacc50632be6e391 │ │ │ │ ├── 2705215ac5b84b70bacc50632be6e391.info │ │ │ │ ├── 27619889b8ba8c24980f49ee34dbb44a │ │ │ │ ├── 27619889b8ba8c24980f49ee34dbb44a.info │ │ │ │ ├── 27769e9b00b038d47aefe306a4d20bec │ │ │ │ ├── 27769e9b00b038d47aefe306a4d20bec.info │ │ │ │ ├── 2799eb4c84e72e54092a292cf626936b │ │ │ │ ├── 2799eb4c84e72e54092a292cf626936b.info │ │ │ │ ├── 27a0335dab59ec542aadd6636a5b4ebd │ │ │ │ ├── 27a0335dab59ec542aadd6636a5b4ebd.info │ │ │ │ ├── 27df3b12f30d0b74a9b10a3968c402ff │ │ │ │ ├── 27df3b12f30d0b74a9b10a3968c402ff.info │ │ │ │ ├── 27ed3e221887b3544bd9d6505d4a789f │ │ │ │ └── 27ed3e221887b3544bd9d6505d4a789f.info │ │ │ ├── 28/ │ │ │ │ ├── 2808ba6bccb2478ec9c7209d8bf1f3cc │ │ │ │ ├── 2808ba6bccb2478ec9c7209d8bf1f3cc.info │ │ │ │ ├── 281f7e519f1ddd14b96c09995386ec82 │ │ │ │ ├── 281f7e519f1ddd14b96c09995386ec82.info │ │ │ │ ├── 28375447bcea455c9b51a6650b10c9d7 │ │ │ │ ├── 28375447bcea455c9b51a6650b10c9d7.info │ │ │ │ ├── 28542eca5f1b4c64813acfbd512524b6 │ │ │ │ ├── 28542eca5f1b4c64813acfbd512524b6.info │ │ │ │ ├── 28c8fcb831e6e734a9f564bc4f495eba │ │ │ │ ├── 28c8fcb831e6e734a9f564bc4f495eba.info │ │ │ │ ├── 28e8b16370ff78c4faca58757271619f │ │ │ │ ├── 28e8b16370ff78c4faca58757271619f.info │ │ │ │ ├── 28f79a0d7e64c2345bc46f8c4cf788f8 │ │ │ │ └── 28f79a0d7e64c2345bc46f8c4cf788f8.info │ │ │ ├── 29/ │ │ │ │ ├── 29b7e99efaf64b949afd3d5b830c72aa │ │ │ │ ├── 29b7e99efaf64b949afd3d5b830c72aa.info │ │ │ │ ├── 29bf1d4ec1012bc45967ce95b729b8b3 │ │ │ │ ├── 29bf1d4ec1012bc45967ce95b729b8b3.info │ │ │ │ ├── 29d603e0a726a9043b3503112271844a │ │ │ │ └── 29d603e0a726a9043b3503112271844a.info │ │ │ ├── 2a/ │ │ │ │ ├── 2a0bd678385f98e4d8eabdfc07d62b4f │ │ │ │ ├── 2a0bd678385f98e4d8eabdfc07d62b4f.info │ │ │ │ ├── 2a16748d9461eae46a725db9776d5390 │ │ │ │ ├── 2a16748d9461eae46a725db9776d5390.info │ │ │ │ ├── 2a28c2fab6b1bb745a844ef6b908e7ee │ │ │ │ ├── 2a28c2fab6b1bb745a844ef6b908e7ee.info │ │ │ │ ├── 2a4db7a114972834c8e4117be1d82ba3 │ │ │ │ ├── 2a4db7a114972834c8e4117be1d82ba3.info │ │ │ │ ├── 2ac6db96cd5bff048a79be0215503e16 │ │ │ │ ├── 2ac6db96cd5bff048a79be0215503e16.info │ │ │ │ ├── 2ae2ce6274819484fa8747a28cebdf3a │ │ │ │ ├── 2ae2ce6274819484fa8747a28cebdf3a.info │ │ │ │ ├── 2aff4fada0516c64a8537a20bfe1b699 │ │ │ │ └── 2aff4fada0516c64a8537a20bfe1b699.info │ │ │ ├── 2b/ │ │ │ │ ├── 2b301b727225f1941974d69e61a55620 │ │ │ │ ├── 2b301b727225f1941974d69e61a55620.info │ │ │ │ ├── 2bafac87e7f4b9b418d9448d219b01ab │ │ │ │ ├── 2bafac87e7f4b9b418d9448d219b01ab.info │ │ │ │ ├── 2bc8a181dfd9de24388de89bb8db7713 │ │ │ │ ├── 2bc8a181dfd9de24388de89bb8db7713.info │ │ │ │ ├── 2bd3ca1fde4b154448ef972b0f9d292e │ │ │ │ ├── 2bd3ca1fde4b154448ef972b0f9d292e.info │ │ │ │ ├── 2bf68308f6cdff141ab98cd34174e4f1 │ │ │ │ └── 2bf68308f6cdff141ab98cd34174e4f1.info │ │ │ ├── 2c/ │ │ │ │ ├── 2c03ae9aa36a4fd44a983831f44654be │ │ │ │ ├── 2c03ae9aa36a4fd44a983831f44654be.info │ │ │ │ ├── 2c2dfcbbb77359547bcaa7cdabd47ebb │ │ │ │ ├── 2c2dfcbbb77359547bcaa7cdabd47ebb.info │ │ │ │ ├── 2c80ef0306e06ac4d8a4b0fe7e4536ac │ │ │ │ ├── 2c80ef0306e06ac4d8a4b0fe7e4536ac.info │ │ │ │ ├── 2c814623cb42764d304be0c5ddd03ceb │ │ │ │ ├── 2c814623cb42764d304be0c5ddd03ceb.info │ │ │ │ ├── 2c87ec8c97244cd47945ec90a99abe35 │ │ │ │ ├── 2c87ec8c97244cd47945ec90a99abe35.info │ │ │ │ ├── 2cb24b5a5793c654e899a06bf08ec3ae │ │ │ │ ├── 2cb24b5a5793c654e899a06bf08ec3ae.info │ │ │ │ ├── 2ce4bbcc4722440890a03312706037fe │ │ │ │ └── 2ce4bbcc4722440890a03312706037fe.info │ │ │ ├── 2d/ │ │ │ │ ├── 2d142b475fbfb8cf12ba3a795194300a │ │ │ │ ├── 2d142b475fbfb8cf12ba3a795194300a.info │ │ │ │ ├── 2d49b7c1bcd2e07499844da127be038d │ │ │ │ ├── 2d49b7c1bcd2e07499844da127be038d.info │ │ │ │ ├── 2d6ba5cbe47e6ad3c87474c56174d4e0 │ │ │ │ ├── 2d6ba5cbe47e6ad3c87474c56174d4e0.info │ │ │ │ ├── 2d8485e4e3a2bcb429fc32900ca26d9e │ │ │ │ ├── 2d8485e4e3a2bcb429fc32900ca26d9e.info │ │ │ │ ├── 2d9b6ff056b6f484ba6500aa8e06bcf3 │ │ │ │ ├── 2d9b6ff056b6f484ba6500aa8e06bcf3.info │ │ │ │ ├── 2da0c512f12947e489f739169773d7ca │ │ │ │ ├── 2da0c512f12947e489f739169773d7ca.info │ │ │ │ ├── 2da27f5fe80a3a549ac7331d9f52f5f0 │ │ │ │ ├── 2da27f5fe80a3a549ac7331d9f52f5f0.info │ │ │ │ ├── 2de8ba3b840049641897e0da7ce1d5cd │ │ │ │ └── 2de8ba3b840049641897e0da7ce1d5cd.info │ │ │ ├── 2e/ │ │ │ │ ├── 2e0de782b8e9e4e45baeb7bb5ef4907f │ │ │ │ ├── 2e0de782b8e9e4e45baeb7bb5ef4907f.info │ │ │ │ ├── 2e3b9bbf2c1a3cd4f88883ca32882ec6 │ │ │ │ └── 2e3b9bbf2c1a3cd4f88883ca32882ec6.info │ │ │ ├── 2f/ │ │ │ │ ├── 2fa2cf7de51b0d34d9dce3747b72e49d │ │ │ │ ├── 2fa2cf7de51b0d34d9dce3747b72e49d.info │ │ │ │ ├── 2fafe2cfe61f6974895a912c3755e8f1 │ │ │ │ ├── 2fafe2cfe61f6974895a912c3755e8f1.info │ │ │ │ ├── 2fd6421f253b4ef1a19526541f9ffc0c │ │ │ │ └── 2fd6421f253b4ef1a19526541f9ffc0c.info │ │ │ ├── 30/ │ │ │ │ ├── 305ca32be1aa5504aa182f583895dfe4 │ │ │ │ ├── 305ca32be1aa5504aa182f583895dfe4.info │ │ │ │ ├── 30649d3a9faa99c48a7b1166b86bf2a0 │ │ │ │ ├── 30649d3a9faa99c48a7b1166b86bf2a0.info │ │ │ │ ├── 3069a00b8c364df395994d7d379e0a99 │ │ │ │ ├── 3069a00b8c364df395994d7d379e0a99.info │ │ │ │ ├── 306cc8c2b49d7114eaa3623786fc2126 │ │ │ │ ├── 306cc8c2b49d7114eaa3623786fc2126.info │ │ │ │ ├── 309b0604924786544a3786ec4073c5a1 │ │ │ │ ├── 309b0604924786544a3786ec4073c5a1.info │ │ │ │ ├── 30a939dce2fd4073955f2f20e659d506 │ │ │ │ ├── 30a939dce2fd4073955f2f20e659d506.info │ │ │ │ ├── 30bed781e402439ab8ce4e3357708115 │ │ │ │ └── 30bed781e402439ab8ce4e3357708115.info │ │ │ ├── 31/ │ │ │ │ ├── 3168bf9e060ff4b46be4bf08e308ce97 │ │ │ │ ├── 3168bf9e060ff4b46be4bf08e308ce97.info │ │ │ │ ├── 3174898fbcdf12448963cdb5f5b60a33 │ │ │ │ ├── 3174898fbcdf12448963cdb5f5b60a33.info │ │ │ │ ├── 319b8889f363f5947acf209c17a94149 │ │ │ │ ├── 319b8889f363f5947acf209c17a94149.info │ │ │ │ ├── 31a19414c41e5ae4aae2af33fee712f6 │ │ │ │ └── 31a19414c41e5ae4aae2af33fee712f6.info │ │ │ ├── 32/ │ │ │ │ ├── 321dc2c0720f8dd4f9396ecdc12b8746 │ │ │ │ ├── 321dc2c0720f8dd4f9396ecdc12b8746.info │ │ │ │ ├── 322392995be44d23a3c86cfd972f838f │ │ │ │ ├── 322392995be44d23a3c86cfd972f838f.info │ │ │ │ ├── 3245ec927659c4140ac4f8d17403cc18 │ │ │ │ ├── 3245ec927659c4140ac4f8d17403cc18.info │ │ │ │ ├── 32535dd294c621e4297fba34b15b1c52 │ │ │ │ ├── 32535dd294c621e4297fba34b15b1c52.info │ │ │ │ ├── 32a4a0ea998dd6149937d2774781c436 │ │ │ │ ├── 32a4a0ea998dd6149937d2774781c436.info │ │ │ │ ├── 32d40088a6124c578ad6b428df586e2e │ │ │ │ ├── 32d40088a6124c578ad6b428df586e2e.info │ │ │ │ ├── 32da81683c22faf458026716a2b821aa │ │ │ │ ├── 32da81683c22faf458026716a2b821aa.info │ │ │ │ ├── 32e2186f4598cff489784aae586f2215 │ │ │ │ └── 32e2186f4598cff489784aae586f2215.info │ │ │ ├── 33/ │ │ │ │ ├── 3312d7739989d2b4e91e6319e9a96d76 │ │ │ │ ├── 3312d7739989d2b4e91e6319e9a96d76.info │ │ │ │ ├── 335020228a0fe124897f51f25f6350ee │ │ │ │ ├── 335020228a0fe124897f51f25f6350ee.info │ │ │ │ ├── 3371106faf8d06f47a73979a3c8d82a1 │ │ │ │ ├── 3371106faf8d06f47a73979a3c8d82a1.info │ │ │ │ ├── 3387717991705ce4e8ef033a0e543a06 │ │ │ │ ├── 3387717991705ce4e8ef033a0e543a06.info │ │ │ │ ├── 33e6b78c96bb0694e96383e3c56b7b54 │ │ │ │ └── 33e6b78c96bb0694e96383e3c56b7b54.info │ │ │ ├── 34/ │ │ │ │ ├── 3411e19edd44cfd46b548b058c3bc36c │ │ │ │ ├── 3411e19edd44cfd46b548b058c3bc36c.info │ │ │ │ ├── 342a0f8aca7f4f0691338912faec0494 │ │ │ │ ├── 342a0f8aca7f4f0691338912faec0494.info │ │ │ │ ├── 343deaaf83e0cee4ca978e7df0b80d21 │ │ │ │ ├── 343deaaf83e0cee4ca978e7df0b80d21.info │ │ │ │ ├── 3477d28057cb3e4469c7ea6b8dc23046 │ │ │ │ ├── 3477d28057cb3e4469c7ea6b8dc23046.info │ │ │ │ ├── 34d6f60b171c1004e8335d52c65928a3 │ │ │ │ ├── 34d6f60b171c1004e8335d52c65928a3.info │ │ │ │ ├── 34e150112c1c42ac83170b52d898e322 │ │ │ │ ├── 34e150112c1c42ac83170b52d898e322.info │ │ │ │ ├── 34e2c9b9d9e44953933afe37461f44e6 │ │ │ │ ├── 34e2c9b9d9e44953933afe37461f44e6.info │ │ │ │ ├── 34f6695d37a94370a3697f6b068f5d5e │ │ │ │ ├── 34f6695d37a94370a3697f6b068f5d5e.info │ │ │ │ ├── 34f9419ac53fdb44fa9676a451481931 │ │ │ │ ├── 34f9419ac53fdb44fa9676a451481931.info │ │ │ │ ├── 34fc60e2fe0cbfa4a87375cdfff9dc86 │ │ │ │ └── 34fc60e2fe0cbfa4a87375cdfff9dc86.info │ │ │ ├── 35/ │ │ │ │ ├── 3504aa04cda851b44a65973f9aead6f7 │ │ │ │ ├── 3504aa04cda851b44a65973f9aead6f7.info │ │ │ │ ├── 3550d8ec6f29ab34d895ae9a43d560c2 │ │ │ │ ├── 3550d8ec6f29ab34d895ae9a43d560c2.info │ │ │ │ ├── 357e9aeae0d19c148b2437b05c8b3361 │ │ │ │ ├── 357e9aeae0d19c148b2437b05c8b3361.info │ │ │ │ ├── 358a618bc6bd9354d81cc206fd2ed80e │ │ │ │ ├── 358a618bc6bd9354d81cc206fd2ed80e.info │ │ │ │ ├── 35a0d10199de49f4db0128003bfd3bda │ │ │ │ ├── 35a0d10199de49f4db0128003bfd3bda.info │ │ │ │ ├── 35cb34351b19cf44ba78afbd58746610 │ │ │ │ ├── 35cb34351b19cf44ba78afbd58746610.info │ │ │ │ ├── 35d143b352678294ab0f5feb97b67f88 │ │ │ │ ├── 35d143b352678294ab0f5feb97b67f88.info │ │ │ │ ├── 35ff0937876540d3bd4b6a941df62a92 │ │ │ │ └── 35ff0937876540d3bd4b6a941df62a92.info │ │ │ ├── 36/ │ │ │ │ ├── 3664a2ade19bb7848a4d2c96ac9148e3 │ │ │ │ ├── 3664a2ade19bb7848a4d2c96ac9148e3.info │ │ │ │ ├── 368d3a0498e78014da578aa5f45e2797 │ │ │ │ └── 368d3a0498e78014da578aa5f45e2797.info │ │ │ ├── 37/ │ │ │ │ ├── 371b6b9c8adc50745ace66a6fdf67481 │ │ │ │ ├── 371b6b9c8adc50745ace66a6fdf67481.info │ │ │ │ ├── 373b4c78c0396334288fa5ff8e7b7350 │ │ │ │ ├── 373b4c78c0396334288fa5ff8e7b7350.info │ │ │ │ ├── 37472f5179ca2004489ac901814cdbc3 │ │ │ │ ├── 37472f5179ca2004489ac901814cdbc3.info │ │ │ │ ├── 376c84ea405e0f2b80562c23bb977216 │ │ │ │ ├── 376c84ea405e0f2b80562c23bb977216.info │ │ │ │ ├── 37888acc09d9ee848bf9559f06645c45 │ │ │ │ ├── 37888acc09d9ee848bf9559f06645c45.info │ │ │ │ ├── 37b164a494cd92a498526852ecceedef │ │ │ │ ├── 37b164a494cd92a498526852ecceedef.info │ │ │ │ ├── 37cea569bfefafe49a1513c4d7f0e9eb │ │ │ │ ├── 37cea569bfefafe49a1513c4d7f0e9eb.info │ │ │ │ ├── 37cff9f5a86ae494c8cb04423580480d │ │ │ │ └── 37cff9f5a86ae494c8cb04423580480d.info │ │ │ ├── 38/ │ │ │ │ ├── 380f7372e785c7d408552e2c760d269d │ │ │ │ ├── 380f7372e785c7d408552e2c760d269d.info │ │ │ │ ├── 383966e89d344865a36addd5d378ffd3 │ │ │ │ ├── 383966e89d344865a36addd5d378ffd3.info │ │ │ │ ├── 38a6d0a81fcac8e4e851c921333f9803 │ │ │ │ ├── 38a6d0a81fcac8e4e851c921333f9803.info │ │ │ │ ├── 38e3a8976f0b9c586b6dfbcef4e4066c │ │ │ │ └── 38e3a8976f0b9c586b6dfbcef4e4066c.info │ │ │ ├── 39/ │ │ │ │ ├── 393b15da08c88194dbbcacd6ee15a89c │ │ │ │ ├── 393b15da08c88194dbbcacd6ee15a89c.info │ │ │ │ ├── 39728903e57c60021f80449a8bbc0096 │ │ │ │ ├── 39728903e57c60021f80449a8bbc0096.info │ │ │ │ ├── 39ab466162988eb4f83443f911bbf5c8 │ │ │ │ ├── 39ab466162988eb4f83443f911bbf5c8.info │ │ │ │ ├── 39dcddcb5895328489c92214aa73e3bb │ │ │ │ └── 39dcddcb5895328489c92214aa73e3bb.info │ │ │ ├── 3a/ │ │ │ │ ├── 3a2d94c8977984b67984caeff9fa666e │ │ │ │ ├── 3a2d94c8977984b67984caeff9fa666e.info │ │ │ │ ├── 3a5038547af7c7f46bd90a015862e0b3 │ │ │ │ ├── 3a5038547af7c7f46bd90a015862e0b3.info │ │ │ │ ├── 3a784fb721704576b3b4c3a7f3324264 │ │ │ │ ├── 3a784fb721704576b3b4c3a7f3324264.info │ │ │ │ ├── 3ad53269c7421084ab67f804591994e0 │ │ │ │ └── 3ad53269c7421084ab67f804591994e0.info │ │ │ ├── 3b/ │ │ │ │ ├── 3b0c53b13a1539949b3b212e049151d1 │ │ │ │ ├── 3b0c53b13a1539949b3b212e049151d1.info │ │ │ │ ├── 3b28913f21577de429da928d6d05219f │ │ │ │ ├── 3b28913f21577de429da928d6d05219f.info │ │ │ │ ├── 3b4429eff9fcffb48b006e8edcc90338 │ │ │ │ ├── 3b4429eff9fcffb48b006e8edcc90338.info │ │ │ │ ├── 3bce033ee26244e419b3bb3bba95a37d │ │ │ │ ├── 3bce033ee26244e419b3bb3bba95a37d.info │ │ │ │ ├── 3bda1886f58f4e0ab1139400b160c3ee │ │ │ │ └── 3bda1886f58f4e0ab1139400b160c3ee.info │ │ │ ├── 3c/ │ │ │ │ ├── 3c01b61b3a6887c49a15276fd38be918 │ │ │ │ ├── 3c01b61b3a6887c49a15276fd38be918.info │ │ │ │ ├── 3c09dc5cd0a70cf40856b7d406106ee1 │ │ │ │ ├── 3c09dc5cd0a70cf40856b7d406106ee1.info │ │ │ │ ├── 3c4ccfb0896bcf44da13e152b267aa49 │ │ │ │ ├── 3c4ccfb0896bcf44da13e152b267aa49.info │ │ │ │ ├── 3c6c403084eacec478a1129ce20061ea │ │ │ │ ├── 3c6c403084eacec478a1129ce20061ea.info │ │ │ │ ├── 3c731404613599947b4b4559797a5168 │ │ │ │ ├── 3c731404613599947b4b4559797a5168.info │ │ │ │ ├── 3c737f7a9d78541d1ab25f28f045dd32 │ │ │ │ ├── 3c737f7a9d78541d1ab25f28f045dd32.info │ │ │ │ ├── 3cf5cb9e1ef590c48b1f919f2a7bd895 │ │ │ │ └── 3cf5cb9e1ef590c48b1f919f2a7bd895.info │ │ │ ├── 3d/ │ │ │ │ ├── 3d42c4854f9093e409cd90c00ef26de0 │ │ │ │ ├── 3d42c4854f9093e409cd90c00ef26de0.info │ │ │ │ ├── 3d67ccdf81bed8247ad0db2d5f47a7d1 │ │ │ │ ├── 3d67ccdf81bed8247ad0db2d5f47a7d1.info │ │ │ │ ├── 3dde15f260b0dd1469e60d16eaa795dc │ │ │ │ └── 3dde15f260b0dd1469e60d16eaa795dc.info │ │ │ ├── 3e/ │ │ │ │ ├── 3e29cdd1646803545b8fb18908666ec4 │ │ │ │ ├── 3e29cdd1646803545b8fb18908666ec4.info │ │ │ │ ├── 3e8d6af343b383544ba5743d119f4062 │ │ │ │ ├── 3e8d6af343b383544ba5743d119f4062.info │ │ │ │ ├── 3e99141cd5dbef844a4338bb87930b89 │ │ │ │ ├── 3e99141cd5dbef844a4338bb87930b89.info │ │ │ │ ├── 3ec7596410385054a9e0bc90377fbe63 │ │ │ │ ├── 3ec7596410385054a9e0bc90377fbe63.info │ │ │ │ ├── 3ec9edad2de6c4df3a146b543a0fbc4c │ │ │ │ ├── 3ec9edad2de6c4df3a146b543a0fbc4c.info │ │ │ │ ├── 3edf75dd062cabf449c243d3c0da9464 │ │ │ │ ├── 3edf75dd062cabf449c243d3c0da9464.info │ │ │ │ ├── 3ee40aa79cd242a5b53b0b0ca4f13f0f │ │ │ │ └── 3ee40aa79cd242a5b53b0b0ca4f13f0f.info │ │ │ ├── 3f/ │ │ │ │ ├── 3f8643c1f8dd449e85b548a14edbea2e │ │ │ │ ├── 3f8643c1f8dd449e85b548a14edbea2e.info │ │ │ │ ├── 3f8c1075884df0249b80e23a0598f9c1 │ │ │ │ ├── 3f8c1075884df0249b80e23a0598f9c1.info │ │ │ │ ├── 3f9202a39620f51418046c7754f215f0 │ │ │ │ ├── 3f9202a39620f51418046c7754f215f0.info │ │ │ │ ├── 3fa274f26b1574c40b949e114327022e │ │ │ │ ├── 3fa274f26b1574c40b949e114327022e.info │ │ │ │ ├── 3fdd83b151eb8d25c5e2f82fc39dcb04 │ │ │ │ ├── 3fdd83b151eb8d25c5e2f82fc39dcb04.info │ │ │ │ ├── 3ff3d24ea34f9f74cb138e435f5f491e │ │ │ │ └── 3ff3d24ea34f9f74cb138e435f5f491e.info │ │ │ ├── 40/ │ │ │ │ ├── 4068e97704a16794ea218ba560cdc1e9 │ │ │ │ ├── 4068e97704a16794ea218ba560cdc1e9.info │ │ │ │ ├── 408674d91d506a54aac9a7f07951c018 │ │ │ │ ├── 408674d91d506a54aac9a7f07951c018.info │ │ │ │ ├── 40bf3cec17fa0b49fe04443c8332d638 │ │ │ │ ├── 40bf3cec17fa0b49fe04443c8332d638.info │ │ │ │ ├── 40c83ba6a1a64cb4baac27028dd1acc1 │ │ │ │ ├── 40c83ba6a1a64cb4baac27028dd1acc1.info │ │ │ │ ├── 40cb137d0e9816e48a4141ed13afedad │ │ │ │ └── 40cb137d0e9816e48a4141ed13afedad.info │ │ │ ├── 41/ │ │ │ │ ├── 411b7c7ffc0960249b35a2a247b66ff7 │ │ │ │ ├── 411b7c7ffc0960249b35a2a247b66ff7.info │ │ │ │ ├── 41b96614b2e6494ba995ddcd252d11ae │ │ │ │ ├── 41b96614b2e6494ba995ddcd252d11ae.info │ │ │ │ ├── 41d60936b62cc6d4ca7fe628b22b0e40 │ │ │ │ ├── 41d60936b62cc6d4ca7fe628b22b0e40.info │ │ │ │ ├── 41dcdc094b311464c8d6cb614548d89b │ │ │ │ ├── 41dcdc094b311464c8d6cb614548d89b.info │ │ │ │ ├── 41e14f40b915ca743a3dffd18ffc65ab │ │ │ │ └── 41e14f40b915ca743a3dffd18ffc65ab.info │ │ │ ├── 42/ │ │ │ │ ├── 423cd382a7804414d9bfdb2e7fb7bb62 │ │ │ │ ├── 423cd382a7804414d9bfdb2e7fb7bb62.info │ │ │ │ ├── 423fe2ef878fa1140a7e1f7f9e365815 │ │ │ │ ├── 423fe2ef878fa1140a7e1f7f9e365815.info │ │ │ │ ├── 426106349a0ff964fa4e7178c1d3a4f5 │ │ │ │ ├── 426106349a0ff964fa4e7178c1d3a4f5.info │ │ │ │ ├── 42fe78c8fe682715a2cb531422e6ccb3 │ │ │ │ └── 42fe78c8fe682715a2cb531422e6ccb3.info │ │ │ ├── 43/ │ │ │ │ ├── 4335a164bb763104c8805212c23d795f │ │ │ │ ├── 4335a164bb763104c8805212c23d795f.info │ │ │ │ ├── 438efd46088d408d8a53f707fa68d976 │ │ │ │ ├── 438efd46088d408d8a53f707fa68d976.info │ │ │ │ ├── 439c018cf4619e94d9a92110ce0aa188 │ │ │ │ ├── 439c018cf4619e94d9a92110ce0aa188.info │ │ │ │ ├── 43a3aec217baa9644a7cf34b5f93fed9 │ │ │ │ ├── 43a3aec217baa9644a7cf34b5f93fed9.info │ │ │ │ ├── 43ad7f10b8cb01a4ca1b57eff53b024c │ │ │ │ ├── 43ad7f10b8cb01a4ca1b57eff53b024c.info │ │ │ │ ├── 43b1467da3d29ae4597a733828cdd84a │ │ │ │ └── 43b1467da3d29ae4597a733828cdd84a.info │ │ │ ├── 44/ │ │ │ │ ├── 4402dcee6e9969549bf5b33f11533208 │ │ │ │ ├── 4402dcee6e9969549bf5b33f11533208.info │ │ │ │ ├── 44100f5f60f351348b9719b46d46cebe │ │ │ │ ├── 44100f5f60f351348b9719b46d46cebe.info │ │ │ │ ├── 44507a833d0ca8a42aaec1c3d752eb5f │ │ │ │ ├── 44507a833d0ca8a42aaec1c3d752eb5f.info │ │ │ │ ├── 445cdcfc747eba94288b97f5869aa2fb │ │ │ │ ├── 445cdcfc747eba94288b97f5869aa2fb.info │ │ │ │ ├── 44df73535c7a760458518e95391dbfdc │ │ │ │ ├── 44df73535c7a760458518e95391dbfdc.info │ │ │ │ ├── 44e1d646473a40178712cb2150f54cec │ │ │ │ └── 44e1d646473a40178712cb2150f54cec.info │ │ │ ├── 45/ │ │ │ │ ├── 4506ac79f5b274cb1b249ed7f4abfb9a │ │ │ │ ├── 4506ac79f5b274cb1b249ed7f4abfb9a.info │ │ │ │ ├── 452534715106564439d2240d82999d88 │ │ │ │ ├── 452534715106564439d2240d82999d88.info │ │ │ │ ├── 45322b284be6baf43a273a61abba527d │ │ │ │ ├── 45322b284be6baf43a273a61abba527d.info │ │ │ │ ├── 4545bb65ccebf8040ac212d5792979b5 │ │ │ │ ├── 4545bb65ccebf8040ac212d5792979b5.info │ │ │ │ ├── 4584db2acba045742a16942983e7fb96 │ │ │ │ ├── 4584db2acba045742a16942983e7fb96.info │ │ │ │ ├── 4585b5feb801bdb44b0e5eafdd95a3be │ │ │ │ ├── 4585b5feb801bdb44b0e5eafdd95a3be.info │ │ │ │ ├── 459f6a07ee4a58b42ba2568b097c3ec4 │ │ │ │ └── 459f6a07ee4a58b42ba2568b097c3ec4.info │ │ │ ├── 46/ │ │ │ │ ├── 46646a5562f14984690c85ee7b946bc9 │ │ │ │ ├── 46646a5562f14984690c85ee7b946bc9.info │ │ │ │ ├── 468e1bfc887161e4196f33e942fc3199 │ │ │ │ └── 468e1bfc887161e4196f33e942fc3199.info │ │ │ ├── 47/ │ │ │ │ ├── 470530e667ad4475786b28fa3187ce95 │ │ │ │ ├── 470530e667ad4475786b28fa3187ce95.info │ │ │ │ ├── 470fdf3cd8176d94e8aadd242240fe3c │ │ │ │ ├── 470fdf3cd8176d94e8aadd242240fe3c.info │ │ │ │ ├── 4722a1362908a1843ab03a055c5c3fa0 │ │ │ │ ├── 4722a1362908a1843ab03a055c5c3fa0.info │ │ │ │ ├── 472a6f18dd2f97c41af72271d22db869 │ │ │ │ ├── 472a6f18dd2f97c41af72271d22db869.info │ │ │ │ ├── 475e3699f219c854f8581a9838135002 │ │ │ │ ├── 475e3699f219c854f8581a9838135002.info │ │ │ │ ├── 47d9eecc3df4a854eaabab84609abb27 │ │ │ │ └── 47d9eecc3df4a854eaabab84609abb27.info │ │ │ ├── 48/ │ │ │ │ ├── 48230e4e90fb4d14a9d56bddea898413 │ │ │ │ ├── 48230e4e90fb4d14a9d56bddea898413.info │ │ │ │ ├── 4884ccc3528cb2e40a0e6f0a19a2b35b │ │ │ │ ├── 4884ccc3528cb2e40a0e6f0a19a2b35b.info │ │ │ │ ├── 48853ae485fa386428341ac1ea122570 │ │ │ │ ├── 48853ae485fa386428341ac1ea122570.info │ │ │ │ ├── 48967a2d5427ac2489cc0ea61da5f1a0 │ │ │ │ ├── 48967a2d5427ac2489cc0ea61da5f1a0.info │ │ │ │ ├── 48b10b41f58d5b49717f376cda59eeb8 │ │ │ │ ├── 48b10b41f58d5b49717f376cda59eeb8.info │ │ │ │ ├── 48d034c499ee4697af9dd6e327110249 │ │ │ │ └── 48d034c499ee4697af9dd6e327110249.info │ │ │ ├── 49/ │ │ │ │ ├── 495e2738ac7d88a41a158cd2e237d70b │ │ │ │ ├── 495e2738ac7d88a41a158cd2e237d70b.info │ │ │ │ ├── 49679f302ac6408697f6b9314a38985c │ │ │ │ ├── 49679f302ac6408697f6b9314a38985c.info │ │ │ │ ├── 49d4c2ab7ff0f4442af256bad7c9d57c │ │ │ │ ├── 49d4c2ab7ff0f4442af256bad7c9d57c.info │ │ │ │ ├── 49f1d2c7420db4444b011955726d0046 │ │ │ │ └── 49f1d2c7420db4444b011955726d0046.info │ │ │ ├── 4a/ │ │ │ │ ├── 4a0757ee0236f39489520769ae710288 │ │ │ │ ├── 4a0757ee0236f39489520769ae710288.info │ │ │ │ ├── 4ac5b6a65aaeb59478e3b78660e9f134 │ │ │ │ ├── 4ac5b6a65aaeb59478e3b78660e9f134.info │ │ │ │ ├── 4acbfc0398bab674f922f693e58f4afc │ │ │ │ ├── 4acbfc0398bab674f922f693e58f4afc.info │ │ │ │ ├── 4ad09461bf994e54da846f726a23118e │ │ │ │ ├── 4ad09461bf994e54da846f726a23118e.info │ │ │ │ ├── 4ae64f3f72004807a9f919f9c27af0db │ │ │ │ └── 4ae64f3f72004807a9f919f9c27af0db.info │ │ │ ├── 4b/ │ │ │ │ ├── 4b518b37798c97b0f860962cbf615533 │ │ │ │ ├── 4b518b37798c97b0f860962cbf615533.info │ │ │ │ ├── 4b57f909f22642d469a39e9628535312 │ │ │ │ ├── 4b57f909f22642d469a39e9628535312.info │ │ │ │ ├── 4b721099b5d509d4093e516f59ad9ad6 │ │ │ │ ├── 4b721099b5d509d4093e516f59ad9ad6.info │ │ │ │ ├── 4b8be68229770db4ea3c78ab0d854325 │ │ │ │ ├── 4b8be68229770db4ea3c78ab0d854325.info │ │ │ │ ├── 4ba2329b63d54f0187bcaa12486b1b0f │ │ │ │ ├── 4ba2329b63d54f0187bcaa12486b1b0f.info │ │ │ │ ├── 4bbc17b35884fdf468e4b52ae4222882 │ │ │ │ ├── 4bbc17b35884fdf468e4b52ae4222882.info │ │ │ │ ├── 4bd2bc28ff24d5c488844851cb785db0 │ │ │ │ └── 4bd2bc28ff24d5c488844851cb785db0.info │ │ │ ├── 4c/ │ │ │ │ ├── 4c1821c1816c6fa44967b8ecb79ea7e4 │ │ │ │ ├── 4c1821c1816c6fa44967b8ecb79ea7e4.info │ │ │ │ ├── 4c5eb52d37bb6714a98af73df7d9cf2c │ │ │ │ ├── 4c5eb52d37bb6714a98af73df7d9cf2c.info │ │ │ │ ├── 4c6f60d349ea37048af03504fc872f33 │ │ │ │ ├── 4c6f60d349ea37048af03504fc872f33.info │ │ │ │ ├── 4cb169caa67eddf4d83b39fd0917a945 │ │ │ │ ├── 4cb169caa67eddf4d83b39fd0917a945.info │ │ │ │ ├── 4cfe5ade9a1375e40aed87618b92bd12 │ │ │ │ └── 4cfe5ade9a1375e40aed87618b92bd12.info │ │ │ ├── 4d/ │ │ │ │ ├── 4d2250412b81fe34abf39f246e274479 │ │ │ │ ├── 4d2250412b81fe34abf39f246e274479.info │ │ │ │ ├── 4d31e19fd539ac54c8d9151da43683e9 │ │ │ │ ├── 4d31e19fd539ac54c8d9151da43683e9.info │ │ │ │ ├── 4d3d51749e989f747b2674e0b4d9b3d7 │ │ │ │ ├── 4d3d51749e989f747b2674e0b4d9b3d7.info │ │ │ │ ├── 4d616d1a494edd144b262cf6cd5e5fda │ │ │ │ ├── 4d616d1a494edd144b262cf6cd5e5fda.info │ │ │ │ ├── 4db13e1060deaae48b30246ed63b7c9b │ │ │ │ ├── 4db13e1060deaae48b30246ed63b7c9b.info │ │ │ │ ├── 4dc5887d05b52fd4fb5f52909d09ffe9 │ │ │ │ ├── 4dc5887d05b52fd4fb5f52909d09ffe9.info │ │ │ │ ├── 4ddcdc3816429494a8bea67e973875f7 │ │ │ │ ├── 4ddcdc3816429494a8bea67e973875f7.info │ │ │ │ ├── 4dfcd3a631f61d248b7cc0b845d40345 │ │ │ │ └── 4dfcd3a631f61d248b7cc0b845d40345.info │ │ │ ├── 4e/ │ │ │ │ ├── 4e29b1a8efbd4b44bb3f3716e73f07ff │ │ │ │ ├── 4e29b1a8efbd4b44bb3f3716e73f07ff.info │ │ │ │ ├── 4e82512e02403f342aefc6129f4d04a4 │ │ │ │ └── 4e82512e02403f342aefc6129f4d04a4.info │ │ │ ├── 4f/ │ │ │ │ ├── 4f07c137155b291429c0b3670c4defba │ │ │ │ ├── 4f07c137155b291429c0b3670c4defba.info │ │ │ │ ├── 4f0ca6874aa74540bb3d4fe5a0f86bcc │ │ │ │ ├── 4f0ca6874aa74540bb3d4fe5a0f86bcc.info │ │ │ │ ├── 4f0f9b9f3ed97ad2b9ba8f1a8e4666c2 │ │ │ │ ├── 4f0f9b9f3ed97ad2b9ba8f1a8e4666c2.info │ │ │ │ ├── 4f10dd60657c6004587f237a7e90f8e4 │ │ │ │ ├── 4f10dd60657c6004587f237a7e90f8e4.info │ │ │ │ ├── 4f231c4fb786f3946a6b90b886c48677 │ │ │ │ ├── 4f231c4fb786f3946a6b90b886c48677.info │ │ │ │ ├── 4f5ed95515938d14189b094f8654d0bd │ │ │ │ ├── 4f5ed95515938d14189b094f8654d0bd.info │ │ │ │ ├── 4f809c227a3cfde4bbb9482dc1814105 │ │ │ │ ├── 4f809c227a3cfde4bbb9482dc1814105.info │ │ │ │ ├── 4f90cfe4bf5cfb44f84a5b11387f2a42 │ │ │ │ ├── 4f90cfe4bf5cfb44f84a5b11387f2a42.info │ │ │ │ ├── 4f939b9e23a0946439b812551e07ac81 │ │ │ │ ├── 4f939b9e23a0946439b812551e07ac81.info │ │ │ │ ├── 4f9ac6e545d53f94b9f09c85b9576f36 │ │ │ │ ├── 4f9ac6e545d53f94b9f09c85b9576f36.info │ │ │ │ ├── 4fbcc9b1f6ace8c4f8724a88dccca5f8 │ │ │ │ └── 4fbcc9b1f6ace8c4f8724a88dccca5f8.info │ │ │ ├── 50/ │ │ │ │ ├── 505965fb9ab352b4d88882d7c8d822bf │ │ │ │ ├── 505965fb9ab352b4d88882d7c8d822bf.info │ │ │ │ ├── 5082cb99a8f99b84d84dd8b4c5233a9e │ │ │ │ ├── 5082cb99a8f99b84d84dd8b4c5233a9e.info │ │ │ │ ├── 50de529b6a28f4a7093045e08810a5df │ │ │ │ └── 50de529b6a28f4a7093045e08810a5df.info │ │ │ ├── 51/ │ │ │ │ ├── 511aa760b8728a940a41c29837945292 │ │ │ │ ├── 511aa760b8728a940a41c29837945292.info │ │ │ │ ├── 5143f58107604835ab1a5efa2d8818fd │ │ │ │ ├── 5143f58107604835ab1a5efa2d8818fd.info │ │ │ │ ├── 5151708d47edd4344ba8e7bd469d966e │ │ │ │ ├── 5151708d47edd4344ba8e7bd469d966e.info │ │ │ │ ├── 51557afa652635743b264a309f0a5c60 │ │ │ │ ├── 51557afa652635743b264a309f0a5c60.info │ │ │ │ ├── 515638b803bef8599dbd6d5c8bdaa53e │ │ │ │ ├── 515638b803bef8599dbd6d5c8bdaa53e.info │ │ │ │ ├── 51a7878f6c989394782db73339e90e46 │ │ │ │ └── 51a7878f6c989394782db73339e90e46.info │ │ │ ├── 52/ │ │ │ │ ├── 526f285e8d4fb8140b4cdfeb9102d8cb │ │ │ │ ├── 526f285e8d4fb8140b4cdfeb9102d8cb.info │ │ │ │ ├── 529fde071171dfd4e99d45ca81a3ac7b │ │ │ │ ├── 529fde071171dfd4e99d45ca81a3ac7b.info │ │ │ │ ├── 52c907c81459f324497af504b84fd557 │ │ │ │ └── 52c907c81459f324497af504b84fd557.info │ │ │ ├── 54/ │ │ │ │ ├── 5415c904c4fbc3e498253bc2866b37cd │ │ │ │ ├── 5415c904c4fbc3e498253bc2866b37cd.info │ │ │ │ ├── 543674eec776b1442a192c932e6cd9b3 │ │ │ │ ├── 543674eec776b1442a192c932e6cd9b3.info │ │ │ │ ├── 5440c1153b397e14c9c7b1d6eb83b9f9 │ │ │ │ ├── 5440c1153b397e14c9c7b1d6eb83b9f9.info │ │ │ │ ├── 5469ef0820152a4ae45d400fdc4626e4 │ │ │ │ ├── 5469ef0820152a4ae45d400fdc4626e4.info │ │ │ │ ├── 5472815444de2ce45bf2053a4af04b9d │ │ │ │ ├── 5472815444de2ce45bf2053a4af04b9d.info │ │ │ │ ├── 54d21f6ece3b46479f0c328f8c6007e0 │ │ │ │ └── 54d21f6ece3b46479f0c328f8c6007e0.info │ │ │ ├── 55/ │ │ │ │ ├── 5503f95d174761548a68a901beab13c2 │ │ │ │ ├── 5503f95d174761548a68a901beab13c2.info │ │ │ │ ├── 559482fe33c79e44882d3a6cedc55fb5 │ │ │ │ ├── 559482fe33c79e44882d3a6cedc55fb5.info │ │ │ │ ├── 5598b14661b5f4c43bed757f34b6d172 │ │ │ │ ├── 5598b14661b5f4c43bed757f34b6d172.info │ │ │ │ ├── 55a8539917657b14baf6c6a051a7df22 │ │ │ │ └── 55a8539917657b14baf6c6a051a7df22.info │ │ │ ├── 56/ │ │ │ │ ├── 5653477a5039f674da8f856adcf47172 │ │ │ │ ├── 5653477a5039f674da8f856adcf47172.info │ │ │ │ ├── 56666c5a40171f54783dd416a44f42bf │ │ │ │ ├── 56666c5a40171f54783dd416a44f42bf.info │ │ │ │ ├── 5673d7b11cb9ad04eb2368068b720c17 │ │ │ │ ├── 5673d7b11cb9ad04eb2368068b720c17.info │ │ │ │ ├── 56ba6cb160ebfc042b48224bd1a35614 │ │ │ │ └── 56ba6cb160ebfc042b48224bd1a35614.info │ │ │ ├── 57/ │ │ │ │ ├── 57a39be2178cca94ab21e15c082e3ab6 │ │ │ │ ├── 57a39be2178cca94ab21e15c082e3ab6.info │ │ │ │ ├── 57acdaad593b8d143b8fb5052a09d7d0 │ │ │ │ ├── 57acdaad593b8d143b8fb5052a09d7d0.info │ │ │ │ ├── 57b0c806ba25b48aa8a6ecb3345a4a9b │ │ │ │ ├── 57b0c806ba25b48aa8a6ecb3345a4a9b.info │ │ │ │ ├── 57d2ac5c7d5786e499d4794973fe0d4e │ │ │ │ ├── 57d2ac5c7d5786e499d4794973fe0d4e.info │ │ │ │ ├── 57ff740bce4ab0c498ada374a8ca1dc0 │ │ │ │ └── 57ff740bce4ab0c498ada374a8ca1dc0.info │ │ │ ├── 58/ │ │ │ │ ├── 58004290eb3aab44e9823d1f25c4ed73 │ │ │ │ ├── 58004290eb3aab44e9823d1f25c4ed73.info │ │ │ │ ├── 585b70cb75dd43efbfead809c30a1731 │ │ │ │ ├── 585b70cb75dd43efbfead809c30a1731.info │ │ │ │ ├── 58628227479c34542ac8c5193ccced84 │ │ │ │ ├── 58628227479c34542ac8c5193ccced84.info │ │ │ │ ├── 5882d0e4313310143acb11d1a66c597f │ │ │ │ ├── 5882d0e4313310143acb11d1a66c597f.info │ │ │ │ ├── 589533fb2413e3e4fba7df13a6a75bf2 │ │ │ │ ├── 589533fb2413e3e4fba7df13a6a75bf2.info │ │ │ │ ├── 58ad09607a0d62d458a78d7174665566 │ │ │ │ ├── 58ad09607a0d62d458a78d7174665566.info │ │ │ │ ├── 58e7d991249847640b1534192721c5ea │ │ │ │ └── 58e7d991249847640b1534192721c5ea.info │ │ │ ├── 59/ │ │ │ │ ├── 592f7288ed0df2c4b884e2cd9baac023 │ │ │ │ ├── 592f7288ed0df2c4b884e2cd9baac023.info │ │ │ │ ├── 59d3f5586b341a74c84c8f72144a4568 │ │ │ │ ├── 59d3f5586b341a74c84c8f72144a4568.info │ │ │ │ ├── 59f8146938fff824cb5fd77236b75775 │ │ │ │ ├── 59f8146938fff824cb5fd77236b75775.info │ │ │ │ ├── 59ff995fabb3bac45afa0f96f333e5dc │ │ │ │ └── 59ff995fabb3bac45afa0f96f333e5dc.info │ │ │ ├── 5a/ │ │ │ │ ├── 5a2e98b03511c6f43bc645238cd40857 │ │ │ │ ├── 5a2e98b03511c6f43bc645238cd40857.info │ │ │ │ ├── 5a31542ccf4e8584ca4f60843e9d02d0 │ │ │ │ ├── 5a31542ccf4e8584ca4f60843e9d02d0.info │ │ │ │ ├── 5a7f0d89a47f18c41b6ddf60dfae1bde │ │ │ │ ├── 5a7f0d89a47f18c41b6ddf60dfae1bde.info │ │ │ │ ├── 5a8c170a1ec28a148ab78df2460a3135 │ │ │ │ ├── 5a8c170a1ec28a148ab78df2460a3135.info │ │ │ │ ├── 5aa8f57287fc17149bcd798be813180b │ │ │ │ ├── 5aa8f57287fc17149bcd798be813180b.info │ │ │ │ ├── 5af3322745e78aa488fca5a2090f8755 │ │ │ │ └── 5af3322745e78aa488fca5a2090f8755.info │ │ │ ├── 5b/ │ │ │ │ ├── 5b00473355622524394628f7ec51808d │ │ │ │ ├── 5b00473355622524394628f7ec51808d.info │ │ │ │ ├── 5b24618beecc3bf41acadfcf2246d772 │ │ │ │ ├── 5b24618beecc3bf41acadfcf2246d772.info │ │ │ │ ├── 5b2eeca598284bd4abb4a15c30df1576 │ │ │ │ ├── 5b2eeca598284bd4abb4a15c30df1576.info │ │ │ │ ├── 5b3bd7a976306c9449ba84e0591e8a0f │ │ │ │ ├── 5b3bd7a976306c9449ba84e0591e8a0f.info │ │ │ │ ├── 5b3e90046c38f1d4dad2e0d5a79e871c │ │ │ │ ├── 5b3e90046c38f1d4dad2e0d5a79e871c.info │ │ │ │ ├── 5b5c6a576605b3c4aab7d27193785f27 │ │ │ │ ├── 5b5c6a576605b3c4aab7d27193785f27.info │ │ │ │ ├── 5b60206b4b7ac1043ba19efe7ecfd5be │ │ │ │ ├── 5b60206b4b7ac1043ba19efe7ecfd5be.info │ │ │ │ ├── 5b6cac4a98010394791c66942a33caf4 │ │ │ │ ├── 5b6cac4a98010394791c66942a33caf4.info │ │ │ │ ├── 5b994928117e3db418da69c821da7e19 │ │ │ │ ├── 5b994928117e3db418da69c821da7e19.info │ │ │ │ ├── 5ba130fc1db953547a50bcf5c162a3e8 │ │ │ │ ├── 5ba130fc1db953547a50bcf5c162a3e8.info │ │ │ │ ├── 5bcb408b7b5e4d346aeb4860ab1d9d9b │ │ │ │ └── 5bcb408b7b5e4d346aeb4860ab1d9d9b.info │ │ │ ├── 5c/ │ │ │ │ ├── 5c004b1354944164fb076276c289afc1 │ │ │ │ ├── 5c004b1354944164fb076276c289afc1.info │ │ │ │ ├── 5c15bf0966eb95847a4260d830a30d30 │ │ │ │ ├── 5c15bf0966eb95847a4260d830a30d30.info │ │ │ │ ├── 5c9c9f62af2efb948a1974650039e2db │ │ │ │ └── 5c9c9f62af2efb948a1974650039e2db.info │ │ │ ├── 5d/ │ │ │ │ ├── 5d4d7b45df12a6845beb7d6a034a41a2 │ │ │ │ ├── 5d4d7b45df12a6845beb7d6a034a41a2.info │ │ │ │ ├── 5d4de3d4682a8d641907cc75e4fb950e │ │ │ │ ├── 5d4de3d4682a8d641907cc75e4fb950e.info │ │ │ │ ├── 5d7f0d6acfced954682a89e7002c04d9 │ │ │ │ ├── 5d7f0d6acfced954682a89e7002c04d9.info │ │ │ │ ├── 5da62a0c1c5218c4aa16b74546a7822d │ │ │ │ ├── 5da62a0c1c5218c4aa16b74546a7822d.info │ │ │ │ ├── 5da77d4d078922b4c8466e9e35fb3f5e │ │ │ │ ├── 5da77d4d078922b4c8466e9e35fb3f5e.info │ │ │ │ ├── 5da88f348abcbd94585671a69c672781 │ │ │ │ ├── 5da88f348abcbd94585671a69c672781.info │ │ │ │ ├── 5ddd9f7d3cce6724696a33752ab2f5a4 │ │ │ │ ├── 5ddd9f7d3cce6724696a33752ab2f5a4.info │ │ │ │ ├── 5df3c21c5237c994db89660fbdfee07d │ │ │ │ └── 5df3c21c5237c994db89660fbdfee07d.info │ │ │ ├── 5e/ │ │ │ │ ├── 5e726086cd652f82087d59d67d2c24cd │ │ │ │ ├── 5e726086cd652f82087d59d67d2c24cd.info │ │ │ │ ├── 5e83f8baac96eaa47bdd9ca781cd2002 │ │ │ │ ├── 5e83f8baac96eaa47bdd9ca781cd2002.info │ │ │ │ ├── 5ea6a8a826704f743b3b0ce3e9d3c9a9 │ │ │ │ ├── 5ea6a8a826704f743b3b0ce3e9d3c9a9.info │ │ │ │ ├── 5ea9f573d4b800a49b9d83a1f61c0a88 │ │ │ │ ├── 5ea9f573d4b800a49b9d83a1f61c0a88.info │ │ │ │ ├── 5ebb87899ca30b743bb4274bc00c02b4 │ │ │ │ ├── 5ebb87899ca30b743bb4274bc00c02b4.info │ │ │ │ ├── 5ebeb75bd91642048bb3f6c1939fde66 │ │ │ │ ├── 5ebeb75bd91642048bb3f6c1939fde66.info │ │ │ │ ├── 5ec95f4d5b2d1f14e9ff8682562553f9 │ │ │ │ ├── 5ec95f4d5b2d1f14e9ff8682562553f9.info │ │ │ │ ├── 5ecec8cdc3ff99e4a9c65635d7e6b043 │ │ │ │ └── 5ecec8cdc3ff99e4a9c65635d7e6b043.info │ │ │ ├── 5f/ │ │ │ │ ├── 5f31f28cc64c91042976555c016ffd5f │ │ │ │ ├── 5f31f28cc64c91042976555c016ffd5f.info │ │ │ │ ├── 5f603f10b9ec26841b2ecb6003dc1d0e │ │ │ │ ├── 5f603f10b9ec26841b2ecb6003dc1d0e.info │ │ │ │ ├── 5f7201a12d95ffc409449d95f23cf332 │ │ │ │ ├── 5f7201a12d95ffc409449d95f23cf332.info │ │ │ │ ├── 5f875a14565308a40a5262d2504da705 │ │ │ │ ├── 5f875a14565308a40a5262d2504da705.info │ │ │ │ ├── 5fc988a1d5b04aee9a5222502b201a45 │ │ │ │ └── 5fc988a1d5b04aee9a5222502b201a45.info │ │ │ ├── 60/ │ │ │ │ ├── 600f4b74746dbf944901257f81a8af6d │ │ │ │ ├── 600f4b74746dbf944901257f81a8af6d.info │ │ │ │ ├── 6023f2b823fc19b4e4a90875281ff117 │ │ │ │ ├── 6023f2b823fc19b4e4a90875281ff117.info │ │ │ │ ├── 6055be8ebefd69e48b49212b09b47b2f │ │ │ │ └── 6055be8ebefd69e48b49212b09b47b2f.info │ │ │ ├── 61/ │ │ │ │ ├── 6124ad3c57404c3429a93ca37df030e9 │ │ │ │ ├── 6124ad3c57404c3429a93ca37df030e9.info │ │ │ │ ├── 61a20120cddc53849bbc10fc805ffe3e │ │ │ │ ├── 61a20120cddc53849bbc10fc805ffe3e.info │ │ │ │ ├── 61d491d99e9292c4a81d7d01a74781ea │ │ │ │ ├── 61d491d99e9292c4a81d7d01a74781ea.info │ │ │ │ ├── 61e236e8570a95e4eb754fb291e102e0 │ │ │ │ └── 61e236e8570a95e4eb754fb291e102e0.info │ │ │ ├── 62/ │ │ │ │ ├── 621a76c0c3927aa45aba7d2ad0c8e1c8 │ │ │ │ ├── 621a76c0c3927aa45aba7d2ad0c8e1c8.info │ │ │ │ ├── 621fd19bcb071b64aa1d68f0271aa780 │ │ │ │ ├── 621fd19bcb071b64aa1d68f0271aa780.info │ │ │ │ ├── 623c79a1e113b4941afdbfc88d19e8fd │ │ │ │ └── 623c79a1e113b4941afdbfc88d19e8fd.info │ │ │ ├── 63/ │ │ │ │ ├── 63118a0c9ee42ac46b7f30e793177a76 │ │ │ │ ├── 63118a0c9ee42ac46b7f30e793177a76.info │ │ │ │ ├── 63572993f2104574099a48392460b211 │ │ │ │ ├── 63572993f2104574099a48392460b211.info │ │ │ │ ├── 6366ee97f6b541449155028b9487355a │ │ │ │ ├── 6366ee97f6b541449155028b9487355a.info │ │ │ │ ├── 63cd91d36b6b0e4479ef6e61ad4f6f9a │ │ │ │ ├── 63cd91d36b6b0e4479ef6e61ad4f6f9a.info │ │ │ │ ├── 63f2caa33e79582448112b2e286d576d │ │ │ │ └── 63f2caa33e79582448112b2e286d576d.info │ │ │ ├── 64/ │ │ │ │ ├── 640125adae259fe47a36be84e510a46e │ │ │ │ ├── 640125adae259fe47a36be84e510a46e.info │ │ │ │ ├── 645165c8169474bfbbeb8fb0bcfd26f5 │ │ │ │ ├── 645165c8169474bfbbeb8fb0bcfd26f5.info │ │ │ │ ├── 64689f8b25eadac4da519e96f514b653 │ │ │ │ ├── 64689f8b25eadac4da519e96f514b653.info │ │ │ │ ├── 647e1bbd3809b30459d946b4a1ddf22b │ │ │ │ ├── 647e1bbd3809b30459d946b4a1ddf22b.info │ │ │ │ ├── 64b9fad609434c489c32b1cdf2004a1c │ │ │ │ └── 64b9fad609434c489c32b1cdf2004a1c.info │ │ │ ├── 65/ │ │ │ │ ├── 6546d7765b4165b40850b3667f981c26 │ │ │ │ ├── 6546d7765b4165b40850b3667f981c26.info │ │ │ │ ├── 656e461844099ae43a609ff6109b0877 │ │ │ │ ├── 656e461844099ae43a609ff6109b0877.info │ │ │ │ ├── 65701ebe8bada6b4785e9c7afe7f5bee │ │ │ │ ├── 65701ebe8bada6b4785e9c7afe7f5bee.info │ │ │ │ ├── 658c1fb149e7498aa072b0c0f3bf13f0 │ │ │ │ ├── 658c1fb149e7498aa072b0c0f3bf13f0.info │ │ │ │ ├── 65b045927b3948f43afb31234936c6aa │ │ │ │ ├── 65b045927b3948f43afb31234936c6aa.info │ │ │ │ ├── 65f3a4c67e4927a478b7036bae1da0e3 │ │ │ │ ├── 65f3a4c67e4927a478b7036bae1da0e3.info │ │ │ │ ├── 65fb6da362a78334ab360a125cfafdaf │ │ │ │ └── 65fb6da362a78334ab360a125cfafdaf.info │ │ │ ├── 66/ │ │ │ │ ├── 661266b8a30572e4fb9365bba3866896 │ │ │ │ ├── 661266b8a30572e4fb9365bba3866896.info │ │ │ │ ├── 667a99762bdf5484fbaa02573fd396e2 │ │ │ │ ├── 667a99762bdf5484fbaa02573fd396e2.info │ │ │ │ ├── 667c6ad86a0b7a548aaa5c287f2c2861 │ │ │ │ ├── 667c6ad86a0b7a548aaa5c287f2c2861.info │ │ │ │ ├── 66b2b8fd1d9b4bc4c96b07335ad822f3 │ │ │ │ ├── 66b2b8fd1d9b4bc4c96b07335ad822f3.info │ │ │ │ ├── 66c95bb3c74257f41bae2622511dc02d │ │ │ │ └── 66c95bb3c74257f41bae2622511dc02d.info │ │ │ ├── 67/ │ │ │ │ ├── 6773203120b27984d9a8572fa3564f03 │ │ │ │ ├── 6773203120b27984d9a8572fa3564f03.info │ │ │ │ ├── 67db9e8f0e2ae9c40bc1e2b64352a6b4 │ │ │ │ ├── 67db9e8f0e2ae9c40bc1e2b64352a6b4.info │ │ │ │ ├── 67e3583b91179094094c6a188b232262 │ │ │ │ ├── 67e3583b91179094094c6a188b232262.info │ │ │ │ ├── 67e9c6cf60c57a54f9f4db1bc33fd2e3 │ │ │ │ ├── 67e9c6cf60c57a54f9f4db1bc33fd2e3.info │ │ │ │ ├── 67ee43b2f6148de40861b289b0e00591 │ │ │ │ └── 67ee43b2f6148de40861b289b0e00591.info │ │ │ ├── 68/ │ │ │ │ ├── 685f63932bebd0c4db02ee14845191e2 │ │ │ │ ├── 685f63932bebd0c4db02ee14845191e2.info │ │ │ │ ├── 68993ba529ae04440916cb7c23bf3279 │ │ │ │ ├── 68993ba529ae04440916cb7c23bf3279.info │ │ │ │ ├── 68a48d1900320ed458e118415857faf6 │ │ │ │ ├── 68a48d1900320ed458e118415857faf6.info │ │ │ │ ├── 68cb547af0187634aad591a09c01cd5b │ │ │ │ ├── 68cb547af0187634aad591a09c01cd5b.info │ │ │ │ ├── 68e5dc8bfd5d72647a93b7f2e1da831a │ │ │ │ ├── 68e5dc8bfd5d72647a93b7f2e1da831a.info │ │ │ │ ├── 68eedd4e5b33b37429c02c4add0036fe │ │ │ │ └── 68eedd4e5b33b37429c02c4add0036fe.info │ │ │ ├── 69/ │ │ │ │ ├── 6901fab4d5157ac48b9f263730387c03 │ │ │ │ ├── 6901fab4d5157ac48b9f263730387c03.info │ │ │ │ ├── 691475c57a824010be0c6f474caeb7e1 │ │ │ │ ├── 691475c57a824010be0c6f474caeb7e1.info │ │ │ │ ├── 691db8cb70c4426a8ae718465c21345f │ │ │ │ ├── 691db8cb70c4426a8ae718465c21345f.info │ │ │ │ ├── 6965880f76f40194593cb53a88f74005 │ │ │ │ ├── 6965880f76f40194593cb53a88f74005.info │ │ │ │ ├── 698b660e9477f4f16abad03ec00ce38c │ │ │ │ ├── 698b660e9477f4f16abad03ec00ce38c.info │ │ │ │ ├── 69ae55f76840b2849ba56cfb53a17df0 │ │ │ │ ├── 69ae55f76840b2849ba56cfb53a17df0.info │ │ │ │ ├── 69e3979b7029e8a4da2d96b714ba5c3a │ │ │ │ └── 69e3979b7029e8a4da2d96b714ba5c3a.info │ │ │ ├── 6a/ │ │ │ │ ├── 6a022d21eb285c143ae29fc2aca21e11 │ │ │ │ ├── 6a022d21eb285c143ae29fc2aca21e11.info │ │ │ │ ├── 6a44d0f20e3f6cd45881a44134574169 │ │ │ │ ├── 6a44d0f20e3f6cd45881a44134574169.info │ │ │ │ ├── 6a4f0c91a28ece04198b200dd55145d0 │ │ │ │ ├── 6a4f0c91a28ece04198b200dd55145d0.info │ │ │ │ ├── 6a981cd1456bec84b86e1c66773f57f5 │ │ │ │ ├── 6a981cd1456bec84b86e1c66773f57f5.info │ │ │ │ ├── 6ace62d30f494c948b71d5594afce11d │ │ │ │ ├── 6ace62d30f494c948b71d5594afce11d.info │ │ │ │ ├── 6ad632cbcc87f634d9b86006cdffdaf5 │ │ │ │ ├── 6ad632cbcc87f634d9b86006cdffdaf5.info │ │ │ │ ├── 6afb166a156df2d20433d981f4bb2832 │ │ │ │ └── 6afb166a156df2d20433d981f4bb2832.info │ │ │ ├── 6b/ │ │ │ │ ├── 6b01141ed8f74d198965c86f25eb7040 │ │ │ │ ├── 6b01141ed8f74d198965c86f25eb7040.info │ │ │ │ ├── 6b152d671c864bf41bbcc096f5a7567c │ │ │ │ ├── 6b152d671c864bf41bbcc096f5a7567c.info │ │ │ │ ├── 6b1ae1e78552c459d9ce27048ff51c7f │ │ │ │ ├── 6b1ae1e78552c459d9ce27048ff51c7f.info │ │ │ │ ├── 6b259c4003a802847b9ada90744e34c5 │ │ │ │ ├── 6b259c4003a802847b9ada90744e34c5.info │ │ │ │ ├── 6b32b6725087a0d4bb1670818d26996e │ │ │ │ ├── 6b32b6725087a0d4bb1670818d26996e.info │ │ │ │ ├── 6b72875690e0f7343911e06af3145bd5 │ │ │ │ ├── 6b72875690e0f7343911e06af3145bd5.info │ │ │ │ ├── 6ba7805325c426c43b8e85b5be4eae36 │ │ │ │ ├── 6ba7805325c426c43b8e85b5be4eae36.info │ │ │ │ ├── 6bfec54ce89b0b642a65d44def023b99 │ │ │ │ └── 6bfec54ce89b0b642a65d44def023b99.info │ │ │ ├── 6c/ │ │ │ │ ├── 6c3d52cc5c46d7946a920e21901ff38e │ │ │ │ ├── 6c3d52cc5c46d7946a920e21901ff38e.info │ │ │ │ ├── 6c61ba0c209bcc74f83e3650039ebdf9 │ │ │ │ ├── 6c61ba0c209bcc74f83e3650039ebdf9.info │ │ │ │ ├── 6ca745fb561cbf640b6e603f95662fa0 │ │ │ │ ├── 6ca745fb561cbf640b6e603f95662fa0.info │ │ │ │ ├── 6cccd50ebf7384242bda4d7bcb282ebf │ │ │ │ └── 6cccd50ebf7384242bda4d7bcb282ebf.info │ │ │ ├── 6d/ │ │ │ │ ├── 6d16f2e78a356d34c9a32108929de932 │ │ │ │ ├── 6d16f2e78a356d34c9a32108929de932.info │ │ │ │ ├── 6d437b997e074079b4b2f6e395394f4b │ │ │ │ ├── 6d437b997e074079b4b2f6e395394f4b.info │ │ │ │ ├── 6d468ee3657be7a43a2ef2178ec14239 │ │ │ │ ├── 6d468ee3657be7a43a2ef2178ec14239.info │ │ │ │ ├── 6d56244f8c39a851975d3c0bd432c66f │ │ │ │ ├── 6d56244f8c39a851975d3c0bd432c66f.info │ │ │ │ ├── 6d5833966abeadb429de247e4316eef4 │ │ │ │ ├── 6d5833966abeadb429de247e4316eef4.info │ │ │ │ ├── 6d6f82a762acb4417b895d3babc790f9 │ │ │ │ ├── 6d6f82a762acb4417b895d3babc790f9.info │ │ │ │ ├── 6d768b1bb52e2c64ba818933dbdd8452 │ │ │ │ ├── 6d768b1bb52e2c64ba818933dbdd8452.info │ │ │ │ ├── 6d9df2bc198c417db00037803568139c │ │ │ │ ├── 6d9df2bc198c417db00037803568139c.info │ │ │ │ ├── 6dbcf248c987476181a37f01a1814975 │ │ │ │ ├── 6dbcf248c987476181a37f01a1814975.info │ │ │ │ ├── 6de79ae237e51554da96fd28f68b66a6 │ │ │ │ └── 6de79ae237e51554da96fd28f68b66a6.info │ │ │ ├── 6e/ │ │ │ │ ├── 6e0e62db88935c74288c97c907243bd0 │ │ │ │ ├── 6e0e62db88935c74288c97c907243bd0.info │ │ │ │ ├── 6e1c8b97ec8aa0464e92506ffe099558 │ │ │ │ ├── 6e1c8b97ec8aa0464e92506ffe099558.info │ │ │ │ ├── 6e7c80eefe2def5459e0b486b3ab96e2 │ │ │ │ ├── 6e7c80eefe2def5459e0b486b3ab96e2.info │ │ │ │ ├── 6ecb9e17e44feb84cb80451fa27b09fe │ │ │ │ └── 6ecb9e17e44feb84cb80451fa27b09fe.info │ │ │ ├── 6f/ │ │ │ │ ├── 6f1c7ebc8ac78cb951be24c238cbd3ba │ │ │ │ ├── 6f1c7ebc8ac78cb951be24c238cbd3ba.info │ │ │ │ ├── 6f25fb081e85cb743b272c2f7fbc2f6b │ │ │ │ ├── 6f25fb081e85cb743b272c2f7fbc2f6b.info │ │ │ │ ├── 6f515f8ecd3b6a546b90abaae2553f99 │ │ │ │ ├── 6f515f8ecd3b6a546b90abaae2553f99.info │ │ │ │ ├── 6f516f1ec21a54a59a92bf99db2d9535 │ │ │ │ ├── 6f516f1ec21a54a59a92bf99db2d9535.info │ │ │ │ ├── 6f72aa6eab9392548b9e9d92eb6b2ef8 │ │ │ │ ├── 6f72aa6eab9392548b9e9d92eb6b2ef8.info │ │ │ │ ├── 6f768c3714a34a549960ea903fbadcc2 │ │ │ │ ├── 6f768c3714a34a549960ea903fbadcc2.info │ │ │ │ ├── 6fdea2af3daa40fe8f88e5e9cfc17abb │ │ │ │ └── 6fdea2af3daa40fe8f88e5e9cfc17abb.info │ │ │ ├── 70/ │ │ │ │ ├── 7004c8cc6d477784e8d85fbad56de5f8 │ │ │ │ ├── 7004c8cc6d477784e8d85fbad56de5f8.info │ │ │ │ ├── 7043e9a330ac2d84a80a965ada4589ad │ │ │ │ ├── 7043e9a330ac2d84a80a965ada4589ad.info │ │ │ │ ├── 7065397ff8184621aa3ca4f854491259 │ │ │ │ ├── 7065397ff8184621aa3ca4f854491259.info │ │ │ │ ├── 7071adaea60f6124d9ab426b002d5afa │ │ │ │ ├── 7071adaea60f6124d9ab426b002d5afa.info │ │ │ │ ├── 70a190a1b304d1e43995af35d09231d6 │ │ │ │ ├── 70a190a1b304d1e43995af35d09231d6.info │ │ │ │ ├── 70b265ed18dc14041bedc0263d4578ef │ │ │ │ ├── 70b265ed18dc14041bedc0263d4578ef.info │ │ │ │ ├── 70d4d75a2877243758b0750cbc75b6eb │ │ │ │ ├── 70d4d75a2877243758b0750cbc75b6eb.info │ │ │ │ ├── 70eae1897c9d308448eb3bb0b5be9f58 │ │ │ │ ├── 70eae1897c9d308448eb3bb0b5be9f58.info │ │ │ │ ├── 70f955bbb437a494888ef54d97abb474 │ │ │ │ └── 70f955bbb437a494888ef54d97abb474.info │ │ │ ├── 71/ │ │ │ │ ├── 7116e04a377b195458798657c617e324 │ │ │ │ ├── 7116e04a377b195458798657c617e324.info │ │ │ │ ├── 718966f960cb50643986195e5fe953ca │ │ │ │ ├── 718966f960cb50643986195e5fe953ca.info │ │ │ │ ├── 71bb46b59a9a7a346bbab1e185c723df │ │ │ │ ├── 71bb46b59a9a7a346bbab1e185c723df.info │ │ │ │ ├── 71c1514a6bd24e1e882cebbe1904ce04 │ │ │ │ └── 71c1514a6bd24e1e882cebbe1904ce04.info │ │ │ ├── 72/ │ │ │ │ ├── 7241c7dc25374fc1a6ab3ef9da79c363 │ │ │ │ ├── 7241c7dc25374fc1a6ab3ef9da79c363.info │ │ │ │ ├── 725600e98a048ad46aacb96a8bb155cd │ │ │ │ ├── 725600e98a048ad46aacb96a8bb155cd.info │ │ │ │ ├── 728d2c19676ea3743aaa087aa28c4a16 │ │ │ │ └── 728d2c19676ea3743aaa087aa28c4a16.info │ │ │ ├── 73/ │ │ │ │ ├── 7341c0cd0aad4994e8fa461cb443aa7d │ │ │ │ ├── 7341c0cd0aad4994e8fa461cb443aa7d.info │ │ │ │ ├── 735d54f21944f834f931716514c87a84 │ │ │ │ ├── 735d54f21944f834f931716514c87a84.info │ │ │ │ ├── 73deb9b8722aa284eab27c4dc90956c6 │ │ │ │ └── 73deb9b8722aa284eab27c4dc90956c6.info │ │ │ ├── 74/ │ │ │ │ ├── 740b3785866edda4b8d1e1a05570a5f8 │ │ │ │ ├── 740b3785866edda4b8d1e1a05570a5f8.info │ │ │ │ ├── 742654cad2425334696ba6ed4495cfef │ │ │ │ ├── 742654cad2425334696ba6ed4495cfef.info │ │ │ │ ├── 74374298effb78d47b85450f7f724cef │ │ │ │ ├── 74374298effb78d47b85450f7f724cef.info │ │ │ │ ├── 743879b4db4bc1a4b829aae4386f4acf │ │ │ │ ├── 743879b4db4bc1a4b829aae4386f4acf.info │ │ │ │ ├── 7496af95dfe67cf429ac65edaaf99106 │ │ │ │ └── 7496af95dfe67cf429ac65edaaf99106.info │ │ │ ├── 75/ │ │ │ │ ├── 750aad009559b814dbc27001341fc1c3 │ │ │ │ ├── 750aad009559b814dbc27001341fc1c3.info │ │ │ │ ├── 75df57ccb1e44c64085399277405e1ca │ │ │ │ ├── 75df57ccb1e44c64085399277405e1ca.info │ │ │ │ ├── 75e7d7a9a57458841a85fe42d9c9141f │ │ │ │ └── 75e7d7a9a57458841a85fe42d9c9141f.info │ │ │ ├── 76/ │ │ │ │ ├── 7602252bdb82b8d45ae3483c3a00d3e1 │ │ │ │ ├── 7602252bdb82b8d45ae3483c3a00d3e1.info │ │ │ │ ├── 7693972390a4ed841a986c0c452c1058 │ │ │ │ ├── 7693972390a4ed841a986c0c452c1058.info │ │ │ │ ├── 769f6f5dd7c8f2d4c9ab1caba0bd2628 │ │ │ │ ├── 769f6f5dd7c8f2d4c9ab1caba0bd2628.info │ │ │ │ ├── 76b6bf32a6fcf934aab8c529bddccc81 │ │ │ │ ├── 76b6bf32a6fcf934aab8c529bddccc81.info │ │ │ │ ├── 76c392e42b5098c458856cdf6ecaaaa1 │ │ │ │ ├── 76c392e42b5098c458856cdf6ecaaaa1.info │ │ │ │ ├── 76c82729ad712f14bae1a8a279c52ac3 │ │ │ │ └── 76c82729ad712f14bae1a8a279c52ac3.info │ │ │ ├── 77/ │ │ │ │ ├── 77476292f9fa4905a787e6417853846b │ │ │ │ ├── 77476292f9fa4905a787e6417853846b.info │ │ │ │ ├── 7748a1d3701ac824ea7f366ba0388f5d │ │ │ │ ├── 7748a1d3701ac824ea7f366ba0388f5d.info │ │ │ │ ├── 77f432980bb30084299a138e15c6f571 │ │ │ │ └── 77f432980bb30084299a138e15c6f571.info │ │ │ ├── 78/ │ │ │ │ ├── 78213b1ce4da5e6438195d405c9da0f5 │ │ │ │ ├── 78213b1ce4da5e6438195d405c9da0f5.info │ │ │ │ ├── 782c49e6e68074dc7ba12c95537825ce │ │ │ │ ├── 782c49e6e68074dc7ba12c95537825ce.info │ │ │ │ ├── 782de34c17796430ba8d0ceddb60944e │ │ │ │ ├── 782de34c17796430ba8d0ceddb60944e.info │ │ │ │ ├── 7883cd788d83a71478342eef943e8150 │ │ │ │ ├── 7883cd788d83a71478342eef943e8150.info │ │ │ │ ├── 7895e41fc42ee304cbd33be552917a5a │ │ │ │ └── 7895e41fc42ee304cbd33be552917a5a.info │ │ │ ├── 79/ │ │ │ │ ├── 794f3951c48395848920fdb593a2ae38 │ │ │ │ ├── 794f3951c48395848920fdb593a2ae38.info │ │ │ │ ├── 798968d841703b54bb9d08b1da6bc52f │ │ │ │ ├── 798968d841703b54bb9d08b1da6bc52f.info │ │ │ │ ├── 79ced2556f0af814a840b86232613ff1 │ │ │ │ ├── 79ced2556f0af814a840b86232613ff1.info │ │ │ │ ├── 79ff392d1bde4ad78a3836a4a480392d │ │ │ │ └── 79ff392d1bde4ad78a3836a4a480392d.info │ │ │ ├── 7a/ │ │ │ │ ├── 7a24ec4b5c3e08e47bf50c8298c1fe0d │ │ │ │ ├── 7a24ec4b5c3e08e47bf50c8298c1fe0d.info │ │ │ │ ├── 7a892c920c8ad2848b469ec9579c5219 │ │ │ │ ├── 7a892c920c8ad2848b469ec9579c5219.info │ │ │ │ ├── 7a98125502f715b4b83cfb77b434e436 │ │ │ │ ├── 7a98125502f715b4b83cfb77b434e436.info │ │ │ │ ├── 7af6ac3e6b51b8d4aab04adc85b8de2f │ │ │ │ └── 7af6ac3e6b51b8d4aab04adc85b8de2f.info │ │ │ ├── 7b/ │ │ │ │ ├── 7b743370ac3e4ec2a1668f5455a8ef8a │ │ │ │ ├── 7b743370ac3e4ec2a1668f5455a8ef8a.info │ │ │ │ ├── 7bd96d76711152648a736c4d28d865f2 │ │ │ │ ├── 7bd96d76711152648a736c4d28d865f2.info │ │ │ │ ├── 7be84a49bb2cd7e4a9ed097ba22794d0 │ │ │ │ └── 7be84a49bb2cd7e4a9ed097ba22794d0.info │ │ │ ├── 7c/ │ │ │ │ ├── 7c04f0dfa9243c04681a55d90d3ff3fc │ │ │ │ ├── 7c04f0dfa9243c04681a55d90d3ff3fc.info │ │ │ │ ├── 7c6295db74da28645bf49db58b7c9c65 │ │ │ │ ├── 7c6295db74da28645bf49db58b7c9c65.info │ │ │ │ ├── 7cfaad4e53832d94c9421d2dd1ad82f7 │ │ │ │ └── 7cfaad4e53832d94c9421d2dd1ad82f7.info │ │ │ ├── 7d/ │ │ │ │ ├── 7d36034e63ad8254b9b2f55280fcc040 │ │ │ │ ├── 7d36034e63ad8254b9b2f55280fcc040.info │ │ │ │ ├── 7d3aa106cfe752241997b3759bf80163 │ │ │ │ ├── 7d3aa106cfe752241997b3759bf80163.info │ │ │ │ ├── 7d7bd4bcc815cfb44b9990c29dabdb9f │ │ │ │ ├── 7d7bd4bcc815cfb44b9990c29dabdb9f.info │ │ │ │ ├── 7db44d889e0cbbf4281132a752f96ce1 │ │ │ │ └── 7db44d889e0cbbf4281132a752f96ce1.info │ │ │ ├── 7e/ │ │ │ │ ├── 7e609b27ad2caa14c83dd9951b6c13c6 │ │ │ │ ├── 7e609b27ad2caa14c83dd9951b6c13c6.info │ │ │ │ ├── 7ef6801a8b664544aa9f2ab1bc1f8b60 │ │ │ │ ├── 7ef6801a8b664544aa9f2ab1bc1f8b60.info │ │ │ │ ├── 7ef8348b8ea834d7e1bc214b07f7fb87 │ │ │ │ └── 7ef8348b8ea834d7e1bc214b07f7fb87.info │ │ │ ├── 7f/ │ │ │ │ ├── 7f27709c942d91541be1fd6aa5cb3d78 │ │ │ │ ├── 7f27709c942d91541be1fd6aa5cb3d78.info │ │ │ │ ├── 7f65567c9026afb4db5de3355accc636 │ │ │ │ ├── 7f65567c9026afb4db5de3355accc636.info │ │ │ │ ├── 7fc2147e42d71644aad0eaf9a3526249 │ │ │ │ └── 7fc2147e42d71644aad0eaf9a3526249.info │ │ │ ├── 80/ │ │ │ │ ├── 803abab0f7e17044db56f8760186dbd1 │ │ │ │ ├── 803abab0f7e17044db56f8760186dbd1.info │ │ │ │ ├── 806de5a9211448c8b65c8435ebb48dd4 │ │ │ │ ├── 806de5a9211448c8b65c8435ebb48dd4.info │ │ │ │ ├── 80ae83fdf1fb2c649bccb8c293b94556 │ │ │ │ ├── 80ae83fdf1fb2c649bccb8c293b94556.info │ │ │ │ ├── 80b10e1c58509a449a3c5aecc07d4455 │ │ │ │ ├── 80b10e1c58509a449a3c5aecc07d4455.info │ │ │ │ ├── 80beef77cb19e713c7c2d481b65ed485 │ │ │ │ └── 80beef77cb19e713c7c2d481b65ed485.info │ │ │ ├── 81/ │ │ │ │ ├── 811d999912a5f3f459a637aad029fbc8 │ │ │ │ ├── 811d999912a5f3f459a637aad029fbc8.info │ │ │ │ ├── 812aaaefaab404448a3e4db49dfa5206 │ │ │ │ ├── 812aaaefaab404448a3e4db49dfa5206.info │ │ │ │ ├── 8143d3a8390f2c64685e3bc272bd9e90 │ │ │ │ ├── 8143d3a8390f2c64685e3bc272bd9e90.info │ │ │ │ ├── 81a142c61a4e14d46bb21b02548ad24d │ │ │ │ ├── 81a142c61a4e14d46bb21b02548ad24d.info │ │ │ │ ├── 81ed8c76d2bc4a4c95d092c98af4e58f │ │ │ │ └── 81ed8c76d2bc4a4c95d092c98af4e58f.info │ │ │ ├── 82/ │ │ │ │ ├── 821f5482c5a3f4389885f4432433f56f │ │ │ │ ├── 821f5482c5a3f4389885f4432433f56f.info │ │ │ │ ├── 826b6becaef90fb458eedebe4c2f3664 │ │ │ │ ├── 826b6becaef90fb458eedebe4c2f3664.info │ │ │ │ ├── 828075bc53f2de84982a943870529b7b │ │ │ │ ├── 828075bc53f2de84982a943870529b7b.info │ │ │ │ ├── 82a8ce43816925d4b971951094cb755c │ │ │ │ ├── 82a8ce43816925d4b971951094cb755c.info │ │ │ │ ├── 82bf3f737dec0be43a60891958a8da87 │ │ │ │ ├── 82bf3f737dec0be43a60891958a8da87.info │ │ │ │ ├── 82cd92ffc29383742932b27ca414c80f │ │ │ │ └── 82cd92ffc29383742932b27ca414c80f.info │ │ │ ├── 83/ │ │ │ │ ├── 83088ba2132cbc940b7ca0c679a02b0d │ │ │ │ ├── 83088ba2132cbc940b7ca0c679a02b0d.info │ │ │ │ ├── 8313ea704470a264295ec9e09aec6ebc │ │ │ │ ├── 8313ea704470a264295ec9e09aec6ebc.info │ │ │ │ ├── 83154bbefa9fb00469e42ff5014345a2 │ │ │ │ ├── 83154bbefa9fb00469e42ff5014345a2.info │ │ │ │ ├── 833143c443f979e44ae0b8ed899e3b59 │ │ │ │ ├── 833143c443f979e44ae0b8ed899e3b59.info │ │ │ │ ├── 8349e42a2b30c7a4abd8678c203428ba │ │ │ │ ├── 8349e42a2b30c7a4abd8678c203428ba.info │ │ │ │ ├── 83eda34b7da01e04aa894f268158b0c0 │ │ │ │ └── 83eda34b7da01e04aa894f268158b0c0.info │ │ │ ├── 84/ │ │ │ │ ├── 8413ca0e506d42a1a4bd9769f204ad16 │ │ │ │ ├── 8413ca0e506d42a1a4bd9769f204ad16.info │ │ │ │ ├── 844873d1afe1c3142ab922324950e1dd │ │ │ │ ├── 844873d1afe1c3142ab922324950e1dd.info │ │ │ │ ├── 84a92b25f83d49b9bc132d206b370281 │ │ │ │ ├── 84a92b25f83d49b9bc132d206b370281.info │ │ │ │ ├── 84b5362754a9d934ba259398b757d0be │ │ │ │ ├── 84b5362754a9d934ba259398b757d0be.info │ │ │ │ ├── 84d86c98104d94063ad70bc591530f65 │ │ │ │ └── 84d86c98104d94063ad70bc591530f65.info │ │ │ ├── 85/ │ │ │ │ ├── 850af9f3bf6d14143baf2ecfbf25db52 │ │ │ │ ├── 850af9f3bf6d14143baf2ecfbf25db52.info │ │ │ │ ├── 850c54ee0b9e1aa740b1c67792eb1f26 │ │ │ │ ├── 850c54ee0b9e1aa740b1c67792eb1f26.info │ │ │ │ ├── 853edc343b78a7c4c81cbb3851d48c0a │ │ │ │ ├── 853edc343b78a7c4c81cbb3851d48c0a.info │ │ │ │ ├── 8573c56c34e616248a3881b2c56280ef │ │ │ │ ├── 8573c56c34e616248a3881b2c56280ef.info │ │ │ │ ├── 85dd7af03f02aea4aae13a3945e3b313 │ │ │ │ ├── 85dd7af03f02aea4aae13a3945e3b313.info │ │ │ │ ├── 85f3c3a3c2623cd4da1661b0479e2ef2 │ │ │ │ └── 85f3c3a3c2623cd4da1661b0479e2ef2.info │ │ │ ├── 86/ │ │ │ │ ├── 8620e97e7e9859049934889a52248435 │ │ │ │ ├── 8620e97e7e9859049934889a52248435.info │ │ │ │ ├── 8645aa9c3c74fb34ba9499e14fb332b5 │ │ │ │ ├── 8645aa9c3c74fb34ba9499e14fb332b5.info │ │ │ │ ├── 86710e43de46f6f4bac7c8e50813a599 │ │ │ │ ├── 86710e43de46f6f4bac7c8e50813a599.info │ │ │ │ ├── 86cacab070a0a46e99aedb596a32c4fe │ │ │ │ └── 86cacab070a0a46e99aedb596a32c4fe.info │ │ │ ├── 87/ │ │ │ │ ├── 871f8edd56e84b8fb295b10cc3c78f36 │ │ │ │ ├── 871f8edd56e84b8fb295b10cc3c78f36.info │ │ │ │ ├── 872e4b92d663b05489fe34966680c29d │ │ │ │ ├── 872e4b92d663b05489fe34966680c29d.info │ │ │ │ ├── 87357ff0dec4ef348a295235835c6ee4 │ │ │ │ ├── 87357ff0dec4ef348a295235835c6ee4.info │ │ │ │ ├── 874c0713cdc44f549b0161750b48d2c2 │ │ │ │ ├── 874c0713cdc44f549b0161750b48d2c2.info │ │ │ │ ├── 874e40a588dbb1e48bc128d686337d4e │ │ │ │ ├── 874e40a588dbb1e48bc128d686337d4e.info │ │ │ │ ├── 8795e0dd0041d2f44b1fe1959fc9fb53 │ │ │ │ ├── 8795e0dd0041d2f44b1fe1959fc9fb53.info │ │ │ │ ├── 87a1ae9719ec25d44a4dbec20ec0f892 │ │ │ │ ├── 87a1ae9719ec25d44a4dbec20ec0f892.info │ │ │ │ ├── 87ab1bebe13f41f89d5427e7d2c34d58 │ │ │ │ ├── 87ab1bebe13f41f89d5427e7d2c34d58.info │ │ │ │ ├── 87d720faa37005c08600090e04d8c739 │ │ │ │ └── 87d720faa37005c08600090e04d8c739.info │ │ │ ├── 88/ │ │ │ │ ├── 882f1a4147a284f028899b9c018e63eb │ │ │ │ ├── 882f1a4147a284f028899b9c018e63eb.info │ │ │ │ ├── 88338eb35defad644a48718188e8f219 │ │ │ │ ├── 88338eb35defad644a48718188e8f219.info │ │ │ │ ├── 88ed537c17c34f339121fe9a7d6d7a0e │ │ │ │ └── 88ed537c17c34f339121fe9a7d6d7a0e.info │ │ │ ├── 89/ │ │ │ │ ├── 8938e753b3f47374889d5cf3265b563c │ │ │ │ ├── 8938e753b3f47374889d5cf3265b563c.info │ │ │ │ ├── 898bc38486fc899428fbe5bd6adfe473 │ │ │ │ ├── 898bc38486fc899428fbe5bd6adfe473.info │ │ │ │ ├── 89b31ff5ca0a5eb4797ac65d43949807 │ │ │ │ ├── 89b31ff5ca0a5eb4797ac65d43949807.info │ │ │ │ ├── 89b48a03f6f43e94e87cc8d2104d3d4d │ │ │ │ ├── 89b48a03f6f43e94e87cc8d2104d3d4d.info │ │ │ │ ├── 89df79cf5061c394d82abd40383976e5 │ │ │ │ ├── 89df79cf5061c394d82abd40383976e5.info │ │ │ │ ├── 89e0061781af2da4d938cac6c7381fdc │ │ │ │ └── 89e0061781af2da4d938cac6c7381fdc.info │ │ │ ├── 8a/ │ │ │ │ ├── 8a13cbeb2099aca47bb456f49845f86c │ │ │ │ ├── 8a13cbeb2099aca47bb456f49845f86c.info │ │ │ │ ├── 8a4b6301a5afaec4cb87d21383ceb0b3 │ │ │ │ ├── 8a4b6301a5afaec4cb87d21383ceb0b3.info │ │ │ │ ├── 8a8695521f0d02e499659fee002a26c2 │ │ │ │ ├── 8a8695521f0d02e499659fee002a26c2.info │ │ │ │ ├── 8aa8171e088f94069bbd1978a053f7dd │ │ │ │ └── 8aa8171e088f94069bbd1978a053f7dd.info │ │ │ ├── 8b/ │ │ │ │ ├── 8b22792c3b570444eb18cb78c2af3a74 │ │ │ │ ├── 8b22792c3b570444eb18cb78c2af3a74.info │ │ │ │ ├── 8b7d06780fca6fc4384580d3ebed9219 │ │ │ │ ├── 8b7d06780fca6fc4384580d3ebed9219.info │ │ │ │ ├── 8b845b123ab418448a8be2935fa804e0 │ │ │ │ ├── 8b845b123ab418448a8be2935fa804e0.info │ │ │ │ ├── 8bb59cb2f66d156418ca1bd1e2703233 │ │ │ │ ├── 8bb59cb2f66d156418ca1bd1e2703233.info │ │ │ │ ├── 8bc2b083b068f3546a9509c805e0541c │ │ │ │ ├── 8bc2b083b068f3546a9509c805e0541c.info │ │ │ │ ├── 8bc445bb79654bf496c92d0407840a92 │ │ │ │ ├── 8bc445bb79654bf496c92d0407840a92.info │ │ │ │ ├── 8bc74398aa3944646ade4ee78cd57484 │ │ │ │ ├── 8bc74398aa3944646ade4ee78cd57484.info │ │ │ │ ├── 8beed9aab74505d488e6befe54c3f6ef │ │ │ │ └── 8beed9aab74505d488e6befe54c3f6ef.info │ │ │ ├── 8c/ │ │ │ │ ├── 8cc83bff6b39f3d44af0de8320999144 │ │ │ │ └── 8cc83bff6b39f3d44af0de8320999144.info │ │ │ ├── 8d/ │ │ │ │ ├── 8d20eedbe40f0ce41a4c4f633f225de8 │ │ │ │ ├── 8d20eedbe40f0ce41a4c4f633f225de8.info │ │ │ │ ├── 8d34348f8b97a334291f5cf31adc5d67 │ │ │ │ ├── 8d34348f8b97a334291f5cf31adc5d67.info │ │ │ │ ├── 8db4dc37ed52fc24ba715aaa8e0fd20f │ │ │ │ ├── 8db4dc37ed52fc24ba715aaa8e0fd20f.info │ │ │ │ ├── 8df45492ff0815a488744d61efcecba7 │ │ │ │ └── 8df45492ff0815a488744d61efcecba7.info │ │ │ ├── 8e/ │ │ │ │ ├── 8e6115ff67c8ba44ba8780322ca78ef8 │ │ │ │ ├── 8e6115ff67c8ba44ba8780322ca78ef8.info │ │ │ │ ├── 8e78f8a8575e4a04f8337a54e241cdc5 │ │ │ │ └── 8e78f8a8575e4a04f8337a54e241cdc5.info │ │ │ ├── 8f/ │ │ │ │ ├── 8f74c99a65464bb4b86ccb314ee95a7f │ │ │ │ ├── 8f74c99a65464bb4b86ccb314ee95a7f.info │ │ │ │ ├── 8f7652e09069a1943278893d4264401e │ │ │ │ ├── 8f7652e09069a1943278893d4264401e.info │ │ │ │ ├── 8f8b248abe6b4dcebd6cdd0d754717f4 │ │ │ │ └── 8f8b248abe6b4dcebd6cdd0d754717f4.info │ │ │ ├── 90/ │ │ │ │ ├── 900aac3710bc14542a8d164e3f0ff820 │ │ │ │ ├── 900aac3710bc14542a8d164e3f0ff820.info │ │ │ │ ├── 900f1a451c764dc3bdcc0de815a15935 │ │ │ │ ├── 900f1a451c764dc3bdcc0de815a15935.info │ │ │ │ ├── 9014630255533ed42915965b4065cde8 │ │ │ │ ├── 9014630255533ed42915965b4065cde8.info │ │ │ │ ├── 901b761c5c1e22d4e8a3ba7d95bc1f5d │ │ │ │ ├── 901b761c5c1e22d4e8a3ba7d95bc1f5d.info │ │ │ │ ├── 906c12bc9cd95d3963c6d58f62522c78 │ │ │ │ ├── 906c12bc9cd95d3963c6d58f62522c78.info │ │ │ │ ├── 907dff89ca8c76745b031725757e5f8b │ │ │ │ ├── 907dff89ca8c76745b031725757e5f8b.info │ │ │ │ ├── 9085046f02f69544eb97fd06b6048fe2 │ │ │ │ ├── 9085046f02f69544eb97fd06b6048fe2.info │ │ │ │ ├── 90fe1c65e6bb3bc4e90862df7297719e │ │ │ │ └── 90fe1c65e6bb3bc4e90862df7297719e.info │ │ │ ├── 91/ │ │ │ │ ├── 9129183a42052cd43b9c284d6dbd541e │ │ │ │ ├── 9129183a42052cd43b9c284d6dbd541e.info │ │ │ │ ├── 91319408591cec1478efd3c62f9f418a │ │ │ │ ├── 91319408591cec1478efd3c62f9f418a.info │ │ │ │ ├── 91950f78729ab144aa36e94690b28fad │ │ │ │ ├── 91950f78729ab144aa36e94690b28fad.info │ │ │ │ ├── 919d97c1a707113409177d498d31cf51 │ │ │ │ ├── 919d97c1a707113409177d498d31cf51.info │ │ │ │ ├── 91c20d2c22b8b3a4cb6c816bd225591a │ │ │ │ ├── 91c20d2c22b8b3a4cb6c816bd225591a.info │ │ │ │ ├── 91f495459b6e34f419ac123740d798b1 │ │ │ │ └── 91f495459b6e34f419ac123740d798b1.info │ │ │ ├── 92/ │ │ │ │ ├── 92027f7f8cfc4feaa477da0dc38d3d46 │ │ │ │ ├── 92027f7f8cfc4feaa477da0dc38d3d46.info │ │ │ │ ├── 9202fbba95ea8294cb5e718f028f21b0 │ │ │ │ ├── 9202fbba95ea8294cb5e718f028f21b0.info │ │ │ │ ├── 926a61ff0dec44a5aab649acb411e9ad │ │ │ │ ├── 926a61ff0dec44a5aab649acb411e9ad.info │ │ │ │ ├── 9288066c33474b94b6ee5465f4df1cc0 │ │ │ │ ├── 9288066c33474b94b6ee5465f4df1cc0.info │ │ │ │ ├── 928dc55e2c8c3ee4dad33b6d561cb6ea │ │ │ │ ├── 928dc55e2c8c3ee4dad33b6d561cb6ea.info │ │ │ │ ├── 92a378669877c05c6071d0fed687bb95 │ │ │ │ └── 92a378669877c05c6071d0fed687bb95.info │ │ │ ├── 93/ │ │ │ │ ├── 93665e8b67658804d99c4487228cc050 │ │ │ │ ├── 93665e8b67658804d99c4487228cc050.info │ │ │ │ ├── 936bea4b2545c4a4fad2e623b0f6371f │ │ │ │ ├── 936bea4b2545c4a4fad2e623b0f6371f.info │ │ │ │ ├── 936c6340f3468444ebb1785b4c311126 │ │ │ │ ├── 936c6340f3468444ebb1785b4c311126.info │ │ │ │ ├── 9390296e78291b543b2f4a9761ef8139 │ │ │ │ ├── 9390296e78291b543b2f4a9761ef8139.info │ │ │ │ ├── 93eea84e53d0226479c9a584f19427b5 │ │ │ │ ├── 93eea84e53d0226479c9a584f19427b5.info │ │ │ │ ├── 93effba7cf7f3824ab0bd048a27a9c02 │ │ │ │ └── 93effba7cf7f3824ab0bd048a27a9c02.info │ │ │ ├── 94/ │ │ │ │ ├── 94412382cf909c843b9a46a8f6b364f4 │ │ │ │ ├── 94412382cf909c843b9a46a8f6b364f4.info │ │ │ │ ├── 945f4ecec6df62244b9ebcc363833642 │ │ │ │ ├── 945f4ecec6df62244b9ebcc363833642.info │ │ │ │ ├── 949b7e126b3f27940885a6808a15458e │ │ │ │ ├── 949b7e126b3f27940885a6808a15458e.info │ │ │ │ ├── 94a7f67cf7303d94fa3f076bd9f33095 │ │ │ │ └── 94a7f67cf7303d94fa3f076bd9f33095.info │ │ │ ├── 95/ │ │ │ │ ├── 9502550ba4785e3499d6c9251fa2114b │ │ │ │ ├── 9502550ba4785e3499d6c9251fa2114b.info │ │ │ │ ├── 950890083f4907541a6ed06d70959e49 │ │ │ │ ├── 950890083f4907541a6ed06d70959e49.info │ │ │ │ ├── 952b3dc7b47846947b37c8d3ae46579a │ │ │ │ ├── 952b3dc7b47846947b37c8d3ae46579a.info │ │ │ │ ├── 953fab16d15d5885b3600fcd6388b2ad │ │ │ │ ├── 953fab16d15d5885b3600fcd6388b2ad.info │ │ │ │ ├── 9541d86e2fd84c1d9990edf0852d74ab │ │ │ │ ├── 9541d86e2fd84c1d9990edf0852d74ab.info │ │ │ │ ├── 9545c9eb3bf94265810463794fec8334 │ │ │ │ ├── 9545c9eb3bf94265810463794fec8334.info │ │ │ │ ├── 95a2914724952ef40bb590d0607fc878 │ │ │ │ ├── 95a2914724952ef40bb590d0607fc878.info │ │ │ │ ├── 95b719082a664ea45bb56759eed1f271 │ │ │ │ ├── 95b719082a664ea45bb56759eed1f271.info │ │ │ │ ├── 95c91abdcc1ea03458c2ea4e9626a5d8 │ │ │ │ ├── 95c91abdcc1ea03458c2ea4e9626a5d8.info │ │ │ │ ├── 95cdf27b47eb82747ba9e51f41e72a35 │ │ │ │ ├── 95cdf27b47eb82747ba9e51f41e72a35.info │ │ │ │ ├── 95f85adeda79e994f011eb2152cf4fc9 │ │ │ │ └── 95f85adeda79e994f011eb2152cf4fc9.info │ │ │ ├── 96/ │ │ │ │ ├── 961642509dec50b44a293d26240140ec │ │ │ │ ├── 961642509dec50b44a293d26240140ec.info │ │ │ │ ├── 9650d910fcaefb34cb45f121c1993892 │ │ │ │ ├── 9650d910fcaefb34cb45f121c1993892.info │ │ │ │ ├── 9685354eb873b8d4699078b307b0f260 │ │ │ │ ├── 9685354eb873b8d4699078b307b0f260.info │ │ │ │ ├── 968a09f153574430a6e15ae975145768 │ │ │ │ ├── 968a09f153574430a6e15ae975145768.info │ │ │ │ ├── 96b44f7d98314b139324a8a87eb66067 │ │ │ │ ├── 96b44f7d98314b139324a8a87eb66067.info │ │ │ │ ├── 96c503bf059df984c86eecf572370347 │ │ │ │ ├── 96c503bf059df984c86eecf572370347.info │ │ │ │ ├── 96d14b71b907bb52333b2886e665aba6 │ │ │ │ ├── 96d14b71b907bb52333b2886e665aba6.info │ │ │ │ ├── 96e9072453a441618754c478755b3028 │ │ │ │ └── 96e9072453a441618754c478755b3028.info │ │ │ ├── 97/ │ │ │ │ ├── 970e7735a0864fd40842a36d053d08fe │ │ │ │ ├── 970e7735a0864fd40842a36d053d08fe.info │ │ │ │ ├── 9713795381722eb43b623dffba25d115 │ │ │ │ ├── 9713795381722eb43b623dffba25d115.info │ │ │ │ ├── 973b024861c5ae84f869aad614234b04 │ │ │ │ ├── 973b024861c5ae84f869aad614234b04.info │ │ │ │ ├── 976acc75bfafe594cb01142ba21947be │ │ │ │ ├── 976acc75bfafe594cb01142ba21947be.info │ │ │ │ ├── 977190a4db46de442aed27279d247df4 │ │ │ │ ├── 977190a4db46de442aed27279d247df4.info │ │ │ │ ├── 97a05971510726f438153cd4987526fb │ │ │ │ ├── 97a05971510726f438153cd4987526fb.info │ │ │ │ ├── 97d6c87381e3e51488b49f5891490b70 │ │ │ │ ├── 97d6c87381e3e51488b49f5891490b70.info │ │ │ │ ├── 97f2c862ef7ea1d4fa3423506b5cf0ff │ │ │ │ └── 97f2c862ef7ea1d4fa3423506b5cf0ff.info │ │ │ ├── 98/ │ │ │ │ ├── 9805855c8e379ed4cad77f639aaddb73 │ │ │ │ ├── 9805855c8e379ed4cad77f639aaddb73.info │ │ │ │ ├── 980daac0955b74442b91df43f0f1b776 │ │ │ │ ├── 980daac0955b74442b91df43f0f1b776.info │ │ │ │ ├── 983c76d87fb6f4f4597a526a4b2b5fd7 │ │ │ │ ├── 983c76d87fb6f4f4597a526a4b2b5fd7.info │ │ │ │ ├── 985eed4bc2fbee941b761b8816d9055d │ │ │ │ ├── 985eed4bc2fbee941b761b8816d9055d.info │ │ │ │ ├── 98808b11e78f6c84a841a6b4bc5a29d2 │ │ │ │ ├── 98808b11e78f6c84a841a6b4bc5a29d2.info │ │ │ │ ├── 98ba0396e4b4ee8498a8f097affcfddf │ │ │ │ ├── 98ba0396e4b4ee8498a8f097affcfddf.info │ │ │ │ ├── 98bf0690f0c9686468d3866e3c0e5e45 │ │ │ │ ├── 98bf0690f0c9686468d3866e3c0e5e45.info │ │ │ │ ├── 98d14ab1acf42df4f88a0561822ac807 │ │ │ │ └── 98d14ab1acf42df4f88a0561822ac807.info │ │ │ ├── 99/ │ │ │ │ ├── 9945ffed4692c6044b6d3acf81efd694 │ │ │ │ ├── 9945ffed4692c6044b6d3acf81efd694.info │ │ │ │ ├── 995c08a3305ff9f0dab5e86f340bd9a7 │ │ │ │ ├── 995c08a3305ff9f0dab5e86f340bd9a7.info │ │ │ │ ├── 99744ed686e28004180091658ee4f5ae │ │ │ │ ├── 99744ed686e28004180091658ee4f5ae.info │ │ │ │ ├── 99c5970046bb263469514e56eb6aa519 │ │ │ │ └── 99c5970046bb263469514e56eb6aa519.info │ │ │ ├── 9a/ │ │ │ │ ├── 9a0f991b6c2f45b44b92e163f9969e8e │ │ │ │ ├── 9a0f991b6c2f45b44b92e163f9969e8e.info │ │ │ │ ├── 9a3557da07c729b4eb774b8e30e157a4 │ │ │ │ ├── 9a3557da07c729b4eb774b8e30e157a4.info │ │ │ │ ├── 9a371bcbba2084dd0a8ebc6826aa8794 │ │ │ │ ├── 9a371bcbba2084dd0a8ebc6826aa8794.info │ │ │ │ ├── 9a6069768ff3d8043a79348813f86cba │ │ │ │ ├── 9a6069768ff3d8043a79348813f86cba.info │ │ │ │ ├── 9ace5095cc37ed849b52109d2ee305d4 │ │ │ │ ├── 9ace5095cc37ed849b52109d2ee305d4.info │ │ │ │ ├── 9ad0b0c865b01af4ca1b414689e71259 │ │ │ │ └── 9ad0b0c865b01af4ca1b414689e71259.info │ │ │ ├── 9b/ │ │ │ │ ├── 9b1a3034a9e81704abdd08677a2d035f │ │ │ │ ├── 9b1a3034a9e81704abdd08677a2d035f.info │ │ │ │ ├── 9b4f21acd14fdd445b37b76f6587539e │ │ │ │ ├── 9b4f21acd14fdd445b37b76f6587539e.info │ │ │ │ ├── 9b5abcb38bac0c54794ad732a3fa0de3 │ │ │ │ ├── 9b5abcb38bac0c54794ad732a3fa0de3.info │ │ │ │ ├── 9bc2b69915879416f8df18971dc98e2e │ │ │ │ ├── 9bc2b69915879416f8df18971dc98e2e.info │ │ │ │ ├── 9bd5a110ed89025499ddee8c7e73778e │ │ │ │ ├── 9bd5a110ed89025499ddee8c7e73778e.info │ │ │ │ ├── 9be6112c2b1c3ae44927680ba7b36e10 │ │ │ │ ├── 9be6112c2b1c3ae44927680ba7b36e10.info │ │ │ │ ├── 9bedab6f9886aee42b33e424bffdb640 │ │ │ │ └── 9bedab6f9886aee42b33e424bffdb640.info │ │ │ ├── 9c/ │ │ │ │ ├── 9c2177aaf0fde92439246adc2dc0bfa2 │ │ │ │ ├── 9c2177aaf0fde92439246adc2dc0bfa2.info │ │ │ │ ├── 9c21cfda3336137438c3001d40564be0 │ │ │ │ ├── 9c21cfda3336137438c3001d40564be0.info │ │ │ │ ├── 9c4a050f089abb04ebd4125e419f4548 │ │ │ │ ├── 9c4a050f089abb04ebd4125e419f4548.info │ │ │ │ ├── 9c7ad350fb20c854a9112cf4156d1b6e │ │ │ │ ├── 9c7ad350fb20c854a9112cf4156d1b6e.info │ │ │ │ ├── 9c7c268fa6492449654839df69f2a2f4 │ │ │ │ ├── 9c7c268fa6492449654839df69f2a2f4.info │ │ │ │ ├── 9c8ceb9efacb4974bb3b7e2a87137b07 │ │ │ │ ├── 9c8ceb9efacb4974bb3b7e2a87137b07.info │ │ │ │ ├── 9c9e5198af35eb74d8c5d84a5194b184 │ │ │ │ ├── 9c9e5198af35eb74d8c5d84a5194b184.info │ │ │ │ ├── 9ce3cf11b8f74594bb7b1e1dba03122d │ │ │ │ └── 9ce3cf11b8f74594bb7b1e1dba03122d.info │ │ │ ├── 9d/ │ │ │ │ ├── 9d614808f9add8a4f8e4860db2c7af0d │ │ │ │ ├── 9d614808f9add8a4f8e4860db2c7af0d.info │ │ │ │ ├── 9d816a6ab06c6834480f5f45f440e287 │ │ │ │ ├── 9d816a6ab06c6834480f5f45f440e287.info │ │ │ │ ├── 9db19a04003fca7439552acd4de9baa1 │ │ │ │ ├── 9db19a04003fca7439552acd4de9baa1.info │ │ │ │ ├── 9de24983a2c6cbe4f925c3e98a79b804 │ │ │ │ └── 9de24983a2c6cbe4f925c3e98a79b804.info │ │ │ ├── 9e/ │ │ │ │ ├── 9e2b7a65f0a52974193ed497d145b0bc │ │ │ │ ├── 9e2b7a65f0a52974193ed497d145b0bc.info │ │ │ │ ├── 9ec94545c5b00344c9bd8e691f15d799 │ │ │ │ ├── 9ec94545c5b00344c9bd8e691f15d799.info │ │ │ │ ├── 9edc9283e7d6409fab242fe8fb6a822c │ │ │ │ └── 9edc9283e7d6409fab242fe8fb6a822c.info │ │ │ ├── 9f/ │ │ │ │ ├── 9f1026265f8e3d54fb6e9f082c43debf │ │ │ │ ├── 9f1026265f8e3d54fb6e9f082c43debf.info │ │ │ │ ├── 9f2f480fb2536e54ab8493a4e7421720 │ │ │ │ └── 9f2f480fb2536e54ab8493a4e7421720.info │ │ │ ├── a0/ │ │ │ │ ├── a002d3737b873954395b7cf862873ab8 │ │ │ │ ├── a002d3737b873954395b7cf862873ab8.info │ │ │ │ ├── a021b6d2ca2e9404b8a4d94343ecd068 │ │ │ │ ├── a021b6d2ca2e9404b8a4d94343ecd068.info │ │ │ │ ├── a025ba7ee40d0104db8d08b1d9eabb0d │ │ │ │ ├── a025ba7ee40d0104db8d08b1d9eabb0d.info │ │ │ │ ├── a04a45bbed9e1714f9902fc9443669b9 │ │ │ │ ├── a04a45bbed9e1714f9902fc9443669b9.info │ │ │ │ ├── a0a02e768c802b641b6793fa864f1c2c │ │ │ │ ├── a0a02e768c802b641b6793fa864f1c2c.info │ │ │ │ ├── a0b56195e00682b4594dfaeef9d5fa78 │ │ │ │ ├── a0b56195e00682b4594dfaeef9d5fa78.info │ │ │ │ ├── a0bae4ff8f5baf64aad3b92b8aea0603 │ │ │ │ ├── a0bae4ff8f5baf64aad3b92b8aea0603.info │ │ │ │ ├── a0fba9bd62d2b5c4bb89c81f58569c58 │ │ │ │ └── a0fba9bd62d2b5c4bb89c81f58569c58.info │ │ │ ├── a1/ │ │ │ │ ├── a132bd53f9677ee489dac2f1da2b05ea │ │ │ │ ├── a132bd53f9677ee489dac2f1da2b05ea.info │ │ │ │ ├── a14a59f2a5c757e469c3e4e17b798c2e │ │ │ │ └── a14a59f2a5c757e469c3e4e17b798c2e.info │ │ │ ├── a2/ │ │ │ │ ├── a2a8aecb05814e644abbb070fbd91156 │ │ │ │ ├── a2a8aecb05814e644abbb070fbd91156.info │ │ │ │ ├── a2cb43d6b0c226443be7e176590837a5 │ │ │ │ ├── a2cb43d6b0c226443be7e176590837a5.info │ │ │ │ ├── a2cc3e5914c2bb345a87c15d0b894ee8 │ │ │ │ └── a2cc3e5914c2bb345a87c15d0b894ee8.info │ │ │ ├── a3/ │ │ │ │ ├── a331c23f613bfba4294059442ab01d4e │ │ │ │ ├── a331c23f613bfba4294059442ab01d4e.info │ │ │ │ ├── a3529368f4cd0424a89aa51080a16b06 │ │ │ │ ├── a3529368f4cd0424a89aa51080a16b06.info │ │ │ │ ├── a36d8b72880a8004f96ac54ce4598ff9 │ │ │ │ ├── a36d8b72880a8004f96ac54ce4598ff9.info │ │ │ │ ├── a3949cc8bd731bb47bedf6589367d0c9 │ │ │ │ ├── a3949cc8bd731bb47bedf6589367d0c9.info │ │ │ │ ├── a3c7ce509d225e740aed9d6579e2a1e9 │ │ │ │ └── a3c7ce509d225e740aed9d6579e2a1e9.info │ │ │ ├── a4/ │ │ │ │ ├── a429b38ee9d48c7408c8870baf406034 │ │ │ │ ├── a429b38ee9d48c7408c8870baf406034.info │ │ │ │ ├── a4610cf559d77b9f256416d9ccaeac55 │ │ │ │ ├── a4610cf559d77b9f256416d9ccaeac55.info │ │ │ │ ├── a483595b0257945278dc75c5ff7d82ee │ │ │ │ ├── a483595b0257945278dc75c5ff7d82ee.info │ │ │ │ ├── a4cac3a64ff3a4540bbabd58e2d7c8b2 │ │ │ │ └── a4cac3a64ff3a4540bbabd58e2d7c8b2.info │ │ │ ├── a5/ │ │ │ │ ├── a55fb7b4961a425381d1282fc424f966 │ │ │ │ ├── a55fb7b4961a425381d1282fc424f966.info │ │ │ │ ├── a582090813554df479fb9ca03e9857d3 │ │ │ │ ├── a582090813554df479fb9ca03e9857d3.info │ │ │ │ ├── a598580d0cfc7224ebed8d2b627d9e00 │ │ │ │ ├── a598580d0cfc7224ebed8d2b627d9e00.info │ │ │ │ ├── a59c2e62fbd97f84f92c3b546e3903cb │ │ │ │ ├── a59c2e62fbd97f84f92c3b546e3903cb.info │ │ │ │ ├── a5c214e5846a99242b348c37e49b2f59 │ │ │ │ └── a5c214e5846a99242b348c37e49b2f59.info │ │ │ ├── a6/ │ │ │ │ ├── a6238e9452bfc704f82ff36791fe1a45 │ │ │ │ ├── a6238e9452bfc704f82ff36791fe1a45.info │ │ │ │ ├── a62706dc421fc9b4fa368a8050a930f7 │ │ │ │ ├── a62706dc421fc9b4fa368a8050a930f7.info │ │ │ │ ├── a667f6654ad7a9548b8c8e68b51c8895 │ │ │ │ ├── a667f6654ad7a9548b8c8e68b51c8895.info │ │ │ │ ├── a6ab6fd2b91214e8a9c8ec2224a528de │ │ │ │ └── a6ab6fd2b91214e8a9c8ec2224a528de.info │ │ │ ├── a7/ │ │ │ │ ├── a704c010bcdb1ec4a9f3417b3c393164 │ │ │ │ ├── a704c010bcdb1ec4a9f3417b3c393164.info │ │ │ │ ├── a73ebdb6c1006364f8c7b37dc53d8ab7 │ │ │ │ ├── a73ebdb6c1006364f8c7b37dc53d8ab7.info │ │ │ │ ├── a7842a837a4b13e41ae16193db753418 │ │ │ │ ├── a7842a837a4b13e41ae16193db753418.info │ │ │ │ ├── a7c91a123806d41a0873fcdcb629b1c4 │ │ │ │ ├── a7c91a123806d41a0873fcdcb629b1c4.info │ │ │ │ ├── a7ebd1239373d5f41af65ef32d67f445 │ │ │ │ ├── a7ebd1239373d5f41af65ef32d67f445.info │ │ │ │ ├── a7ec9e7ad8b847b7ae4510af83c5d868 │ │ │ │ └── a7ec9e7ad8b847b7ae4510af83c5d868.info │ │ │ ├── a8/ │ │ │ │ ├── a809a4b50addbf44b9023b5e7f9fd4d2 │ │ │ │ ├── a809a4b50addbf44b9023b5e7f9fd4d2.info │ │ │ │ ├── a8604e8f13b3be84b8bc0c1507d8f3f6 │ │ │ │ ├── a8604e8f13b3be84b8bc0c1507d8f3f6.info │ │ │ │ ├── a8ed4063f2beecd41a234a582202f3c4 │ │ │ │ └── a8ed4063f2beecd41a234a582202f3c4.info │ │ │ ├── a9/ │ │ │ │ ├── a9126848c43c4dd499da39a90664dd73 │ │ │ │ ├── a9126848c43c4dd499da39a90664dd73.info │ │ │ │ ├── a956e5803e95df349bd35832492d4014 │ │ │ │ └── a956e5803e95df349bd35832492d4014.info │ │ │ ├── aa/ │ │ │ │ ├── aa14b70e6a58c5b4fa6663623e3dca91 │ │ │ │ ├── aa14b70e6a58c5b4fa6663623e3dca91.info │ │ │ │ ├── aa160f27c3fe4052a5850e21108811b6 │ │ │ │ ├── aa160f27c3fe4052a5850e21108811b6.info │ │ │ │ ├── aa76955fe5bb44f7915d91db8c7043c4 │ │ │ │ └── aa76955fe5bb44f7915d91db8c7043c4.info │ │ │ ├── ab/ │ │ │ │ ├── ab2114bdc8544297b417dfefe9f1e410 │ │ │ │ ├── ab2114bdc8544297b417dfefe9f1e410.info │ │ │ │ ├── ab93e1a81defc3243a6e9cd0df3cb443 │ │ │ │ └── ab93e1a81defc3243a6e9cd0df3cb443.info │ │ │ ├── ac/ │ │ │ │ ├── ac071ac86a8f1af43827e11a522640e4 │ │ │ │ ├── ac071ac86a8f1af43827e11a522640e4.info │ │ │ │ ├── ac281230df7b14becb40b3c479f1b429 │ │ │ │ ├── ac281230df7b14becb40b3c479f1b429.info │ │ │ │ ├── ac3f13489022aa34d861a0320a6917b9 │ │ │ │ ├── ac3f13489022aa34d861a0320a6917b9.info │ │ │ │ ├── ac68f5ae37c8957468562b8da42f9984 │ │ │ │ ├── ac68f5ae37c8957468562b8da42f9984.info │ │ │ │ ├── ac742e1acf5f82f45b9d8ec53fe15b21 │ │ │ │ ├── ac742e1acf5f82f45b9d8ec53fe15b21.info │ │ │ │ ├── acc16f0c684508f44813662a300c574b │ │ │ │ ├── acc16f0c684508f44813662a300c574b.info │ │ │ │ ├── acfa3573efc38c844be021fdaa8cf8a6 │ │ │ │ └── acfa3573efc38c844be021fdaa8cf8a6.info │ │ │ ├── ad/ │ │ │ │ ├── ad09d3e70e7b09244b56b51e495a319c │ │ │ │ ├── ad09d3e70e7b09244b56b51e495a319c.info │ │ │ │ ├── ad70ff8d98b257540b683737743828cb │ │ │ │ ├── ad70ff8d98b257540b683737743828cb.info │ │ │ │ ├── adf7bea9401c1834380d55601add6cfb │ │ │ │ └── adf7bea9401c1834380d55601add6cfb.info │ │ │ ├── ae/ │ │ │ │ ├── ae05f0dd1cf145e4e8e905c7971ee433 │ │ │ │ ├── ae05f0dd1cf145e4e8e905c7971ee433.info │ │ │ │ ├── ae242449e9279d44789513b922d3178a │ │ │ │ ├── ae242449e9279d44789513b922d3178a.info │ │ │ │ ├── ae8ce3ffe04ac2c42945fd27e0291fc3 │ │ │ │ ├── ae8ce3ffe04ac2c42945fd27e0291fc3.info │ │ │ │ ├── aed7ab02155e43341a2dbcb7bc17c160 │ │ │ │ └── aed7ab02155e43341a2dbcb7bc17c160.info │ │ │ ├── af/ │ │ │ │ ├── af30a361ab68260438b6ec3fb7e64500 │ │ │ │ ├── af30a361ab68260438b6ec3fb7e64500.info │ │ │ │ ├── af5042802f06c804c8abddd544b77a4a │ │ │ │ ├── af5042802f06c804c8abddd544b77a4a.info │ │ │ │ ├── af84cf39b8fa0654badd9278cbd00d77 │ │ │ │ ├── af84cf39b8fa0654badd9278cbd00d77.info │ │ │ │ ├── afeb55855d7a63b45ba6f8bd97599202 │ │ │ │ └── afeb55855d7a63b45ba6f8bd97599202.info │ │ │ ├── b0/ │ │ │ │ ├── b09be1f217d34247af54863a2f5587e1 │ │ │ │ ├── b09be1f217d34247af54863a2f5587e1.info │ │ │ │ ├── b0c73ea1c5ff95e43806e9002c155070 │ │ │ │ ├── b0c73ea1c5ff95e43806e9002c155070.info │ │ │ │ ├── b0eeee3cdfa56734abca5c1a4e7989ba │ │ │ │ └── b0eeee3cdfa56734abca5c1a4e7989ba.info │ │ │ ├── b1/ │ │ │ │ ├── b10cb8fee5b39014d8a417bf413f5e5c │ │ │ │ ├── b10cb8fee5b39014d8a417bf413f5e5c.info │ │ │ │ ├── b124f0b8ca43e6e46bdc0322fad15ea3 │ │ │ │ ├── b124f0b8ca43e6e46bdc0322fad15ea3.info │ │ │ │ ├── b135ec222fdcd11468014c90d11d6821 │ │ │ │ ├── b135ec222fdcd11468014c90d11d6821.info │ │ │ │ ├── b14b67faac4aff04fac7127cf1ab4f97 │ │ │ │ ├── b14b67faac4aff04fac7127cf1ab4f97.info │ │ │ │ ├── b180fd8310805e44dbbef545d0231418 │ │ │ │ ├── b180fd8310805e44dbbef545d0231418.info │ │ │ │ ├── b1c789407b55e3a4c9cc86135a714e33 │ │ │ │ ├── b1c789407b55e3a4c9cc86135a714e33.info │ │ │ │ ├── b1d8465ba1376b148bdab58965101f47 │ │ │ │ └── b1d8465ba1376b148bdab58965101f47.info │ │ │ ├── b2/ │ │ │ │ ├── b219c86ce508e478367c0a46e1aa9fe4 │ │ │ │ ├── b219c86ce508e478367c0a46e1aa9fe4.info │ │ │ │ ├── b222f61a1f7253e4d8e8cc82bfde9e42 │ │ │ │ ├── b222f61a1f7253e4d8e8cc82bfde9e42.info │ │ │ │ ├── b250be9db55288b48ac121c074d795e6 │ │ │ │ └── b250be9db55288b48ac121c074d795e6.info │ │ │ ├── b3/ │ │ │ │ ├── b33687803b08daf418e5315de17658b8 │ │ │ │ ├── b33687803b08daf418e5315de17658b8.info │ │ │ │ ├── b3cdabf2f1e76854d8aab5930305d70d │ │ │ │ └── b3cdabf2f1e76854d8aab5930305d70d.info │ │ │ ├── b4/ │ │ │ │ ├── b42e1db66fe9c634798674cb9e1df2ca │ │ │ │ ├── b42e1db66fe9c634798674cb9e1df2ca.info │ │ │ │ ├── b458b2c7f196bdc4581b2f9fd6a5d931 │ │ │ │ ├── b458b2c7f196bdc4581b2f9fd6a5d931.info │ │ │ │ ├── b46e36075dd1c124a8422c228e75e1fb │ │ │ │ ├── b46e36075dd1c124a8422c228e75e1fb.info │ │ │ │ ├── b477d1f29b65a674e9d5cdab4eb72b01 │ │ │ │ ├── b477d1f29b65a674e9d5cdab4eb72b01.info │ │ │ │ ├── b4a5ce78107bc38409a3bb5e8b3289ac │ │ │ │ ├── b4a5ce78107bc38409a3bb5e8b3289ac.info │ │ │ │ ├── b4c60b58ddb35c749ad94bd8b5b83168 │ │ │ │ └── b4c60b58ddb35c749ad94bd8b5b83168.info │ │ │ ├── b5/ │ │ │ │ ├── b52bde26a83564960bcb90217f72b910 │ │ │ │ ├── b52bde26a83564960bcb90217f72b910.info │ │ │ │ ├── b5489bb3cd68836439785588fffc67a4 │ │ │ │ ├── b5489bb3cd68836439785588fffc67a4.info │ │ │ │ ├── b557515fff172984e8c4400b43f1c631 │ │ │ │ ├── b557515fff172984e8c4400b43f1c631.info │ │ │ │ ├── b57629d89799e004182564256307b0cc │ │ │ │ ├── b57629d89799e004182564256307b0cc.info │ │ │ │ ├── b5d6c28ed7b94775be9e2560f300247c │ │ │ │ ├── b5d6c28ed7b94775be9e2560f300247c.info │ │ │ │ ├── b5f0881228e5827438f74e9b7b33c2dc │ │ │ │ ├── b5f0881228e5827438f74e9b7b33c2dc.info │ │ │ │ ├── b5f31b7e60df3e64796fb7ab6f54f489 │ │ │ │ ├── b5f31b7e60df3e64796fb7ab6f54f489.info │ │ │ │ ├── b5f70efd2f7b286498ca6c00adbb4a13 │ │ │ │ └── b5f70efd2f7b286498ca6c00adbb4a13.info │ │ │ ├── b6/ │ │ │ │ ├── b611b0a598aeada419afa9737807c598 │ │ │ │ ├── b611b0a598aeada419afa9737807c598.info │ │ │ │ ├── b6e75d7f429a4e7e9e1ffb4f85cff49f │ │ │ │ └── b6e75d7f429a4e7e9e1ffb4f85cff49f.info │ │ │ ├── b7/ │ │ │ │ ├── b7468a027a77337478e133b40b42b4f9 │ │ │ │ ├── b7468a027a77337478e133b40b42b4f9.info │ │ │ │ ├── b759d61544e231c41bc88530b1d94ee8 │ │ │ │ ├── b759d61544e231c41bc88530b1d94ee8.info │ │ │ │ ├── b77b1ad9c05af0412725856c6c53b037 │ │ │ │ ├── b77b1ad9c05af0412725856c6c53b037.info │ │ │ │ ├── b7abcd1a72bb7174ca58e813c6eee9c2 │ │ │ │ ├── b7abcd1a72bb7174ca58e813c6eee9c2.info │ │ │ │ ├── b7c13973a7ed1444fb514d09b5e7e579 │ │ │ │ ├── b7c13973a7ed1444fb514d09b5e7e579.info │ │ │ │ ├── b7cabea05434bb9479aee1e121b0d103 │ │ │ │ ├── b7cabea05434bb9479aee1e121b0d103.info │ │ │ │ ├── b7ff2b2e91321ff4381d4ab45870a32e │ │ │ │ └── b7ff2b2e91321ff4381d4ab45870a32e.info │ │ │ ├── b8/ │ │ │ │ ├── b8046f5b741868b458cdb9b358311fa1 │ │ │ │ ├── b8046f5b741868b458cdb9b358311fa1.info │ │ │ │ ├── b825fd5f27403b84f97726dd9c5a5e6f │ │ │ │ ├── b825fd5f27403b84f97726dd9c5a5e6f.info │ │ │ │ ├── b83f06ac0c0696e9563230865ca72b81 │ │ │ │ ├── b83f06ac0c0696e9563230865ca72b81.info │ │ │ │ ├── b846f69b139b3a341a5699a09fa52b2c │ │ │ │ ├── b846f69b139b3a341a5699a09fa52b2c.info │ │ │ │ ├── b86b117346968ac4d9cc63e4385becb7 │ │ │ │ ├── b86b117346968ac4d9cc63e4385becb7.info │ │ │ │ ├── b88caca58e05ee74486d86fb404c48e2 │ │ │ │ ├── b88caca58e05ee74486d86fb404c48e2.info │ │ │ │ ├── b8abb41ceb6f62c45a00197ae59224c1 │ │ │ │ ├── b8abb41ceb6f62c45a00197ae59224c1.info │ │ │ │ ├── b8c3bda3a988b5f4c910a5c3f722d0be │ │ │ │ ├── b8c3bda3a988b5f4c910a5c3f722d0be.info │ │ │ │ ├── b8c5993172f27e4419d7d4ed5ef77840 │ │ │ │ └── b8c5993172f27e4419d7d4ed5ef77840.info │ │ │ ├── b9/ │ │ │ │ ├── b90311a8f07b00f4bbeb2fff3b128d25 │ │ │ │ ├── b90311a8f07b00f4bbeb2fff3b128d25.info │ │ │ │ ├── b926af22079e00e4a8c073321194cea1 │ │ │ │ ├── b926af22079e00e4a8c073321194cea1.info │ │ │ │ ├── b9ba34e0b1884454fbc4257260e22b64 │ │ │ │ ├── b9ba34e0b1884454fbc4257260e22b64.info │ │ │ │ ├── b9c2a6302985d3846b7b9f6fd9e2da9a │ │ │ │ ├── b9c2a6302985d3846b7b9f6fd9e2da9a.info │ │ │ │ ├── b9d7bb79ed0c2854a8a5ed7decc3e44f │ │ │ │ ├── b9d7bb79ed0c2854a8a5ed7decc3e44f.info │ │ │ │ ├── b9eb962217e00bf4fbc734e109991fca │ │ │ │ └── b9eb962217e00bf4fbc734e109991fca.info │ │ │ ├── ba/ │ │ │ │ ├── ba72b974bd5e43240bd91ade68574875 │ │ │ │ ├── ba72b974bd5e43240bd91ade68574875.info │ │ │ │ ├── bae197be297529d4fa735fbe7c91828d │ │ │ │ └── bae197be297529d4fa735fbe7c91828d.info │ │ │ ├── bb/ │ │ │ │ ├── bb05cab7d802aa5468f8f2f86840d984 │ │ │ │ ├── bb05cab7d802aa5468f8f2f86840d984.info │ │ │ │ ├── bb32bccaf32a6db448d1c0cc99c78688 │ │ │ │ ├── bb32bccaf32a6db448d1c0cc99c78688.info │ │ │ │ ├── bb42b2d967d6427983c901a4ffc8ecd9 │ │ │ │ └── bb42b2d967d6427983c901a4ffc8ecd9.info │ │ │ ├── bc/ │ │ │ │ ├── bc00e25696e4132499f56528d3fed2e3 │ │ │ │ ├── bc00e25696e4132499f56528d3fed2e3.info │ │ │ │ ├── bc98484caab3b6d4facbcff38be93380 │ │ │ │ ├── bc98484caab3b6d4facbcff38be93380.info │ │ │ │ ├── bc9aa6d5a7945f34882c442e9e201537 │ │ │ │ └── bc9aa6d5a7945f34882c442e9e201537.info │ │ │ ├── bd/ │ │ │ │ ├── bd1af0a6633ee94ae21c7d1d702cdc12 │ │ │ │ ├── bd1af0a6633ee94ae21c7d1d702cdc12.info │ │ │ │ ├── bd3e81baa10021f4d877fa36382bab16 │ │ │ │ ├── bd3e81baa10021f4d877fa36382bab16.info │ │ │ │ ├── bd3ffb9a97575a44a82f9ca086813154 │ │ │ │ ├── bd3ffb9a97575a44a82f9ca086813154.info │ │ │ │ ├── bdb4f6935641b574b984da8dc27cab45 │ │ │ │ ├── bdb4f6935641b574b984da8dc27cab45.info │ │ │ │ ├── bdbd564a9fdad0b738e76d030cad1204 │ │ │ │ └── bdbd564a9fdad0b738e76d030cad1204.info │ │ │ ├── be/ │ │ │ │ ├── be07f70ee67e6d74e851a9333719bbb6 │ │ │ │ ├── be07f70ee67e6d74e851a9333719bbb6.info │ │ │ │ ├── be156cc527d606b4aaac403e9843186e │ │ │ │ ├── be156cc527d606b4aaac403e9843186e.info │ │ │ │ ├── bea62e1faac8f9a48a4cb919ea05cb6a │ │ │ │ ├── bea62e1faac8f9a48a4cb919ea05cb6a.info │ │ │ │ ├── bede4033d9f359b41878c4cda6a910b3 │ │ │ │ ├── bede4033d9f359b41878c4cda6a910b3.info │ │ │ │ ├── bee384ad5b4d1a843a018082e7db53cd │ │ │ │ └── bee384ad5b4d1a843a018082e7db53cd.info │ │ │ ├── bf/ │ │ │ │ ├── bf87e20fb5440ec498f441167b5291f8 │ │ │ │ ├── bf87e20fb5440ec498f441167b5291f8.info │ │ │ │ ├── bfb788a43e03363419155b8af77da971 │ │ │ │ ├── bfb788a43e03363419155b8af77da971.info │ │ │ │ ├── bfd567a3d1631a761bca9e99fa53d86d │ │ │ │ ├── bfd567a3d1631a761bca9e99fa53d86d.info │ │ │ │ ├── bfda56da833e2384a9677cd3c976a436 │ │ │ │ └── bfda56da833e2384a9677cd3c976a436.info │ │ │ ├── c0/ │ │ │ │ ├── c060426bfd6e82575228df6656368eaa │ │ │ │ ├── c060426bfd6e82575228df6656368eaa.info │ │ │ │ ├── c072e5b741a87974385c270827879cbf │ │ │ │ └── c072e5b741a87974385c270827879cbf.info │ │ │ ├── c1/ │ │ │ │ ├── c14a5e4bdca08454eb523515cecf43c2 │ │ │ │ ├── c14a5e4bdca08454eb523515cecf43c2.info │ │ │ │ ├── c16c54fe03afb5740bcc0a2a295cb79d │ │ │ │ ├── c16c54fe03afb5740bcc0a2a295cb79d.info │ │ │ │ ├── c171b9ca03610ea4faa426e082a1075d │ │ │ │ ├── c171b9ca03610ea4faa426e082a1075d.info │ │ │ │ ├── c18288a8d31fc9043a807ee8a9f1ae64 │ │ │ │ ├── c18288a8d31fc9043a807ee8a9f1ae64.info │ │ │ │ ├── c18cb9388313e4287ad5895ee735c47d │ │ │ │ └── c18cb9388313e4287ad5895ee735c47d.info │ │ │ ├── c2/ │ │ │ │ ├── c2f7f6a88b4c4f20a53deb72f3d9144c │ │ │ │ └── c2f7f6a88b4c4f20a53deb72f3d9144c.info │ │ │ ├── c3/ │ │ │ │ ├── c32df609537c54c46adf92992a673693 │ │ │ │ ├── c32df609537c54c46adf92992a673693.info │ │ │ │ ├── c346a7445959bba46a96de0747e77c2a │ │ │ │ ├── c346a7445959bba46a96de0747e77c2a.info │ │ │ │ ├── c35a186b967e6a24d9d844d412fe08a3 │ │ │ │ ├── c35a186b967e6a24d9d844d412fe08a3.info │ │ │ │ ├── c38ae0585d6a55042a2d678330689685 │ │ │ │ ├── c38ae0585d6a55042a2d678330689685.info │ │ │ │ ├── c3a595c9a8ed19040bb2612fe168759d │ │ │ │ ├── c3a595c9a8ed19040bb2612fe168759d.info │ │ │ │ ├── c3a75354f6ceac94ca15ca9d96593290 │ │ │ │ ├── c3a75354f6ceac94ca15ca9d96593290.info │ │ │ │ ├── c3de99f9efc582a48995bc8e8c2df418 │ │ │ │ ├── c3de99f9efc582a48995bc8e8c2df418.info │ │ │ │ ├── c3efd39f2cfb43a4c830d4fd5689900f │ │ │ │ └── c3efd39f2cfb43a4c830d4fd5689900f.info │ │ │ ├── c4/ │ │ │ │ ├── c4095d72f77fbb64ea39b8b3ca246622 │ │ │ │ ├── c4095d72f77fbb64ea39b8b3ca246622.info │ │ │ │ ├── c459424081436584c8cec10767f9ac38 │ │ │ │ ├── c459424081436584c8cec10767f9ac38.info │ │ │ │ ├── c46b007a3762fc84cb1ee7ca30060f0b │ │ │ │ ├── c46b007a3762fc84cb1ee7ca30060f0b.info │ │ │ │ ├── c4777500b5da6094e956c3d4f04de4db │ │ │ │ ├── c4777500b5da6094e956c3d4f04de4db.info │ │ │ │ ├── c488c389c17bd8d42b57e25edfc92ebf │ │ │ │ ├── c488c389c17bd8d42b57e25edfc92ebf.info │ │ │ │ ├── c49b4cc203aa6414fae5c798d1d0e7d6 │ │ │ │ ├── c49b4cc203aa6414fae5c798d1d0e7d6.info │ │ │ │ ├── c4c1445ee948a4124bfa9fb818a17e36 │ │ │ │ ├── c4c1445ee948a4124bfa9fb818a17e36.info │ │ │ │ ├── c4df1124e2787ee0c8d1a911de17ee73 │ │ │ │ └── c4df1124e2787ee0c8d1a911de17ee73.info │ │ │ ├── c5/ │ │ │ │ ├── c50a694a8232898498c1cdd47ce9873f │ │ │ │ ├── c50a694a8232898498c1cdd47ce9873f.info │ │ │ │ ├── c522a644a29fcab2eaf63298c118a65b │ │ │ │ ├── c522a644a29fcab2eaf63298c118a65b.info │ │ │ │ ├── c545241cf2e56ec4997d7677f01ef43d │ │ │ │ ├── c545241cf2e56ec4997d7677f01ef43d.info │ │ │ │ ├── c5535d742ea2e4941850b421f9c70a1f │ │ │ │ ├── c5535d742ea2e4941850b421f9c70a1f.info │ │ │ │ ├── c55a64c7570474f47a94abe39ebfef04 │ │ │ │ ├── c55a64c7570474f47a94abe39ebfef04.info │ │ │ │ ├── c5acba6181d845c4e92146009bd4480f │ │ │ │ └── c5acba6181d845c4e92146009bd4480f.info │ │ │ ├── c6/ │ │ │ │ ├── c606041f02fc7d542b1429806872292b │ │ │ │ ├── c606041f02fc7d542b1429806872292b.info │ │ │ │ ├── c67ac6e40bbb6fe47a095b949b609ce0 │ │ │ │ ├── c67ac6e40bbb6fe47a095b949b609ce0.info │ │ │ │ ├── c68f34993bfe85e489158a29c99a20b5 │ │ │ │ └── c68f34993bfe85e489158a29c99a20b5.info │ │ │ ├── c7/ │ │ │ │ ├── c7137daaeb11e8647bf1ade9b7e9aa97 │ │ │ │ ├── c7137daaeb11e8647bf1ade9b7e9aa97.info │ │ │ │ ├── c754112a02f354a6696fa4f2b99e95a5 │ │ │ │ ├── c754112a02f354a6696fa4f2b99e95a5.info │ │ │ │ ├── c76700ea0062413d9f69409b4e9e151b │ │ │ │ ├── c76700ea0062413d9f69409b4e9e151b.info │ │ │ │ ├── c779d3735d950f341ba35154e8b3234b │ │ │ │ ├── c779d3735d950f341ba35154e8b3234b.info │ │ │ │ ├── c7cfda246e604b945b12b7afedb094ce │ │ │ │ └── c7cfda246e604b945b12b7afedb094ce.info │ │ │ ├── c8/ │ │ │ │ ├── c825bad77a42dd341a8f0a5ef9cd5f4c │ │ │ │ ├── c825bad77a42dd341a8f0a5ef9cd5f4c.info │ │ │ │ ├── c851bee4305bddf438cc6ffc515991ce │ │ │ │ ├── c851bee4305bddf438cc6ffc515991ce.info │ │ │ │ ├── c890977a36bfdc849872b9337ab89098 │ │ │ │ └── c890977a36bfdc849872b9337ab89098.info │ │ │ ├── c9/ │ │ │ │ ├── c91c0b6ea03975b419e4cb285a69a10d │ │ │ │ ├── c91c0b6ea03975b419e4cb285a69a10d.info │ │ │ │ ├── c9219e99d466b7741a057132d1994f35 │ │ │ │ ├── c9219e99d466b7741a057132d1994f35.info │ │ │ │ ├── c97b794b51780d349a16826a4c7898d7 │ │ │ │ ├── c97b794b51780d349a16826a4c7898d7.info │ │ │ │ ├── c995a014808fcd047bebea5fd6813310 │ │ │ │ ├── c995a014808fcd047bebea5fd6813310.info │ │ │ │ ├── c9aabac5924106d4790d7b3a924ca34d │ │ │ │ ├── c9aabac5924106d4790d7b3a924ca34d.info │ │ │ │ ├── c9b23632c77de204abfe8bf7168d48c0 │ │ │ │ └── c9b23632c77de204abfe8bf7168d48c0.info │ │ │ ├── ca/ │ │ │ │ ├── ca51b19024094d1b87f3e07edb0a75fb │ │ │ │ ├── ca51b19024094d1b87f3e07edb0a75fb.info │ │ │ │ ├── ca819640f53b48919bf7774744f7f15e │ │ │ │ ├── ca819640f53b48919bf7774744f7f15e.info │ │ │ │ ├── cabaa672b0e3ee91fa7b6da4daab7970 │ │ │ │ ├── cabaa672b0e3ee91fa7b6da4daab7970.info │ │ │ │ ├── cad095eccea17b741bc4cd264e7441cd │ │ │ │ ├── cad095eccea17b741bc4cd264e7441cd.info │ │ │ │ ├── cae60a41b37427b48a00027b3e0fc1e6 │ │ │ │ └── cae60a41b37427b48a00027b3e0fc1e6.info │ │ │ ├── cb/ │ │ │ │ ├── cb281723220c9964094e6c52e0ece792 │ │ │ │ ├── cb281723220c9964094e6c52e0ece792.info │ │ │ │ ├── cb319974ad8ebd44aa1e1fbb02640b5b │ │ │ │ ├── cb319974ad8ebd44aa1e1fbb02640b5b.info │ │ │ │ ├── cb5112bfbee0a8545af567d810945a2a │ │ │ │ ├── cb5112bfbee0a8545af567d810945a2a.info │ │ │ │ ├── cb7c939a806f03341b682c180dc13f08 │ │ │ │ ├── cb7c939a806f03341b682c180dc13f08.info │ │ │ │ ├── cbab8835092323a4389f2dc7d8f6c781 │ │ │ │ ├── cbab8835092323a4389f2dc7d8f6c781.info │ │ │ │ ├── cbbca1d8a0434be4bbc7f165523763ac │ │ │ │ └── cbbca1d8a0434be4bbc7f165523763ac.info │ │ │ ├── cc/ │ │ │ │ ├── cc22cc13b69c1094c85e176c008b9ef8 │ │ │ │ ├── cc22cc13b69c1094c85e176c008b9ef8.info │ │ │ │ ├── cc313cc004395df4a9884390556690a5 │ │ │ │ ├── cc313cc004395df4a9884390556690a5.info │ │ │ │ ├── cc456ba93311a3a43ad896449fee9868 │ │ │ │ ├── cc456ba93311a3a43ad896449fee9868.info │ │ │ │ ├── cc6401f13df54ba44bfd7cdc93c7d64d │ │ │ │ ├── cc6401f13df54ba44bfd7cdc93c7d64d.info │ │ │ │ ├── cce613d1538e76a4785658931c7db093 │ │ │ │ └── cce613d1538e76a4785658931c7db093.info │ │ │ ├── ce/ │ │ │ │ ├── ce4ec0f498d1b1a4f90fe94e115b6f9a │ │ │ │ ├── ce4ec0f498d1b1a4f90fe94e115b6f9a.info │ │ │ │ ├── ce4ff17ca867d2b48b5c8a4181611901 │ │ │ │ ├── ce4ff17ca867d2b48b5c8a4181611901.info │ │ │ │ ├── ce567ddbf30368344bc7b80e20cac36e │ │ │ │ ├── ce567ddbf30368344bc7b80e20cac36e.info │ │ │ │ ├── ce87c287371edde43a4b5fcfdee7b9ef │ │ │ │ ├── ce87c287371edde43a4b5fcfdee7b9ef.info │ │ │ │ ├── ce8da628f68c7594b8b9a597fa52db7b │ │ │ │ ├── ce8da628f68c7594b8b9a597fa52db7b.info │ │ │ │ ├── ceb629fc661813d40986b4abbefe72c6 │ │ │ │ └── ceb629fc661813d40986b4abbefe72c6.info │ │ │ ├── cf/ │ │ │ │ ├── cf1fe50a641faac4691bf49eb32ce333 │ │ │ │ ├── cf1fe50a641faac4691bf49eb32ce333.info │ │ │ │ ├── cf6aca931950a4a6a886e214e9e649c4 │ │ │ │ ├── cf6aca931950a4a6a886e214e9e649c4.info │ │ │ │ ├── cf97e54bcd5479a46bdbade48da047cc │ │ │ │ ├── cf97e54bcd5479a46bdbade48da047cc.info │ │ │ │ ├── cfa73a847eeff06448bb50a8ac6a94e0 │ │ │ │ ├── cfa73a847eeff06448bb50a8ac6a94e0.info │ │ │ │ ├── cfabb0440166ab443bba8876756fdfa9 │ │ │ │ └── cfabb0440166ab443bba8876756fdfa9.info │ │ │ ├── d0/ │ │ │ │ ├── d0080567f62c3f94cb75b2927a349e22 │ │ │ │ ├── d0080567f62c3f94cb75b2927a349e22.info │ │ │ │ ├── d0138170d24533e47b8e6c250c6d7fbc │ │ │ │ ├── d0138170d24533e47b8e6c250c6d7fbc.info │ │ │ │ ├── d029640460cf8ff47bbbfe69f49ddf29 │ │ │ │ ├── d029640460cf8ff47bbbfe69f49ddf29.info │ │ │ │ ├── d061ada5d3169454daf54243390b5fdb │ │ │ │ ├── d061ada5d3169454daf54243390b5fdb.info │ │ │ │ ├── d0663d520c26b7c48a4135599e66acf8 │ │ │ │ ├── d0663d520c26b7c48a4135599e66acf8.info │ │ │ │ ├── d09858396dd7adb4bbdb22ea0c8c3a37 │ │ │ │ ├── d09858396dd7adb4bbdb22ea0c8c3a37.info │ │ │ │ ├── d0abdd8cb6b29a24c8ee19626ef741b9 │ │ │ │ ├── d0abdd8cb6b29a24c8ee19626ef741b9.info │ │ │ │ ├── d0b148fe25e99eb48b9724523833bab1 │ │ │ │ ├── d0b148fe25e99eb48b9724523833bab1.info │ │ │ │ ├── d0ca7b2e84542bf4ab9987087e8d79ad │ │ │ │ ├── d0ca7b2e84542bf4ab9987087e8d79ad.info │ │ │ │ ├── d0cd29fb1ad218b48b814bc3e6d8ac0e │ │ │ │ ├── d0cd29fb1ad218b48b814bc3e6d8ac0e.info │ │ │ │ ├── d0e3ad91972c66f5238f5b9b7d5ae58a │ │ │ │ ├── d0e3ad91972c66f5238f5b9b7d5ae58a.info │ │ │ │ ├── d0fc6f5187a81dc47999eefade6f0935 │ │ │ │ └── d0fc6f5187a81dc47999eefade6f0935.info │ │ │ ├── d1/ │ │ │ │ ├── d1207768d96c479488b6b81f3483e0c1 │ │ │ │ ├── d1207768d96c479488b6b81f3483e0c1.info │ │ │ │ ├── d12fd27d9e34a1e43b79b04f9202d548 │ │ │ │ ├── d12fd27d9e34a1e43b79b04f9202d548.info │ │ │ │ ├── d143f3edd0494bc4c98a421bd59564fa │ │ │ │ ├── d143f3edd0494bc4c98a421bd59564fa.info │ │ │ │ ├── d199490a83bb2b844b9695cbf13b01ef │ │ │ │ ├── d199490a83bb2b844b9695cbf13b01ef.info │ │ │ │ ├── d19b75372f4e44d4fa4b2cffbb54124b │ │ │ │ ├── d19b75372f4e44d4fa4b2cffbb54124b.info │ │ │ │ ├── d1a0a27327b54c3bac52a08929c33f81 │ │ │ │ ├── d1a0a27327b54c3bac52a08929c33f81.info │ │ │ │ ├── d1b534518943030499685344fd1d476d │ │ │ │ ├── d1b534518943030499685344fd1d476d.info │ │ │ │ ├── d1b7ce919aa8864409412e809073cf96 │ │ │ │ ├── d1b7ce919aa8864409412e809073cf96.info │ │ │ │ ├── d1c9c1ed454d0594b951eb6a76ac62ad │ │ │ │ └── d1c9c1ed454d0594b951eb6a76ac62ad.info │ │ │ ├── d2/ │ │ │ │ ├── d208a1684f8aa6a40ad91d6aa9600c14 │ │ │ │ ├── d208a1684f8aa6a40ad91d6aa9600c14.info │ │ │ │ ├── d20e4e177b86a2843805dd3894f41b42 │ │ │ │ ├── d20e4e177b86a2843805dd3894f41b42.info │ │ │ │ ├── d2146428d3f1ad54eb7326c9a44b3284 │ │ │ │ ├── d2146428d3f1ad54eb7326c9a44b3284.info │ │ │ │ ├── d21dcc2386d650c4597f3633c75a1f98 │ │ │ │ ├── d21dcc2386d650c4597f3633c75a1f98.info │ │ │ │ ├── d256fa541faf5d4409992c631adb98a1 │ │ │ │ └── d256fa541faf5d4409992c631adb98a1.info │ │ │ ├── d3/ │ │ │ │ ├── d31dfeaa131921f4eae00783cc48146f │ │ │ │ ├── d31dfeaa131921f4eae00783cc48146f.info │ │ │ │ ├── d31e5d760880a4e52a3a75322481d0d2 │ │ │ │ ├── d31e5d760880a4e52a3a75322481d0d2.info │ │ │ │ ├── d3217d58bbd1d2b4aaee933e2e8b9195 │ │ │ │ ├── d3217d58bbd1d2b4aaee933e2e8b9195.info │ │ │ │ ├── d36a7c7a1ed377c4b8008e53032d7dcf │ │ │ │ ├── d36a7c7a1ed377c4b8008e53032d7dcf.info │ │ │ │ ├── d3721d5c6afa8e545995dfaada328476 │ │ │ │ ├── d3721d5c6afa8e545995dfaada328476.info │ │ │ │ ├── d399317a9fcc74045a7924c9fdf2bcf6 │ │ │ │ ├── d399317a9fcc74045a7924c9fdf2bcf6.info │ │ │ │ ├── d3cbe921f7b3d9a3257e7c61a5761796 │ │ │ │ ├── d3cbe921f7b3d9a3257e7c61a5761796.info │ │ │ │ ├── d3d14fa8f6934e14d92e37279e40e89b │ │ │ │ └── d3d14fa8f6934e14d92e37279e40e89b.info │ │ │ ├── d4/ │ │ │ │ ├── d40a0edbdcdcf9747a420f3bbe0f18db │ │ │ │ ├── d40a0edbdcdcf9747a420f3bbe0f18db.info │ │ │ │ ├── d437fe60bb34f45728664a5d930c1635 │ │ │ │ ├── d437fe60bb34f45728664a5d930c1635.info │ │ │ │ ├── d44e6804bc58be84ea71a619b468f150 │ │ │ │ ├── d44e6804bc58be84ea71a619b468f150.info │ │ │ │ ├── d4979bb992c0fb446a4f6c6cbf4ccfb8 │ │ │ │ ├── d4979bb992c0fb446a4f6c6cbf4ccfb8.info │ │ │ │ ├── d49b2ed20045e034f9cdf6a6d95e6183 │ │ │ │ ├── d49b2ed20045e034f9cdf6a6d95e6183.info │ │ │ │ ├── d4a52abc72e7b5947a077b1357646e55 │ │ │ │ ├── d4a52abc72e7b5947a077b1357646e55.info │ │ │ │ ├── d4ef26aa386b44923b61c9c4b505a67c │ │ │ │ └── d4ef26aa386b44923b61c9c4b505a67c.info │ │ │ ├── d5/ │ │ │ │ ├── d51458b261e0ecc4a98904e53924dc1c │ │ │ │ ├── d51458b261e0ecc4a98904e53924dc1c.info │ │ │ │ ├── d528c8c98d269ca44a06cd9624a03945 │ │ │ │ ├── d528c8c98d269ca44a06cd9624a03945.info │ │ │ │ ├── d548f82e7e9c0ed49ae5b4a5eecfb2f7 │ │ │ │ ├── d548f82e7e9c0ed49ae5b4a5eecfb2f7.info │ │ │ │ ├── d56dbb97f857c8040beef6dd1bfc97df │ │ │ │ ├── d56dbb97f857c8040beef6dd1bfc97df.info │ │ │ │ ├── d5718b3fe3a758b4a9ec29170290d4f6 │ │ │ │ ├── d5718b3fe3a758b4a9ec29170290d4f6.info │ │ │ │ ├── d59cefc45e3c31d4a90563364e7258fa │ │ │ │ ├── d59cefc45e3c31d4a90563364e7258fa.info │ │ │ │ ├── d5f0b0adc6826e9dd3b72e292e8438be │ │ │ │ └── d5f0b0adc6826e9dd3b72e292e8438be.info │ │ │ ├── d6/ │ │ │ │ ├── d6105bc8cf5ce544487daca4cbc62583 │ │ │ │ ├── d6105bc8cf5ce544487daca4cbc62583.info │ │ │ │ ├── d63dd1a776d383248a21ec2a8a6e7868 │ │ │ │ ├── d63dd1a776d383248a21ec2a8a6e7868.info │ │ │ │ ├── d64d92e4f04a13e4b99ea8d48e9e8ae9 │ │ │ │ ├── d64d92e4f04a13e4b99ea8d48e9e8ae9.info │ │ │ │ ├── d685d97a1eb004f49afea0cc982ff728 │ │ │ │ ├── d685d97a1eb004f49afea0cc982ff728.info │ │ │ │ ├── d691174143fd3774ba63d7c493633b99 │ │ │ │ ├── d691174143fd3774ba63d7c493633b99.info │ │ │ │ ├── d6a2e6e4803de7b43baacdc355fc144d │ │ │ │ ├── d6a2e6e4803de7b43baacdc355fc144d.info │ │ │ │ ├── d6c6a000a805f00649b36b542e8426c2 │ │ │ │ ├── d6c6a000a805f00649b36b542e8426c2.info │ │ │ │ ├── d6db7caf2e852b75ebb9c6098418179c │ │ │ │ ├── d6db7caf2e852b75ebb9c6098418179c.info │ │ │ │ ├── d6e23541e3b2fea489be46f704b64707 │ │ │ │ ├── d6e23541e3b2fea489be46f704b64707.info │ │ │ │ ├── d6fa2d92fc1b3f34da284357edf89c3b │ │ │ │ └── d6fa2d92fc1b3f34da284357edf89c3b.info │ │ │ ├── d7/ │ │ │ │ ├── d72ccd2c66ea846fc842adf682b11526 │ │ │ │ ├── d72ccd2c66ea846fc842adf682b11526.info │ │ │ │ ├── d79cb9ecc0d4a6d428ab98a681a33897 │ │ │ │ ├── d79cb9ecc0d4a6d428ab98a681a33897.info │ │ │ │ ├── d7b5b883d3aae8d479647d5ae6182974 │ │ │ │ └── d7b5b883d3aae8d479647d5ae6182974.info │ │ │ ├── d8/ │ │ │ │ ├── d850db319a63d2546932ff76fe55a498 │ │ │ │ ├── d850db319a63d2546932ff76fe55a498.info │ │ │ │ ├── d85e5eeaf8f135aeaaebdc8aa3cff6c3 │ │ │ │ ├── d85e5eeaf8f135aeaaebdc8aa3cff6c3.info │ │ │ │ ├── d8c4a920f001ca64680ed6fdb52d1753 │ │ │ │ └── d8c4a920f001ca64680ed6fdb52d1753.info │ │ │ ├── d9/ │ │ │ │ ├── d912d4873af534bd4a9d44bf1b52f14e │ │ │ │ ├── d912d4873af534bd4a9d44bf1b52f14e.info │ │ │ │ ├── d925cabd9ecd5074aadab0726b96c38f │ │ │ │ ├── d925cabd9ecd5074aadab0726b96c38f.info │ │ │ │ ├── d9647b571c5e44729b71d756b3d55317 │ │ │ │ ├── d9647b571c5e44729b71d756b3d55317.info │ │ │ │ ├── d9682e749d3efc642af54d789d9090a6 │ │ │ │ ├── d9682e749d3efc642af54d789d9090a6.info │ │ │ │ ├── d973fc1524e4d724081553934c55958c │ │ │ │ └── d973fc1524e4d724081553934c55958c.info │ │ │ ├── da/ │ │ │ │ ├── dab656c79e1985c40b31faebcda44442 │ │ │ │ └── dab656c79e1985c40b31faebcda44442.info │ │ │ ├── db/ │ │ │ │ ├── db339ef553721e94999125c0b9f909dc │ │ │ │ ├── db339ef553721e94999125c0b9f909dc.info │ │ │ │ ├── db34f310723c62440a05d3e69f262a70 │ │ │ │ ├── db34f310723c62440a05d3e69f262a70.info │ │ │ │ ├── db7dd43fe1278a9459cd6036f096b91d │ │ │ │ ├── db7dd43fe1278a9459cd6036f096b91d.info │ │ │ │ ├── dbd43d8a3b8122d4e89b055f53382b11 │ │ │ │ └── dbd43d8a3b8122d4e89b055f53382b11.info │ │ │ ├── dc/ │ │ │ │ ├── dc42784cf147c0c48a680349fa168899 │ │ │ │ ├── dc42784cf147c0c48a680349fa168899.info │ │ │ │ ├── dc99dfeec967f2644b25dd6bace59b7e │ │ │ │ ├── dc99dfeec967f2644b25dd6bace59b7e.info │ │ │ │ ├── dcb49b07db5e5f64e876b498105314f1 │ │ │ │ ├── dcb49b07db5e5f64e876b498105314f1.info │ │ │ │ ├── dcc8c6e92b172a65719af5ddf47dd968 │ │ │ │ ├── dcc8c6e92b172a65719af5ddf47dd968.info │ │ │ │ ├── dcf00682bef4d264d84a5c92c8f5a40f │ │ │ │ └── dcf00682bef4d264d84a5c92c8f5a40f.info │ │ │ ├── dd/ │ │ │ │ ├── dd2fe74169b54bf58fca17288513ef38 │ │ │ │ ├── dd2fe74169b54bf58fca17288513ef38.info │ │ │ │ ├── dd85a35169d313840a0874aea1a28629 │ │ │ │ └── dd85a35169d313840a0874aea1a28629.info │ │ │ ├── de/ │ │ │ │ ├── de86b4ed8106fd84a8bc2f5d69798d53 │ │ │ │ ├── de86b4ed8106fd84a8bc2f5d69798d53.info │ │ │ │ ├── de9eb5e2046ffc9448f07e495c436506 │ │ │ │ ├── de9eb5e2046ffc9448f07e495c436506.info │ │ │ │ ├── dec586c160776104da4d9a4e472662bc │ │ │ │ ├── dec586c160776104da4d9a4e472662bc.info │ │ │ │ ├── dec9066d4afefe444be0dad3f137730d │ │ │ │ └── dec9066d4afefe444be0dad3f137730d.info │ │ │ ├── df/ │ │ │ │ ├── df1ba932d4ce4534e97a0f10c85cd3c9 │ │ │ │ ├── df1ba932d4ce4534e97a0f10c85cd3c9.info │ │ │ │ ├── df8df80bb65e9ec4280229a9921c4f3c │ │ │ │ ├── df8df80bb65e9ec4280229a9921c4f3c.info │ │ │ │ ├── dfc336f10b83bd74eaded16a658275c7 │ │ │ │ ├── dfc336f10b83bd74eaded16a658275c7.info │ │ │ │ ├── dfd084fea478f3148b7de3d83bab1d8c │ │ │ │ ├── dfd084fea478f3148b7de3d83bab1d8c.info │ │ │ │ ├── dff73c4907c95264c8fc095a81f9d51e │ │ │ │ └── dff73c4907c95264c8fc095a81f9d51e.info │ │ │ ├── e0/ │ │ │ │ ├── e00a5dea786950546a21b0e2d817e466 │ │ │ │ ├── e00a5dea786950546a21b0e2d817e466.info │ │ │ │ ├── e05ace3bd15740cda0bad60d89092a5b │ │ │ │ ├── e05ace3bd15740cda0bad60d89092a5b.info │ │ │ │ ├── e086b15460c228c4f9b116f0e3e2f175 │ │ │ │ ├── e086b15460c228c4f9b116f0e3e2f175.info │ │ │ │ ├── e091bb444874ef244b1ba4a813fc1e34 │ │ │ │ ├── e091bb444874ef244b1ba4a813fc1e34.info │ │ │ │ ├── e0ae6629cc70b514889df37fccb76832 │ │ │ │ ├── e0ae6629cc70b514889df37fccb76832.info │ │ │ │ ├── e0cb37a014cdcb142af891772a27189c │ │ │ │ ├── e0cb37a014cdcb142af891772a27189c.info │ │ │ │ ├── e0db3f3921670cd4ca2e925737c3fba4 │ │ │ │ └── e0db3f3921670cd4ca2e925737c3fba4.info │ │ │ ├── e1/ │ │ │ │ ├── e165a99d845c10e4ea0f546e542e8684 │ │ │ │ ├── e165a99d845c10e4ea0f546e542e8684.info │ │ │ │ ├── e177382a693dea644acd34e3e7a3feb3 │ │ │ │ ├── e177382a693dea644acd34e3e7a3feb3.info │ │ │ │ ├── e17c88b021c2a4c409b3f15b0d80ac62 │ │ │ │ ├── e17c88b021c2a4c409b3f15b0d80ac62.info │ │ │ │ ├── e19747de3f5aca642ab2be37e372fb86 │ │ │ │ ├── e19747de3f5aca642ab2be37e372fb86.info │ │ │ │ ├── e1e957d39ca70834f9212a1289b6a0d5 │ │ │ │ ├── e1e957d39ca70834f9212a1289b6a0d5.info │ │ │ │ ├── e1ef8466c8fd01a549f10baa4d51fa17 │ │ │ │ ├── e1ef8466c8fd01a549f10baa4d51fa17.info │ │ │ │ ├── e1f640f1769d6274194cf97b0e24602c │ │ │ │ └── e1f640f1769d6274194cf97b0e24602c.info │ │ │ ├── e2/ │ │ │ │ ├── e210c8bf2e9c6514d90a1bd77586af1f │ │ │ │ ├── e210c8bf2e9c6514d90a1bd77586af1f.info │ │ │ │ ├── e21bec35f48a44298911b25ead550ce3 │ │ │ │ ├── e21bec35f48a44298911b25ead550ce3.info │ │ │ │ ├── e2392d942829c3b439a231d514e10321 │ │ │ │ ├── e2392d942829c3b439a231d514e10321.info │ │ │ │ ├── e2cd16a2d73fe7a4c9affa2b790eb5e0 │ │ │ │ └── e2cd16a2d73fe7a4c9affa2b790eb5e0.info │ │ │ ├── e3/ │ │ │ │ ├── e3882522a08b6f5459b4dea6f8791278 │ │ │ │ ├── e3882522a08b6f5459b4dea6f8791278.info │ │ │ │ ├── e3b0f810fdea84e40ab4ba20f256f7e8 │ │ │ │ └── e3b0f810fdea84e40ab4ba20f256f7e8.info │ │ │ ├── e4/ │ │ │ │ ├── e4e0b1de1aee400d81ed4273141e7823 │ │ │ │ ├── e4e0b1de1aee400d81ed4273141e7823.info │ │ │ │ ├── e4e290d31ab7fb54880746bb8f818e0d │ │ │ │ └── e4e290d31ab7fb54880746bb8f818e0d.info │ │ │ ├── e5/ │ │ │ │ ├── e52de21a22b6dd44c9cc19f810c65059 │ │ │ │ ├── e52de21a22b6dd44c9cc19f810c65059.info │ │ │ │ ├── e58bd3cca6475e54b93632bb6837aeea │ │ │ │ ├── e58bd3cca6475e54b93632bb6837aeea.info │ │ │ │ ├── e5d490e301a36f04a9397d7257fb157b │ │ │ │ └── e5d490e301a36f04a9397d7257fb157b.info │ │ │ ├── e6/ │ │ │ │ ├── e6323ebef616fee4486ee155cd56d191 │ │ │ │ ├── e6323ebef616fee4486ee155cd56d191.info │ │ │ │ ├── e6413f4090046814d802ddbff9890878 │ │ │ │ ├── e6413f4090046814d802ddbff9890878.info │ │ │ │ ├── e69259f6ff914146ad610be5491eb44a │ │ │ │ ├── e69259f6ff914146ad610be5491eb44a.info │ │ │ │ ├── e6a1d1e3d2384453a7371b4a07a41ca4 │ │ │ │ └── e6a1d1e3d2384453a7371b4a07a41ca4.info │ │ │ ├── e7/ │ │ │ │ ├── e74ddf4132f3401409c824bed60280ee │ │ │ │ ├── e74ddf4132f3401409c824bed60280ee.info │ │ │ │ ├── e763a90581e2d8143bc9a0e384ce6f0f │ │ │ │ ├── e763a90581e2d8143bc9a0e384ce6f0f.info │ │ │ │ ├── e7719e74d14c6ca45a8d38ed1a32e5d9 │ │ │ │ ├── e7719e74d14c6ca45a8d38ed1a32e5d9.info │ │ │ │ ├── e7a505b341283e14696e86433a5b1ae9 │ │ │ │ └── e7a505b341283e14696e86433a5b1ae9.info │ │ │ ├── e8/ │ │ │ │ ├── e801faa3b0dd2478dbe801a2441b679e │ │ │ │ ├── e801faa3b0dd2478dbe801a2441b679e.info │ │ │ │ ├── e88a766c2b8b47841936c136f4afbba9 │ │ │ │ ├── e88a766c2b8b47841936c136f4afbba9.info │ │ │ │ ├── e8c30efa89029e447b0dc0efc75b294c │ │ │ │ └── e8c30efa89029e447b0dc0efc75b294c.info │ │ │ ├── e9/ │ │ │ │ ├── e90cc37a5ccf4a44dbecc5b7172ec512 │ │ │ │ ├── e90cc37a5ccf4a44dbecc5b7172ec512.info │ │ │ │ ├── e9253e696cd45794d9aec6d4de366b6e │ │ │ │ ├── e9253e696cd45794d9aec6d4de366b6e.info │ │ │ │ ├── e93ec7eb6de342aabd156833e253f838 │ │ │ │ ├── e93ec7eb6de342aabd156833e253f838.info │ │ │ │ ├── e9745f6a32442194c8dc5a43e9ab86f9 │ │ │ │ ├── e9745f6a32442194c8dc5a43e9ab86f9.info │ │ │ │ ├── e9a32780b69dcdb438da3e3f43202f54 │ │ │ │ ├── e9a32780b69dcdb438da3e3f43202f54.info │ │ │ │ ├── e9cac674d67385249b2805670e618c24 │ │ │ │ ├── e9cac674d67385249b2805670e618c24.info │ │ │ │ ├── e9df95f53f1c1d0c9199e235d6c42b50 │ │ │ │ └── e9df95f53f1c1d0c9199e235d6c42b50.info │ │ │ ├── ea/ │ │ │ │ ├── ea28dc637ae40484da709200d3328587 │ │ │ │ ├── ea28dc637ae40484da709200d3328587.info │ │ │ │ ├── ea5aa18a49e4f29d74984ea0ea11a238 │ │ │ │ ├── ea5aa18a49e4f29d74984ea0ea11a238.info │ │ │ │ ├── ea5e2240e8a7d9046a651557deec40b2 │ │ │ │ ├── ea5e2240e8a7d9046a651557deec40b2.info │ │ │ │ ├── ea944378afa086f438b3352ad7b0e835 │ │ │ │ ├── ea944378afa086f438b3352ad7b0e835.info │ │ │ │ ├── ea998292f45ea494d9e100f5f6362f91 │ │ │ │ ├── ea998292f45ea494d9e100f5f6362f91.info │ │ │ │ ├── eac7b0dfe80ae8b41b71e9e0c040a433 │ │ │ │ ├── eac7b0dfe80ae8b41b71e9e0c040a433.info │ │ │ │ ├── eafae18265a10964e97bb7c9c1601ef6 │ │ │ │ └── eafae18265a10964e97bb7c9c1601ef6.info │ │ │ ├── eb/ │ │ │ │ ├── eb1eda9941f181549a0b626e36a4dd26 │ │ │ │ ├── eb1eda9941f181549a0b626e36a4dd26.info │ │ │ │ ├── eb221cf55b3544646b0c3b6bc790080f │ │ │ │ ├── eb221cf55b3544646b0c3b6bc790080f.info │ │ │ │ ├── eb9c5f188a065fc42b24d4f24060e6df │ │ │ │ ├── eb9c5f188a065fc42b24d4f24060e6df.info │ │ │ │ ├── ebc4d20cc106cea49b1df1153f0b3b5e │ │ │ │ ├── ebc4d20cc106cea49b1df1153f0b3b5e.info │ │ │ │ ├── ebcc5f899d9277642868aeda9a17cbaf │ │ │ │ ├── ebcc5f899d9277642868aeda9a17cbaf.info │ │ │ │ ├── ebeedaa04bb53e24ba2e7fb6745e3fd3 │ │ │ │ └── ebeedaa04bb53e24ba2e7fb6745e3fd3.info │ │ │ ├── ec/ │ │ │ │ ├── ec02776fe29df900b897106d61977735 │ │ │ │ ├── ec02776fe29df900b897106d61977735.info │ │ │ │ ├── ec06dea06450dae44b5e1f61ed717c4f │ │ │ │ ├── ec06dea06450dae44b5e1f61ed717c4f.info │ │ │ │ ├── ec35c13a8280a8d4e817bc4afd8a95de │ │ │ │ ├── ec35c13a8280a8d4e817bc4afd8a95de.info │ │ │ │ ├── ec7c645d93308c04d8840982af12101e │ │ │ │ ├── ec7c645d93308c04d8840982af12101e.info │ │ │ │ ├── ec817e5e5781e0a4983a1dc8875d1974 │ │ │ │ ├── ec817e5e5781e0a4983a1dc8875d1974.info │ │ │ │ ├── ecc396d20671d454e8020aa864197779 │ │ │ │ ├── ecc396d20671d454e8020aa864197779.info │ │ │ │ ├── ece36bb2bc4128d42911bbc757a56860 │ │ │ │ └── ece36bb2bc4128d42911bbc757a56860.info │ │ │ ├── ed/ │ │ │ │ ├── ed041e68439749a69d0efa0e3d896c2e │ │ │ │ ├── ed041e68439749a69d0efa0e3d896c2e.info │ │ │ │ ├── edc553b1b3c8a25438b62783410b26ae │ │ │ │ ├── edc553b1b3c8a25438b62783410b26ae.info │ │ │ │ ├── edd2a1fe1acbbde43aad39862bb3f4a8 │ │ │ │ ├── edd2a1fe1acbbde43aad39862bb3f4a8.info │ │ │ │ ├── edd4f4b395430604d935bcf0b14c7d42 │ │ │ │ ├── edd4f4b395430604d935bcf0b14c7d42.info │ │ │ │ ├── ede0462698a4a5643aa9872c074acd38 │ │ │ │ └── ede0462698a4a5643aa9872c074acd38.info │ │ │ ├── ee/ │ │ │ │ ├── ee148e281f3c41c5b4ff5f8a5afe5a6c │ │ │ │ ├── ee148e281f3c41c5b4ff5f8a5afe5a6c.info │ │ │ │ ├── ee83d5e1ad2ac4c9aa39e3a6f256062e │ │ │ │ ├── ee83d5e1ad2ac4c9aa39e3a6f256062e.info │ │ │ │ ├── eea34a28297f9bc4c9f4c573bc8d5d1c │ │ │ │ ├── eea34a28297f9bc4c9f4c573bc8d5d1c.info │ │ │ │ ├── eebde5009793ce948bf5d4c4435b89b9 │ │ │ │ └── eebde5009793ce948bf5d4c4435b89b9.info │ │ │ ├── ef/ │ │ │ │ ├── ef4c81c9368d5a340b14c2fec1cad345 │ │ │ │ ├── ef4c81c9368d5a340b14c2fec1cad345.info │ │ │ │ ├── ef563c5a6ecf64d4193dc144cb7d472a │ │ │ │ ├── ef563c5a6ecf64d4193dc144cb7d472a.info │ │ │ │ ├── ef5fa6e2005defb4ab5142723827b58e │ │ │ │ ├── ef5fa6e2005defb4ab5142723827b58e.info │ │ │ │ ├── ef97f39912c138b4cabdccedfb24093b │ │ │ │ ├── ef97f39912c138b4cabdccedfb24093b.info │ │ │ │ ├── efad3ddb7270ac241b9b1357ec5ee2f2 │ │ │ │ ├── efad3ddb7270ac241b9b1357ec5ee2f2.info │ │ │ │ ├── efcf753a96a07b24dbe5f23a8ad5963d │ │ │ │ ├── efcf753a96a07b24dbe5f23a8ad5963d.info │ │ │ │ ├── effb76e1937b45ff8adf45e51a4c08cf │ │ │ │ └── effb76e1937b45ff8adf45e51a4c08cf.info │ │ │ ├── f0/ │ │ │ │ ├── f06555f75b070af458a003d92f9efb00 │ │ │ │ ├── f06555f75b070af458a003d92f9efb00.info │ │ │ │ ├── f079e3afd077fb94fa2bda74d6409499 │ │ │ │ ├── f079e3afd077fb94fa2bda74d6409499.info │ │ │ │ ├── f0f13f2ab3d6d13cfc6e4656824bfca8 │ │ │ │ └── f0f13f2ab3d6d13cfc6e4656824bfca8.info │ │ │ ├── f1/ │ │ │ │ ├── f136f1f122a53c64c9af51baecaa9c96 │ │ │ │ ├── f136f1f122a53c64c9af51baecaa9c96.info │ │ │ │ ├── f15cbb987069826429540d0ea0937442 │ │ │ │ ├── f15cbb987069826429540d0ea0937442.info │ │ │ │ ├── f1605f5534186904fa2c4c42acbfe01e │ │ │ │ ├── f1605f5534186904fa2c4c42acbfe01e.info │ │ │ │ ├── f16e09785c984c445a0467e30f845636 │ │ │ │ ├── f16e09785c984c445a0467e30f845636.info │ │ │ │ ├── f1b6399349763114d9361bc6dfcd025b │ │ │ │ ├── f1b6399349763114d9361bc6dfcd025b.info │ │ │ │ ├── f1c6f7ed858be004eb1c56dada7ee838 │ │ │ │ ├── f1c6f7ed858be004eb1c56dada7ee838.info │ │ │ │ ├── f1ea944dcf8849ebab391e461b99ccb7 │ │ │ │ └── f1ea944dcf8849ebab391e461b99ccb7.info │ │ │ ├── f3/ │ │ │ │ ├── f32e959de7955be41a4af6dac2f75b09 │ │ │ │ ├── f32e959de7955be41a4af6dac2f75b09.info │ │ │ │ ├── f33e570b8b9af1048b80a27e7848cb09 │ │ │ │ ├── f33e570b8b9af1048b80a27e7848cb09.info │ │ │ │ ├── f3a361a6ad1aff14ba8f48976e94ad76 │ │ │ │ ├── f3a361a6ad1aff14ba8f48976e94ad76.info │ │ │ │ ├── f3e1b3cbf3fac6a459b1a602167ad311 │ │ │ │ └── f3e1b3cbf3fac6a459b1a602167ad311.info │ │ │ ├── f4/ │ │ │ │ ├── f4452670096a14945b20cca112e82047 │ │ │ │ ├── f4452670096a14945b20cca112e82047.info │ │ │ │ ├── f445ca0c614a846449fcd8ae648c24e2 │ │ │ │ ├── f445ca0c614a846449fcd8ae648c24e2.info │ │ │ │ ├── f4688fdb7df04437aeb418b961361dc5 │ │ │ │ ├── f4688fdb7df04437aeb418b961361dc5.info │ │ │ │ ├── f4935fb862d54980b1bcbca942962642 │ │ │ │ ├── f4935fb862d54980b1bcbca942962642.info │ │ │ │ ├── f49bbe06ffa5ae24abe32abdab430c24 │ │ │ │ ├── f49bbe06ffa5ae24abe32abdab430c24.info │ │ │ │ ├── f4f988528bbbb0846a4cb50efb4587a5 │ │ │ │ └── f4f988528bbbb0846a4cb50efb4587a5.info │ │ │ ├── f5/ │ │ │ │ ├── f525580684527b147b70cf94aaa70dbc │ │ │ │ ├── f525580684527b147b70cf94aaa70dbc.info │ │ │ │ ├── f5600e6ae5a1464da659eca36bef9d64 │ │ │ │ ├── f5600e6ae5a1464da659eca36bef9d64.info │ │ │ │ ├── f5a0cc9645f0e2d4fb816156dcf3f4dd │ │ │ │ └── f5a0cc9645f0e2d4fb816156dcf3f4dd.info │ │ │ ├── f6/ │ │ │ │ ├── f601c0d674119f74db9c15166b3a58c4 │ │ │ │ ├── f601c0d674119f74db9c15166b3a58c4.info │ │ │ │ ├── f603edd7163537f44927ad2808147a25 │ │ │ │ ├── f603edd7163537f44927ad2808147a25.info │ │ │ │ ├── f65646ef159c91441bff704a5f7f419b │ │ │ │ ├── f65646ef159c91441bff704a5f7f419b.info │ │ │ │ ├── f66454863bc106549a6b53849ee63b41 │ │ │ │ ├── f66454863bc106549a6b53849ee63b41.info │ │ │ │ ├── f68c7f7359094f045930a108c444e7a4 │ │ │ │ ├── f68c7f7359094f045930a108c444e7a4.info │ │ │ │ ├── f695b5f9415c40b39ae877eaff41c96e │ │ │ │ ├── f695b5f9415c40b39ae877eaff41c96e.info │ │ │ │ ├── f6ba30c492ac73742bc0cfee6817045a │ │ │ │ ├── f6ba30c492ac73742bc0cfee6817045a.info │ │ │ │ ├── f6bb32665bcc91b41a7177fd6af08ad6 │ │ │ │ ├── f6bb32665bcc91b41a7177fd6af08ad6.info │ │ │ │ ├── f6bd368ab00d75c459e2582e017191e6 │ │ │ │ ├── f6bd368ab00d75c459e2582e017191e6.info │ │ │ │ ├── f6c189a159d3bde4c964cee562e508ea │ │ │ │ ├── f6c189a159d3bde4c964cee562e508ea.info │ │ │ │ ├── f6d64d8648793944dbadfd71f0f4b0a1 │ │ │ │ └── f6d64d8648793944dbadfd71f0f4b0a1.info │ │ │ ├── f7/ │ │ │ │ ├── f700f31b2e40d7f4bb69753fdbbbc2b5 │ │ │ │ ├── f700f31b2e40d7f4bb69753fdbbbc2b5.info │ │ │ │ ├── f73fc901e4b0f2d4daf11f46506054ba │ │ │ │ ├── f73fc901e4b0f2d4daf11f46506054ba.info │ │ │ │ ├── f779e779d62b5ca49b658236c337845d │ │ │ │ ├── f779e779d62b5ca49b658236c337845d.info │ │ │ │ ├── f7852b99951997645ae7adaac5f0b083 │ │ │ │ ├── f7852b99951997645ae7adaac5f0b083.info │ │ │ │ ├── f7a8357347c80dc69c08d0b1a05e2122 │ │ │ │ ├── f7a8357347c80dc69c08d0b1a05e2122.info │ │ │ │ ├── f7e61a6fdb34813479ec9e958a030910 │ │ │ │ ├── f7e61a6fdb34813479ec9e958a030910.info │ │ │ │ ├── f7fed0d9d0f7a7f41a8525aa79e790b1 │ │ │ │ └── f7fed0d9d0f7a7f41a8525aa79e790b1.info │ │ │ ├── f8/ │ │ │ │ ├── f817a38900380be47942905e17e7d39b │ │ │ │ ├── f817a38900380be47942905e17e7d39b.info │ │ │ │ ├── f867743975592a743a3581ff042bcc25 │ │ │ │ ├── f867743975592a743a3581ff042bcc25.info │ │ │ │ ├── f8730045d7da0f84cb11c0d868899577 │ │ │ │ ├── f8730045d7da0f84cb11c0d868899577.info │ │ │ │ ├── f8964ef46e1d446dc9eb17a36a3e1f14 │ │ │ │ ├── f8964ef46e1d446dc9eb17a36a3e1f14.info │ │ │ │ ├── f8e6a2d47aba4c6c9b3c5a72d9f48da5 │ │ │ │ ├── f8e6a2d47aba4c6c9b3c5a72d9f48da5.info │ │ │ │ ├── f8ed4321a98682942b9980996131cf26 │ │ │ │ ├── f8ed4321a98682942b9980996131cf26.info │ │ │ │ ├── f8f889eee05c15349bc81eeb0883357d │ │ │ │ └── f8f889eee05c15349bc81eeb0883357d.info │ │ │ ├── f9/ │ │ │ │ ├── f91a00d2dca52b843b2d50ccf750737d │ │ │ │ ├── f91a00d2dca52b843b2d50ccf750737d.info │ │ │ │ ├── f92aa236053c90f41a2e272a05c9186d │ │ │ │ ├── f92aa236053c90f41a2e272a05c9186d.info │ │ │ │ ├── f944311c8fff2479fa3ba741f6039fc8 │ │ │ │ ├── f944311c8fff2479fa3ba741f6039fc8.info │ │ │ │ ├── f96d0ea807c081145a1170ed1b6d71e0 │ │ │ │ ├── f96d0ea807c081145a1170ed1b6d71e0.info │ │ │ │ ├── f9bd02a3a916be64c9b47b1305149423 │ │ │ │ ├── f9bd02a3a916be64c9b47b1305149423.info │ │ │ │ ├── f9d8c8b21846a654092a24f25aa41421 │ │ │ │ └── f9d8c8b21846a654092a24f25aa41421.info │ │ │ ├── fa/ │ │ │ │ ├── fa27413e9edb06a6058d6c894eca0338 │ │ │ │ ├── fa27413e9edb06a6058d6c894eca0338.info │ │ │ │ ├── fa423365b1ce06a4dbdc6fb4a8597bfa │ │ │ │ ├── fa423365b1ce06a4dbdc6fb4a8597bfa.info │ │ │ │ ├── fa6bd40a216346b783a4cce741d277a5 │ │ │ │ └── fa6bd40a216346b783a4cce741d277a5.info │ │ │ ├── fb/ │ │ │ │ ├── fb1eb8dd5509788428a96514cc36f0d0 │ │ │ │ ├── fb1eb8dd5509788428a96514cc36f0d0.info │ │ │ │ ├── fb27f3049fe06c246803a4a4c5b7fda3 │ │ │ │ ├── fb27f3049fe06c246803a4a4c5b7fda3.info │ │ │ │ ├── fb461734117c80c43ab595d699f801eb │ │ │ │ ├── fb461734117c80c43ab595d699f801eb.info │ │ │ │ ├── fb5730e24283d0c489e5c7d0bee023d9 │ │ │ │ ├── fb5730e24283d0c489e5c7d0bee023d9.info │ │ │ │ ├── fb593906b7b6d824087dcaebf6c082e0 │ │ │ │ ├── fb593906b7b6d824087dcaebf6c082e0.info │ │ │ │ ├── fb660d86885d89a499a31c6ab6f26269 │ │ │ │ └── fb660d86885d89a499a31c6ab6f26269.info │ │ │ ├── fc/ │ │ │ │ ├── fc34cd6ea308f3940a729e1a44cd0e82 │ │ │ │ ├── fc34cd6ea308f3940a729e1a44cd0e82.info │ │ │ │ ├── fc3a810351931f5e6183e16b9beb5563 │ │ │ │ ├── fc3a810351931f5e6183e16b9beb5563.info │ │ │ │ ├── fc46f91ea1e8e4ca2ab693fef9156dbe │ │ │ │ ├── fc46f91ea1e8e4ca2ab693fef9156dbe.info │ │ │ │ ├── fc748d99f1f0d484a811a566fc7915ec │ │ │ │ ├── fc748d99f1f0d484a811a566fc7915ec.info │ │ │ │ ├── fc8d686a4c18b8d49bb1db4150de0459 │ │ │ │ ├── fc8d686a4c18b8d49bb1db4150de0459.info │ │ │ │ ├── fcae021c30eccf74790a4e816ba97c19 │ │ │ │ ├── fcae021c30eccf74790a4e816ba97c19.info │ │ │ │ ├── fcb9be00baf924c4183fc0313e6185c5 │ │ │ │ ├── fcb9be00baf924c4183fc0313e6185c5.info │ │ │ │ ├── fcc60c1d6bb544d9b712b652f418ff3a │ │ │ │ ├── fcc60c1d6bb544d9b712b652f418ff3a.info │ │ │ │ ├── fcd66bf74cbeb264aa99679c7df84427 │ │ │ │ └── fcd66bf74cbeb264aa99679c7df84427.info │ │ │ ├── fd/ │ │ │ │ ├── fd0a39b4d296d4d509b4f1dbd08d0630 │ │ │ │ ├── fd0a39b4d296d4d509b4f1dbd08d0630.info │ │ │ │ ├── fd57cf917f61bbb42b8f030436426ddd │ │ │ │ ├── fd57cf917f61bbb42b8f030436426ddd.info │ │ │ │ ├── fd6ede1d2f47ab146b2ec0a3969a37cc │ │ │ │ ├── fd6ede1d2f47ab146b2ec0a3969a37cc.info │ │ │ │ ├── fd871a8be47119612f7c254e96a822b7 │ │ │ │ ├── fd871a8be47119612f7c254e96a822b7.info │ │ │ │ ├── fda82b5ca7a4c5f40b497c4f5f4bd950 │ │ │ │ ├── fda82b5ca7a4c5f40b497c4f5f4bd950.info │ │ │ │ ├── fdb35ef8fc437e14fa4b6c74a0609e86 │ │ │ │ ├── fdb35ef8fc437e14fa4b6c74a0609e86.info │ │ │ │ ├── fdd19c82588da3e498a0c98951efa6c4 │ │ │ │ ├── fdd19c82588da3e498a0c98951efa6c4.info │ │ │ │ ├── fde0d25a170598d46a0b9dc16b4527a5 │ │ │ │ └── fde0d25a170598d46a0b9dc16b4527a5.info │ │ │ ├── fe/ │ │ │ │ ├── fe03a7b0ba57a4d488b6c327ae16c335 │ │ │ │ ├── fe03a7b0ba57a4d488b6c327ae16c335.info │ │ │ │ ├── fe4aef60e4ace544c8430da8ef8acba2 │ │ │ │ ├── fe4aef60e4ace544c8430da8ef8acba2.info │ │ │ │ ├── fe87c0e1cc204ed48ad3b37840f39efc │ │ │ │ ├── fe87c0e1cc204ed48ad3b37840f39efc.info │ │ │ │ ├── fea12beeeb5a7a448b5e60f50e40975d │ │ │ │ ├── fea12beeeb5a7a448b5e60f50e40975d.info │ │ │ │ ├── fea49a0730244a98bf1087f7ca9410a8 │ │ │ │ ├── fea49a0730244a98bf1087f7ca9410a8.info │ │ │ │ ├── fed9dda667cab45d398d06402bba03f4 │ │ │ │ ├── fed9dda667cab45d398d06402bba03f4.info │ │ │ │ ├── fedb0f9e5006b1943abae52f52f08a1a │ │ │ │ └── fedb0f9e5006b1943abae52f52f08a1a.info │ │ │ └── ff/ │ │ │ ├── ff67c526455160f4690a44f74dee4cbe │ │ │ ├── ff67c526455160f4690a44f74dee4cbe.info │ │ │ ├── ff97302ee78d6ad478b433ec557ee303 │ │ │ ├── ff97302ee78d6ad478b433ec557ee303.info │ │ │ ├── ffb335140c799c4408411d81789fb05c │ │ │ ├── ffb335140c799c4408411d81789fb05c.info │ │ │ ├── ffc6271f08270b64ca0aae9c49235d81 │ │ │ ├── ffc6271f08270b64ca0aae9c49235d81.info │ │ │ ├── ffcbe86028d681144b703991885c535a │ │ │ └── ffcbe86028d681144b703991885c535a.info │ │ ├── shadercompiler-UnityShaderCompiler.exe0.log │ │ ├── shadercompiler-UnityShaderCompiler.exe1.log │ │ ├── shadercompiler-UnityShaderCompiler.exe2.log │ │ ├── shadercompiler-UnityShaderCompiler.exe3.log │ │ ├── shadercompiler-UnityShaderCompiler.exe4.log │ │ ├── shadercompiler-UnityShaderCompiler.exe5.log │ │ ├── shadercompiler-UnityShaderCompiler.exe6.log │ │ └── shadercompiler-UnityShaderCompiler.exe7.log │ ├── Logs/ │ │ └── Packages-Update.log │ ├── Packages/ │ │ └── manifest.json │ ├── ProjectSettings/ │ │ ├── AudioManager.asset │ │ ├── ClusterInputManager.asset │ │ ├── DynamicsManager.asset │ │ ├── EditorBuildSettings.asset │ │ ├── EditorSettings.asset │ │ ├── GraphicsSettings.asset │ │ ├── InputManager.asset │ │ ├── NavMeshAreas.asset │ │ ├── NavMeshLayers.asset │ │ ├── NetworkManager.asset │ │ ├── PackageManagerSettings.asset │ │ ├── Physics2DSettings.asset │ │ ├── PresetManager.asset │ │ ├── ProjectSettings.asset │ │ ├── ProjectVersion.txt │ │ ├── QualitySettings.asset │ │ ├── TagManager.asset │ │ ├── TimeManager.asset │ │ ├── UnityConnectSettings.asset │ │ ├── VFXManager.asset │ │ └── XRSettings.asset │ ├── obj/ │ │ ├── Debug/ │ │ │ ├── Assembly-CSharp-Editor.csproj.FileListAbsolute.txt │ │ │ ├── Assembly-CSharp-Editor.csprojResolveAssemblyReference.cache │ │ │ ├── Assembly-CSharp-Editor.pdb │ │ │ ├── Assembly-CSharp.csproj.FileListAbsolute.txt │ │ │ ├── Assembly-CSharp.csprojResolveAssemblyReference.cache │ │ │ ├── Assembly-CSharp.pdb │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ └── Release/ │ │ ├── Assembly-CSharp.csproj.FileListAbsolute.txt │ │ └── Assembly-CSharp.pdb │ ├── scattererShaders-csharp.sln │ └── scattererShaders.sln ├── Proland/ │ └── Textures/ │ └── Atmo/ │ ├── inscatter.raw │ ├── irradiance.raw │ └── transmittance.raw ├── Scatterer.cs ├── Utilities/ │ ├── Camera/ │ │ ├── DepthPrePassMerger.cs │ │ ├── DepthToDistanceCommandBuffer.cs │ │ ├── DisableAmbientLight.cs │ │ ├── DisableEffectsChecker.cs │ │ ├── DisableEffectsForReflectionsCamera.cs │ │ ├── ReflectionProbeChecker.cs │ │ ├── ReflectionProbeFixer.cs │ │ ├── ScreenCopyCommandBuffer.cs │ │ ├── TweakShadowCascades.cs │ │ └── WireFrame.cs │ ├── Dx12UnifiedCamera.cs │ ├── EVE/ │ │ └── EVEReflectionHandler.cs │ ├── Math/ │ │ ├── MathUtility.cs │ │ ├── Matrix3x3.cs │ │ ├── Matrix3x3d.cs │ │ ├── Matrix4x4d.cs │ │ ├── Quat.cs │ │ ├── Vector2d.cs │ │ ├── Vector2i.cs │ │ ├── Vector3d2.cs │ │ └── Vector4d.cs │ ├── Misc/ │ │ ├── IcoSphere.cs │ │ ├── MeshFactory.cs │ │ ├── PlanetSecondaryLightUpdater.cs │ │ └── Utils.cs │ ├── Occlusion/ │ │ ├── ShadowMapCopier.cs │ │ ├── ShadowMapRetrieveCommandBuffer.cs │ │ ├── ShadowMaskCopyCommandBuffer.cs │ │ ├── ShadowMaskModulateCommandBuffer.cs │ │ └── ShadowRemoveFadeCommandBuffer.cs │ ├── ReflectionUtils.cs │ ├── Shader/ │ │ ├── ShaderProperties.cs │ │ └── ShaderReplacer.cs │ ├── Textures/ │ │ ├── RenderTextureUtils.cs │ │ └── VRUtils.cs │ └── VsyncStartupFix.cs ├── scatterer.csproj └── scatterer.sln ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.userprefs scatterer/obj scatterer/bin scatterer/bin/Release/Assembly-CSharp-firstpass.dll scatterer/bin/Release/Assembly-CSharp.dll scatterer/bin/Release/Mono.Cecil.dll scatterer/bin/Release/Mono.Security.dll scatterer/bin/Release/mscorlib.dll scatterer/bin/Release/System.Core.dll scatterer/bin/Release/System.dll scatterer/bin/Release/System.Xml.dll scatterer/bin/Release/TDx.TDxInput.dll scatterer/bin/Release/TrackIRUnity.dll scatterer/bin/Release/UnityEngine.dll scatterer/Shaders/scattererShaders/Library ================================================ FILE: Readme.md ================================================ Scatterer --------------------------------------------------------------------------------- Atmospheric scattering graphical effects for Kerbal Space Program. This project contains the plugin source which is under the following license: GNU GENERAL PUBLIC LICENSE Version 3 This repo does not contain shaders for versions higher than 0.0772 and they are not necessary to compile/load the plugin. Shaders are loaded dynamically from asset bundles and can be replaced by custom shaders. Copyright (c) 2015-2022 Ghassen Lahmar ================================================ FILE: license.md ================================================ Copyright (c) 2015-2022 Ghassen Lahmar You may use, distribute and copy Scatterer under the terms of GNU General Public License version 3, which is displayed below. ------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS /* * Proland: a procedural landscape rendering library. * Website : http://proland.inrialpes.fr/ * Copyright (c) 2008-2015 INRIA - LJK (CNRS - Grenoble University) * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Proland is distributed under the Berkeley Software Distribution 3 Licence. * For any assistance, feedback and enquiries about training programs, you can check out the * contact page on our website : * http://proland.inrialpes.fr/ */ /* * Main authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. */ /* * Proland-To-Unity * Website: https://github.com/Scrawk/Proland-To-Unity */ /* * BSD 3-Clause License * * Copyright (c) 2022, Justin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Intel Corporation - Outdoor Light Scattering Sample * Website:https://github.com/GameTechDev/OutdoorLightScattering */ /* * * Apache License * Version 2.0, January 2004 * * http://www.apache.org/licenses/ * * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION * * 1. Definitions. * * "License" shall mean the terms and conditions for use, reproduction, and * distribution as defined by Sections 1 through 9 of this document. * * "Licensor" shall mean the copyright owner or entity authorized by the copyright * owner that is granting the License. * * "Legal Entity" shall mean the union of the acting entity and all other entities * that control, are controlled by, or are under common control with that entity. * For the purposes of this definition, "control" means (i) the power, direct or * indirect, to cause the direction or management of such entity, whether by * contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the * outstanding shares, or (iii) beneficial ownership of such entity. * * "You" (or "Your") shall mean an individual or Legal Entity exercising * permissions granted by this License. * * "Source" form shall mean the preferred form for making modifications, including * but not limited to software source code, documentation source, and configuration * files. * * "Object" form shall mean any form resulting from mechanical transformation or * translation of a Source form, including but not limited to compiled object code, * generated documentation, and conversions to other media types. * * "Work" shall mean the work of authorship, whether in Source or Object form, made * available under the License, as indicated by a copyright notice that is included * in or attached to the work (an example is provided in the Appendix below). * * "Derivative Works" shall mean any work, whether in Source or Object form, that * is based on (or derived from) the Work and for which the editorial revisions, * annotations, elaborations, or other modifications represent, as a whole, an * original work of authorship. For the purposes of this License, Derivative Works * shall not include works that remain separable from, or merely link (or bind by * name) to the interfaces of, the Work and Derivative Works thereof. * * "Contribution" shall mean any work of authorship, including the original version * of the Work and any modifications or additions to that Work or Derivative Works * thereof, that is intentionally submitted to Licensor for inclusion in the Work * by the copyright owner or by an individual or Legal Entity authorized to submit * on behalf of the copyright owner. For the purposes of this definition, * "submitted" means any form of electronic, verbal, or written communication sent * to the Licensor or its representatives, including but not limited to * communication on electronic mailing lists, source code control systems, and * issue tracking systems that are managed by, or on behalf of, the Licensor for * the purpose of discussing and improving the Work, but excluding communication * that is conspicuously marked or otherwise designated in writing by the copyright * owner as "Not a Contribution." * * "Contributor" shall mean Licensor and any individual or Legal Entity on behalf * of whom a Contribution has been received by Licensor and subsequently * incorporated within the Work. * * 2. Grant of Copyright License. Subject to the terms and conditions of this * License, each Contributor hereby grants to You a perpetual, worldwide, * non-exclusive, no-charge, royalty-free, irrevocable copyright license to * reproduce, prepare Derivative Works of, publicly display, publicly perform, * sublicense, and distribute the Work and such Derivative Works in Source or * Object form. * * 3. Grant of Patent License. Subject to the terms and conditions of this License, * each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, * no-charge, royalty-free, irrevocable (except as stated in this section) patent * license to make, have made, use, offer to sell, sell, import, and otherwise * transfer the Work, where such license applies only to those patent claims * licensable by such Contributor that are necessarily infringed by their * Contribution(s) alone or by combination of their Contribution(s) with the Work * to which such Contribution(s) was submitted. If You institute patent litigation * against any entity (including a cross-claim or counterclaim in a lawsuit) * alleging that the Work or a Contribution incorporated within the Work * constitutes direct or contributory patent infringement, then any patent licenses * granted to You under this License for that Work shall terminate as of the date * such litigation is filed. * * 4. Redistribution. You may reproduce and distribute copies of the Work or * Derivative Works thereof in any medium, with or without modifications, and in * Source or Object form, provided that You meet the following conditions: * You must give any other recipients of the Work or Derivative Works a copy of * this License; and * * * You must cause any modified files to carry prominent notices stating that You * changed the files; and * * * You must retain, in the Source form of any Derivative Works that You * distribute, all copyright, patent, trademark, and attribution notices from the * Source form of the Work, excluding those notices that do not pertain to any * part of the Derivative Works; and * * * If the Work includes a "NOTICE" text file as part of its distribution, then * any Derivative Works that You distribute must include a readable copy of the * attribution notices contained within such NOTICE file, excluding those notices * that do not pertain to any part of the Derivative Works, in at least one of * the following places: within a NOTICE text file distributed as part of the * Derivative Works; within the Source form or documentation, if provided along * with the Derivative Works; or, within a display generated by the Derivative * Works, if and wherever such third-party notices normally appear. The contents * of the NOTICE file are for informational purposes only and do not modify the * License. You may add Your own attribution notices within Derivative Works that * You distribute, alongside or as an addendum to the NOTICE text from the Work, * provided that such additional attribution notices cannot be construed as * modifying the License. * You may add Your own copyright statement to Your modifications and may provide * additional or different license terms and conditions for use, reproduction, or * distribution of Your modifications, or for any such Derivative Works as a whole, * provided Your use, reproduction, and distribution of the Work otherwise complies * with the conditions stated in this License. * * 5. Submission of Contributions. Unless You explicitly state otherwise, any * Contribution intentionally submitted for inclusion in the Work by You to the * Licensor shall be under the terms and conditions of this License, without any * additional terms or conditions. Notwithstanding the above, nothing herein shall * supersede or modify the terms of any separate license agreement you may have * executed with Licensor regarding such Contributions. * * 6. Trademarks. This License does not grant permission to use the trade names, * trademarks, service marks, or product names of the Licensor, except as required * for reasonable and customary use in describing the origin of the Work and * reproducing the content of the NOTICE file. * * 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in * writing, Licensor provides the Work (and each Contributor provides its * Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied, including, without limitation, any warranties * or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A * PARTICULAR PURPOSE. You are solely responsible for determining the * appropriateness of using or redistributing the Work and assume any risks * associated with Your exercise of permissions under this License. * * 8. Limitation of Liability. In no event and under no legal theory, whether in * tort (including negligence), contract, or otherwise, unless required by * applicable law (such as deliberate and grossly negligent acts) or agreed to in * writing, shall any Contributor be liable to You for damages, including any * direct, indirect, special, incidental, or consequential damages of any character * arising as a result of this License or out of the use or inability to use the * Work (including but not limited to damages for loss of goodwill, work stoppage, * computer failure or malfunction, or any and all other commercial damages or * losses), even if such Contributor has been advised of the possibility of such * damages. * * 9. Accepting Warranty or Additional Liability. While redistributing the Work or * Derivative Works thereof, You may choose to offer, and charge a fee for, * acceptance of support, warranty, indemnity, or other liability obligations * and/or rights consistent with this License. However, in accepting such * obligations, You may act only on Your own behalf and on Your sole * responsibility, not on behalf of any other Contributor, and only if You agree to * indemnify, defend, and hold each Contributor harmless for any liability incurred * by, or claims asserted against, such Contributor by reason of your accepting any * such warranty or additional liability. * * END OF TERMS AND CONDITIONS * * APPENDIX: How to apply the Apache License to your work * * To apply the Apache License to your work, attach the following boilerplate * notice, with the fields enclosed by brackets "[]" replaced with your own * identifying information. (Don't include the brackets!) The text should be * enclosed in the appropriate comment syntax for the file format. We also * recommend that a file or class name and description of purpose be included on * the same "printed page" as the copyright notice for easier identification within * third-party archives. * * Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or * agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and * limitations under the License. */ ================================================ FILE: scatterer/CelestialBodySortableByDistance.cs ================================================ using System; using System.Collections.Generic; namespace scatterer { public class celestialBodySortableByDistance : IEquatable , IComparable { public CelestialBody CelestialBody { get; set; } public float Distance { get; set; } public bool usesScatterer { get; set; } public int scattererIndex { get; set; } public override string ToString() { return "dist: " + Distance + " CelestialBodyName: " + CelestialBody.name; } public override bool Equals(object obj) { if (obj == null) return false; celestialBodySortableByDistance objAsCelestialBodySortableByDistance = obj as celestialBodySortableByDistance; if (objAsCelestialBodySortableByDistance == null) return false; else return Equals(objAsCelestialBodySortableByDistance); } public int SortByNameAscending(string name1, string name2) { return name1.CompareTo(name2); } // Default comparer for Part type. public int CompareTo(celestialBodySortableByDistance comparecelestialBodySortableByDistance) { // A null value means that this object is greater. if (comparecelestialBodySortableByDistance == null) return 1; else return this.Distance.CompareTo(comparecelestialBodySortableByDistance.Distance); } public override int GetHashCode() { return (int)Distance; } public bool Equals(celestialBodySortableByDistance other) { if (other == null) return false; return (this.Distance.Equals(other.Distance)); } // Should also override == and != operators. } } ================================================ FILE: scatterer/DataSerialization/ConfigPoint.cs ================================================ using System; using UnityEngine; namespace Scatterer { public class ConfigPoint { [Persistent] public float altitude; [Persistent] public float skyExposure; [Persistent] public float skyAlpha; [Persistent] public float skyExtinctionTint; [Persistent] public float scatteringExposure; [Persistent] public float extinctionThickness; [Persistent] public float postProcessAlpha; [Persistent] public float postProcessDepth; [Persistent] public float extinctionTint; public ConfigPoint(float inAltitude,float inSkyAlpha,float inSkyExposure,float inPostProcessAlpha, float inPostProcessDepth,float inPostProcessExposure, float inSkyExtinctionTint, float in_Post_Extinction_Tint, float inExtinctionThickness) { altitude=inAltitude; skyAlpha=inSkyAlpha; skyExposure=inSkyExposure; postProcessAlpha=inPostProcessAlpha; postProcessDepth=inPostProcessDepth; scatteringExposure=inPostProcessExposure; skyExtinctionTint=inSkyExtinctionTint; extinctionTint = in_Post_Extinction_Tint; extinctionThickness = inExtinctionThickness; } public void getValuesFrom(ConfigPoint inConfigPoint) { skyAlpha=inConfigPoint.skyAlpha; skyExposure=inConfigPoint.skyExposure; postProcessAlpha=inConfigPoint.postProcessAlpha; postProcessDepth=inConfigPoint.postProcessDepth; scatteringExposure=inConfigPoint.scatteringExposure; skyExtinctionTint=inConfigPoint.skyExtinctionTint; extinctionTint = inConfigPoint.extinctionTint; extinctionThickness = inConfigPoint.extinctionThickness; } public void interpolateValuesFrom(ConfigPoint inConfigPoint1, ConfigPoint inConfigPoint2, float x) { skyAlpha=Mathf.Lerp(inConfigPoint1.skyAlpha, inConfigPoint2.skyAlpha ,x); skyExposure=Mathf.Lerp(inConfigPoint1.skyExposure, inConfigPoint2.skyExposure ,x); postProcessAlpha=Mathf.Lerp(inConfigPoint1.postProcessAlpha, inConfigPoint2.postProcessAlpha ,x); postProcessDepth=Mathf.Lerp(inConfigPoint1.postProcessDepth, inConfigPoint2.postProcessDepth ,x); scatteringExposure=Mathf.Lerp(inConfigPoint1.scatteringExposure, inConfigPoint2.scatteringExposure ,x); skyExtinctionTint=Mathf.Lerp(inConfigPoint1.skyExtinctionTint, inConfigPoint2.skyExtinctionTint ,x); extinctionTint = Mathf.Lerp(inConfigPoint1.extinctionTint, inConfigPoint2.extinctionTint ,x); extinctionThickness = Mathf.Lerp(inConfigPoint1.extinctionThickness, inConfigPoint2.extinctionThickness ,x); } public ConfigPoint() { } } } ================================================ FILE: scatterer/DataSerialization/ConfigReader.cs ================================================ using System.Collections; using System.Collections.Generic; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class ConfigReader { [Persistent] public List scattererCelestialBodies = new List {}; [Persistent] public List celestialLightSourcesData=new List {}; public ConfigNode[] sunflareConfigs; public UrlDir.UrlConfig[] baseConfigs,atmoConfigs,oceanConfigs; public void loadConfigs () { baseConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_config"); //only used for displaying filepath ConfigNode[] confNodes = GameDatabase.Instance.GetConfigNodes ("Scatterer_planetsList"); if (confNodes.Length == 0) { Utils.LogError ("No planetsList file found, check your install"); return; } if (confNodes.Length > 1) { Utils.LogError ("Multiple planetsList files detected, check your install"); } ConfigNode.LoadObjectFromConfig (this, confNodes [0]); atmoConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_atmosphere"); oceanConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_ocean"); sunflareConfigs = GameDatabase.Instance.GetConfigNodes ("Scatterer_sunflare"); } } } ================================================ FILE: scatterer/DataSerialization/MainSettingsReadWrite.cs ================================================ using System.Collections; using System.Collections.Generic; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class MainSettingsReadWrite { [Persistent] public bool autosavePlanetSettingsOnSceneChange=false; [Persistent] public bool disableAmbientLight=true; [Persistent] public bool integrateWithEVEClouds=true; // [Persistent] // public bool integrateEVECloudsGodrays=true; [Persistent] public bool overrideNearClipPlane=false; [Persistent] public float nearClipPlane=0.5f; [Persistent] public bool useOceanShaders = true; [Persistent] public bool oceanFoam = true; [Persistent] public bool oceanTransparencyAndRefractions = true; [Persistent] public bool shadowsOnOcean = true; [Persistent] public bool oceanSkyReflections = true; [Persistent] public bool oceanCaustics = true; [Persistent] public bool oceanLightRays = false; [Persistent] public bool oceanCraftWaveInteractions = true; [Persistent] public bool oceanCraftWaveInteractionsOverrideWaterCrashTolerance = true; [Persistent] public float buoyancyCrashToleranceMultOverride=1.2f * 3f; [Persistent] public bool oceanCraftWaveInteractionsOverrideDrag = true; [Persistent] public bool oceanCraftWaveInteractionsOverrideRecoveryVelocity = true; [Persistent] public float waterMaxRecoveryVelocity = 5f; [Persistent] public bool oceanPixelLights = false; [Persistent] public bool fullLensFlareReplacement = true; [Persistent] public bool sunlightExtinction = true; [Persistent] public bool underwaterLightDimming = true; [Persistent] public bool showMenuOnStart = true; [Persistent] public bool useEclipses = true; [Persistent] public bool useRingShadows = true; //[Persistent] public bool usePlanetShine = false; [Persistent] public bool d3d11ShadowFix = true; [Persistent] public bool useLegacyTerrainGodrays = false; //[Persistent] public bool mergeDepthPrePass = false; //[Persistent] public bool quarterResScattering = true; [Persistent] public bool useSubpixelMorphologicalAntialiasing = true; [Persistent] public int smaaQuality = 0; [Persistent] public bool useTemporalAntiAliasing = true; [Persistent] public float taaStationaryBlending = 0.90f; [Persistent] public float taaMotionBlending = 0.55f; [Persistent] public float taaJitterSpread = 0.9f; [Persistent] public float taaSharpness = 0.25f; [Persistent] public int disableTaaBelowFrameRateThreshold = 26; [Persistent] public bool terrainShadows = false; //0 - None, 1 - Bruneton, 2 - Uncharted, 3 - Hable but disabled [Persistent] public int scatteringTonemapper = 2; /* [Persistent] public float hableToeStrength; [Persistent] public float hableToeLength; [Persistent] public float hableShoulderStrength; [Persistent] public float hableShoulderLength; [Persistent] public float hableShoulderAngle; [Persistent] public float hableGamma; */ [Persistent] public float unifiedCamShadowsDistance=50000f; [Persistent] public float unifiedCamShadowNormalBiasOverride=0.4f; [Persistent] public float unifiedCamShadowBiasOverride=0.125f; [Persistent] public int unifiedCamShadowResolutionOverride=0; [Persistent] public Vector3 unifiedCamShadowCascadeSplitsOverride=Vector3.zero; [Persistent] public float dualCamShadowsDistance=50000f; [Persistent] public float dualCamShadowNormalBiasOverride=0.4f; [Persistent] public float dualCamShadowBiasOverride=0.125f; [Persistent] public int dualCamShadowResolutionOverride=0; [Persistent] public Vector3 dualCamShadowCascadeSplitsOverride=Vector3.zero; [Persistent] public bool useDithering = true; [Persistent] public int m_fourierGridSize = 64; [Persistent] public int oceanMeshResolution = 8; [Persistent] public bool useLowResolutionAtmosphere = false; public void loadMainSettings () { UrlDir.UrlConfig[] baseConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_config"); if (baseConfigs.Length == 0) { Utils.LogError ("No config file found, check your install"); return; } if (baseConfigs.Length > 1) { Utils.LogError ("Multiple config files detected, check your install"); } ConfigNode.LoadObjectFromConfig (this, (baseConfigs [0]).config); } public void saveMainSettingsIfChanged() { UrlDir.UrlConfig[] baseConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_config"); if (baseConfigs.Length == 0) { Utils.LogDebug ("No config file found, check your install"); return; } if (baseConfigs.Length > 1) { Utils.LogDebug ("Multiple config files detected, check your install"); } MainSettingsReadWrite OldConfig = new MainSettingsReadWrite (); ConfigNode.LoadObjectFromConfig (OldConfig, (baseConfigs [0]).config); bool configChanged = (OldConfig.autosavePlanetSettingsOnSceneChange != autosavePlanetSettingsOnSceneChange || OldConfig.disableAmbientLight != disableAmbientLight || OldConfig.integrateWithEVEClouds != integrateWithEVEClouds || // OldConfig.integrateEVECloudsGodrays != integrateEVECloudsGodrays || OldConfig.overrideNearClipPlane != overrideNearClipPlane || OldConfig.nearClipPlane != nearClipPlane || OldConfig.useOceanShaders != useOceanShaders || OldConfig.oceanFoam != oceanFoam || OldConfig.oceanTransparencyAndRefractions != oceanTransparencyAndRefractions || OldConfig.shadowsOnOcean != shadowsOnOcean || OldConfig.oceanSkyReflections != oceanSkyReflections || OldConfig.oceanCaustics != oceanCaustics || OldConfig.oceanLightRays != oceanLightRays || OldConfig.oceanCraftWaveInteractions != oceanCraftWaveInteractions || OldConfig.oceanCraftWaveInteractionsOverrideWaterCrashTolerance != oceanCraftWaveInteractionsOverrideWaterCrashTolerance || OldConfig.buoyancyCrashToleranceMultOverride != buoyancyCrashToleranceMultOverride || OldConfig.oceanCraftWaveInteractionsOverrideDrag != oceanCraftWaveInteractionsOverrideDrag || OldConfig.oceanCraftWaveInteractionsOverrideRecoveryVelocity != oceanCraftWaveInteractionsOverrideRecoveryVelocity || OldConfig.waterMaxRecoveryVelocity != waterMaxRecoveryVelocity || OldConfig.oceanPixelLights != oceanPixelLights || OldConfig.fullLensFlareReplacement != fullLensFlareReplacement || OldConfig.sunlightExtinction != sunlightExtinction || OldConfig.underwaterLightDimming != underwaterLightDimming || OldConfig.showMenuOnStart != showMenuOnStart || OldConfig.useEclipses != useEclipses || OldConfig.useRingShadows != useRingShadows || OldConfig.d3d11ShadowFix != d3d11ShadowFix || OldConfig.useLegacyTerrainGodrays != useLegacyTerrainGodrays || //OldConfig.mergeDepthPrePass != mergeDepthPrePass || OldConfig.quarterResScattering != quarterResScattering || OldConfig.useSubpixelMorphologicalAntialiasing != useSubpixelMorphologicalAntialiasing || OldConfig.smaaQuality != smaaQuality || OldConfig.useTemporalAntiAliasing != useTemporalAntiAliasing || OldConfig.taaStationaryBlending != taaStationaryBlending || OldConfig.taaMotionBlending != taaMotionBlending || OldConfig.taaJitterSpread != taaJitterSpread || OldConfig.taaSharpness != taaSharpness || OldConfig.disableTaaBelowFrameRateThreshold != disableTaaBelowFrameRateThreshold || OldConfig.terrainShadows != terrainShadows || OldConfig.scatteringTonemapper != scatteringTonemapper || /* OldConfig.hableToeStrength != hableToeStrength || OldConfig.hableToeLength != hableToeLength || OldConfig.hableShoulderStrength != hableShoulderStrength || OldConfig.hableShoulderLength != hableShoulderLength || OldConfig.hableShoulderAngle != hableShoulderAngle || OldConfig.hableGamma != hableGamma || */ OldConfig.useDithering != useDithering || OldConfig.unifiedCamShadowsDistance != unifiedCamShadowsDistance || OldConfig.unifiedCamShadowNormalBiasOverride != unifiedCamShadowNormalBiasOverride || OldConfig.unifiedCamShadowBiasOverride != unifiedCamShadowBiasOverride || OldConfig.unifiedCamShadowCascadeSplitsOverride != unifiedCamShadowCascadeSplitsOverride || OldConfig.unifiedCamShadowResolutionOverride != unifiedCamShadowResolutionOverride || OldConfig.dualCamShadowsDistance != dualCamShadowsDistance || OldConfig.dualCamShadowNormalBiasOverride != dualCamShadowNormalBiasOverride || OldConfig.dualCamShadowBiasOverride != dualCamShadowBiasOverride || OldConfig.dualCamShadowCascadeSplitsOverride != dualCamShadowCascadeSplitsOverride || OldConfig.dualCamShadowResolutionOverride != dualCamShadowResolutionOverride || OldConfig.m_fourierGridSize != m_fourierGridSize || OldConfig.oceanMeshResolution != oceanMeshResolution) || OldConfig.useLowResolutionAtmosphere != useLowResolutionAtmosphere; if (configChanged) { Utils.LogDebug("Main config changed"); baseConfigs [0].config = ConfigNode.CreateConfigFromObject (this); baseConfigs [0].config.name = "Scatterer_config"; Utils.LogDebug ("Saving settings to: " + baseConfigs [0].parent.url+".cfg"); baseConfigs [0].parent.SaveConfigs (); } else { Utils.LogDebug("No changes to main config, skipping saving."); } } } } ================================================ FILE: scatterer/DataSerialization/PlanetshineSource.cs ================================================ using System; using UnityEngine; using System.Collections.Generic; namespace Scatterer { public class AtmoPlanetShineSource { [Persistent] public string bodyName; [Persistent] public Vector3 color; [Persistent] public float intensity; [Persistent] public bool isSun; public CelestialBody body; } public class PlanetShineLightSource { [Persistent] public string bodyName; [Persistent] public Vector3 color; [Persistent] public float intensity; [Persistent] public bool isSun; [Persistent] public string mainSunCelestialBody; [Persistent] public float localRange; [Persistent] public float scaledRange; [Persistent] public float fadeRadius; } } ================================================ FILE: scatterer/DataSerialization/PluginDataReadWrite.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class PluginDataReadWrite { [Persistent] public string guiModifierKey1String=KeyCode.LeftAlt.ToString(); [Persistent] public string guiModifierKey2String=KeyCode.RightAlt.ToString(); [Persistent] public string guiKey1String=KeyCode.F10.ToString(); [Persistent] public string guiKey2String=KeyCode.F11.ToString(); [Persistent] public int scrollSectionHeight = 500; [Persistent] public Vector2 inGameWindowLocation=Vector2.zero; public KeyCode guiKey1, guiKey2, guiModifierKey1, guiModifierKey2 ; public void loadPluginData () { try { ConfigNode confNode = ConfigNode.Load (Utils.PluginPath + "/config/PluginData/pluginData.cfg"); ConfigNode.LoadObjectFromConfig (this, confNode); guiKey1 = (KeyCode)Enum.Parse(typeof(KeyCode), guiKey1String); guiKey2 = (KeyCode)Enum.Parse(typeof(KeyCode), guiKey2String); guiModifierKey1 = (KeyCode)Enum.Parse(typeof(KeyCode), guiModifierKey1String); guiModifierKey2 = (KeyCode)Enum.Parse(typeof(KeyCode), guiModifierKey2String); } catch (Exception stupid) { Utils.LogError("Couldn't load pluginData "+stupid.ToString()); } } public void savePluginData () { try { var dir = Utils.PluginPath + "/config/PluginData"; if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir); ConfigNode cnTemp = ConfigNode.CreateConfigFromObject (this); cnTemp.Save (dir + "/pluginData.cfg"); } catch (Exception stupid) { Utils.LogError("Couldn't save pluginData "+stupid.ToString()); } } } } ================================================ FILE: scatterer/DataSerialization/QualityPresetsLoader.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class QualityPresetsLoader { public static String[] GetPresetsList() { List presetStrings = new List (); UrlDir.UrlConfig[] presetsList = GameDatabase.Instance.GetConfigs ("Scatterer_quality_preset"); foreach (UrlDir.UrlConfig _url in presetsList) { ConfigNode[] configNodeArray = _url.config.GetNodes("Quality_preset"); foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name")) { presetStrings.Add(_cn.GetValue("name")); } } } return presetStrings.ToArray(); } public static void LoadPresetIntoMainSettings(MainSettingsReadWrite settings, string presetName) { List presetStrings = new List (); UrlDir.UrlConfig[] presetsList = GameDatabase.Instance.GetConfigs ("Scatterer_quality_preset"); foreach (UrlDir.UrlConfig _url in presetsList) { ConfigNode[] configNodeArray = _url.config.GetNodes("Quality_preset"); foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name") && (_cn.GetValue("name") == presetName)) { LoadConfigNodeIntoMainSettings(settings, _cn); break; } } } } private static void LoadConfigNodeIntoMainSettings(MainSettingsReadWrite settings, ConfigNode cn) { MainSettingsReadWrite tempMainSettings = new MainSettingsReadWrite(); Type targetType = tempMainSettings.GetType (); ConfigNode.LoadObjectFromConfig (tempMainSettings, cn); foreach (FieldInfo fi in targetType.GetFields()) { if (cn.HasValue(fi.Name)) { fi.SetValue(settings, fi.GetValue(tempMainSettings)); } } } public static string FindPresetOfCurrentSettings(MainSettingsReadWrite settings) { UrlDir.UrlConfig[] presetsList = GameDatabase.Instance.GetConfigs ("Scatterer_quality_preset"); foreach (UrlDir.UrlConfig _url in presetsList) { ConfigNode[] configNodeArray = _url.config.GetNodes("Quality_preset"); foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name")) { if (PresetMatchesCurrentSettings(settings,_cn)) { return _cn.GetValue("name"); } } } } return ("No preset - custom settings"); } private static bool PresetMatchesCurrentSettings(MainSettingsReadWrite settings, ConfigNode cn) { MainSettingsReadWrite tempMainSettings = new MainSettingsReadWrite(); Type targetType = tempMainSettings.GetType (); ConfigNode.LoadObjectFromConfig (tempMainSettings, cn); bool match = true; bool compared = false; foreach (FieldInfo fi in targetType.GetFields()) { if (cn.HasValue(fi.Name)) { if (!CompareFields(fi, settings, tempMainSettings)) { return false; } compared = true; } } return match && compared; } private static bool CompareFields(FieldInfo fi, MainSettingsReadWrite settings1, MainSettingsReadWrite settings2) { if (fi.FieldType == typeof(float)) { return ((float)(fi.GetValue (settings1)) == (float)(fi.GetValue (settings2))); } else if (fi.FieldType == typeof(int)) { return ((int)(fi.GetValue (settings1)) == (int)(fi.GetValue (settings2))); } else if (fi.FieldType == typeof(bool)) { return ((bool)(fi.GetValue (settings1)) == (bool)(fi.GetValue (settings2))); } else if (fi.FieldType == typeof(Vector3)) { return ((Vector3)(fi.GetValue (settings1)) == (Vector3)(fi.GetValue (settings2))); } Utils.LogError("Unhandled preset type? "+fi.FieldType.ToString()); return false; } } } ================================================ FILE: scatterer/DataSerialization/ScattererCelestialBody.cs ================================================ using System; using UnityEngine; using System.Collections.Generic; using System.Linq; namespace Scatterer { public class ScattererCelestialBody { [Persistent] public string celestialBodyName; [Persistent] public string transformName; [Persistent] public float loadDistance; [Persistent] public float unloadDistance; [Persistent] public bool hasOcean; [Persistent] public bool usesCloudIntegration; [Persistent] public bool cloudIntegrationUsesScattererSunColors = false; [Persistent] public bool flatScaledSpaceModel; [Persistent] public string mainSunCelestialBody; [Persistent] public bool sunsUseIntensityCurves = false; [Persistent] public Color sunColor = Color.white; [Persistent] public List eclipseCasters=new List {}; [Persistent] public List secondarySuns=new List {}; [Persistent] public List planetshineSources=new List {}; public CelestialBody celestialBody; public Transform transform; public bool isFound = false; public bool active; public ProlandManager prolandManager; public ScattererCelestialBody () { } } public class SecondarySunConfig { [Persistent] public string celestialBodyName; [Persistent] public Color sunColor = Color.white; //[Persistent] public List eclipseCasters=new List {}; //maybe don't do this at the start? or at all, especially since we will half-ass it by not being able to eclipse light on terrain anyway } public class SecondarySun { public SecondarySunConfig config; public CelestialBody celestialBody; public Light sunLight = null; public Light scaledSunLight = null; //public List eclipseCasters=new List {}; public SecondarySun (SecondarySunConfig inConfig, CelestialBody body) { config = inConfig; celestialBody = body; } public static SecondarySun FindSecondarySun (SecondarySunConfig inConfig) { var celestialBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == inConfig.celestialBodyName); if (celestialBody == null) { Utils.LogError ("Secondary sun " + inConfig.celestialBodyName + " not found, will be unavailable for atmo/ocean effects"); return null; } else { SecondarySun secondarySun = new SecondarySun(inConfig, celestialBody); return secondarySun; } } } } ================================================ FILE: scatterer/Effects/AntiAliasing/GenericAntiAliasing.cs ================================================ using UnityEngine; namespace Scatterer { public abstract class GenericAntiAliasing : MonoBehaviour { public GenericAntiAliasing () { } } } ================================================ FILE: scatterer/Effects/AntiAliasing/SubpixelMorphologicalAntialiasing.cs ================================================ using System; using UnityEngine; using UnityEngine.Rendering; namespace Scatterer { public class SubpixelMorphologicalAntialiasing : GenericAntiAliasing { Camera targetCamera; CommandBuffer SMAACommandBuffer; Material SMAAMaterial; enum Pass { EdgeDetection = 0, BlendWeights = 3, NeighborhoodBlending = 6 } public enum Quality { DepthMode = 0, Medium = 1, High = 2 } private static CameraEvent SMAACameraEvent = CameraEvent.AfterForwardAlpha; // BeforeImageEffects doesn't work well Quality quality; public void forceDepthBuffermode() { quality = Quality.DepthMode; initialized = false; } int flipRenderTargetNameID, flopRenderTargetNameID; static Texture2D areaTex, searchTex; bool initialized = false; bool hdrEnabled = false; public Quality QualityUsed { get => quality; } public void Awake() { targetCamera = GetComponent (); targetCamera.forceIntoRenderTexture = true; hdrEnabled = targetCamera.allowHDR; // surely there are better names for these? They're both temporaries flipRenderTargetNameID = Shader.PropertyToID("_SMAA_Flip"); flopRenderTargetNameID = Shader.PropertyToID("_SMAA_Flop"); SMAAMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/SubpixelMorphologicalAntialiasing")]); if (areaTex == null) areaTex = (Texture2D) ShaderReplacer.Instance.LoadedTextures ["AreaTex"]; if (searchTex == null) searchTex = (Texture2D)ShaderReplacer.Instance.LoadedTextures ["SearchTex"]; SMAAMaterial.SetTexture("_AreaTex" , areaTex); SMAAMaterial.SetTexture("_SearchTex", searchTex); quality = (Quality)((Int32) Mathf.Clamp( (float) Scatterer.Instance.mainSettings.smaaQuality,1f,2f)); //limit to 1 and 2, 1 and 2 are image-based. 0 is depth-based and would make performance worse by having to run for each camera's depth //only use depth mode when we force it for the IVA camera SMAACommandBuffer = new CommandBuffer (); SMAACommandBuffer.name = $"Scatterer SMAA CommandBuffer for {targetCamera.name}"; } static readonly int MainTextureProperty = Shader.PropertyToID("_MainTexture"); static readonly int BlendTexproperty = Shader.PropertyToID("_BlendTex"); public void OnPreCull() { if (!initialized || targetCamera.allowHDR != hdrEnabled) { SMAACommandBuffer.Clear (); hdrEnabled = targetCamera.allowHDR; var colorFormat = hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32; SMAACommandBuffer.GetTemporaryRT(flipRenderTargetNameID, -1, -1, 0, FilterMode.Bilinear, colorFormat); // TODO: how do we make sure to match the previous settings? Do we need to use RenderTextureDescriptor? //flip.anisoLevel = 1; //flip.antiAliasing = 1; //flip.volumeDepth = 0; //flip.useMipMap = false; //flip.autoGenerateMips = false; //flip.wrapMode = TextureWrapMode.Clamp; //flip.filterMode = FilterMode.Bilinear; SMAACommandBuffer.GetTemporaryRT(flopRenderTargetNameID, -1, -1, 0, FilterMode.Bilinear, colorFormat); SMAACommandBuffer.SetRenderTarget (flopRenderTargetNameID); SMAACommandBuffer.ClearRenderTarget (false, true, Color.clear); SMAACommandBuffer.SetRenderTarget (flipRenderTargetNameID); SMAACommandBuffer.ClearRenderTarget (false, true, Color.clear); SMAACommandBuffer.SetGlobalTexture (MainTextureProperty, BuiltinRenderTextureType.CameraTarget); SMAACommandBuffer.Blit (null, flipRenderTargetNameID, SMAAMaterial, (int)Pass.EdgeDetection + (int)quality); //screen to flip with edge detection SMAACommandBuffer.SetGlobalTexture (MainTextureProperty, flipRenderTargetNameID); SMAACommandBuffer.Blit (null, flopRenderTargetNameID, SMAAMaterial, (int)Pass.BlendWeights + (int)quality); //flip to flop with blendweights SMAACommandBuffer.SetGlobalTexture (BlendTexproperty, flopRenderTargetNameID); SMAACommandBuffer.SetGlobalTexture (MainTextureProperty, BuiltinRenderTextureType.CameraTarget); SMAACommandBuffer.Blit (null, flipRenderTargetNameID, SMAAMaterial, (int)Pass.NeighborhoodBlending); //neighborhood blending to flip SMAACommandBuffer.Blit (flipRenderTargetNameID, BuiltinRenderTextureType.CameraTarget); //blit back to screen targetCamera.AddCommandBuffer (SMAACameraEvent, SMAACommandBuffer); initialized = true; } } public void OnDestroy() { SMAAMaterial = null; if (SMAACommandBuffer !=null) { targetCamera.RemoveCommandBuffer (SMAACameraEvent, SMAACommandBuffer); SMAACommandBuffer.Clear(); SMAACommandBuffer.Release(); SMAACommandBuffer = null; initialized = false; } } } } ================================================ FILE: scatterer/Effects/AntiAliasing/TemporalAntiAliasing.cs ================================================ using UnityEngine; using UnityEngine.Rendering; using UnityEngine.XR; namespace Scatterer { // Temporal anti-aliasing from Unity post-processing stack V2 // Modified to not blur the ocean, removed dependency on other postprocessing classes I don't need here so we can initialize and make everything work by just adding this to a camera // Generating motion vectors for the ocean is both expensive and unnecessary so we should just not apply TAA on the ocean, otherwise it would just blur it without proper motion vectors public class TemporalAntiAliasing : GenericAntiAliasing { public float jitterSpread = 0.9f; //The diameter (in texels) inside which jitter samples are spread. Smaller values result in crisper but more aliased output, while larger values result in more stable, but blurrier, output. Range(0.1f, 1f) public float sharpness = 0.25f; //Controls the amount of sharpening applied to the color buffer. High values may introduce dark-border artifacts. Range(0f, 3f) public float stationaryBlending = 0.90f; //The blend coefficient for a stationary fragment. Controls the percentage of history sample blended into the final color. Range(0f, 0.99f) public float motionBlending = 0.55f; //The blend coefficient for a fragment with significant motion. Controls the percentage of history sample blended into the final color. Range(0f, 0.99f) public Vector2 jitter { get; private set; } // The current jitter amount public int sampleIndex { get; private set; } // The current sample index enum Pass {SolverDilate, SolverNoDilate} readonly RenderTargetIdentifier[] m_Mrt = new RenderTargetIdentifier[2]; bool m_ResetHistory = true; bool hdrEnabled = false; const int k_SampleCount = 8; // Ping-pong between two history textures as we can't read & write the same target in the same pass const int eyesCount = 2; const int historyTexturesCount = 2; RenderTexture[][] historyTextures = new RenderTexture[eyesCount][]; int[] m_HistoryPingPong = new int [eyesCount]; Camera targetCamera; CommandBuffer temporalAACommandBuffer; Material temporalAAMaterial; DepthTextureMode originalDepthTextureMode; public bool checkOceanDepth = false; public bool jitterTransparencies = false; public bool resetMotionVectors = true; private static int jitterProperty = Shader.PropertyToID("_Jitter"); private static int keepPreviousMotionVectorsProperty = Shader.PropertyToID("TAA_KeepPreviousMotionVectors"); private static CameraEvent TAACameraEvent = CameraEvent.AfterForwardAlpha; // BeforeImageEffects doesn't work well bool firstFrame = true; public void Awake() { targetCamera = GetComponent(); originalDepthTextureMode = targetCamera.depthTextureMode; targetCamera.depthTextureMode = DepthTextureMode.Depth | DepthTextureMode.MotionVectors; targetCamera.forceIntoRenderTexture = true; temporalAAMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/TemporalAntialiasing")]); Utils.EnableOrDisableShaderKeywords(temporalAAMaterial, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", false); jitterSpread = Scatterer.Instance.mainSettings.taaJitterSpread; sharpness = Scatterer.Instance.mainSettings.taaSharpness; stationaryBlending = Scatterer.Instance.mainSettings.taaStationaryBlending; motionBlending = Scatterer.Instance.mainSettings.taaMotionBlending; const float kMotionAmplification = 100f * 60f; temporalAAMaterial.SetFloat("_Sharpness", sharpness); temporalAAMaterial.SetVector("_FinalBlendParameters", new Vector4(stationaryBlending, motionBlending, kMotionAmplification, 0f)); temporalAACommandBuffer = new CommandBuffer(); temporalAACommandBuffer.name = $"Scatterer TAA CommandBuffer for {targetCamera.name}"; } internal DepthTextureMode GetCameraFlags() { return DepthTextureMode.Depth | DepthTextureMode.MotionVectors; } internal void ResetHistory() { m_ResetHistory = true; } Vector2 GenerateRandomOffset() { // The variance between 0 and the actual halton sequence values reveals noticeable instability // in Unity's shadow maps, so we avoid index 0. var offset = new Vector2( HaltonSeq.Get((sampleIndex & 1023) + 1, 2) - 0.5f, HaltonSeq.Get((sampleIndex & 1023) + 1, 3) - 0.5f ); if (++sampleIndex >= k_SampleCount) sampleIndex = 0; return offset; } private static class RuntimeUtilities { /// Gets a jittered perspective projection matrix for a given camera. public static Matrix4x4 GetJitteredPerspectiveProjectionMatrix(Camera camera, Vector2 offset) { float near = camera.nearClipPlane; float far = camera.farClipPlane; float vertical = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView) * near; float horizontal = vertical * camera.aspect; offset.x *= horizontal / (0.5f * camera.pixelWidth); offset.y *= vertical / (0.5f * camera.pixelHeight); var matrix = camera.projectionMatrix; matrix[0, 2] += offset.x / horizontal; matrix[1, 2] += offset.y / vertical; return matrix; } public static Matrix4x4 GetJitteredOrthographicProjectionMatrix(Camera camera, Vector2 offset) { float vertical = camera.orthographicSize; float horizontal = vertical * camera.aspect; offset.x *= horizontal / (0.5f * camera.pixelWidth); offset.y *= vertical / (0.5f * camera.pixelHeight); float left = offset.x - horizontal; float right = offset.x + horizontal; float top = offset.y + vertical; float bottom = offset.y - vertical; return Matrix4x4.Ortho(left, right, bottom, top, camera.nearClipPlane, camera.farClipPlane); } public static Matrix4x4 GenerateJitteredProjectionMatrixFromOriginal(int screenWidth, int screenHeight, Matrix4x4 origProj, Vector2 jitter) { var planes = origProj.decomposeProjection; float vertFov = Mathf.Abs(planes.top) + Mathf.Abs(planes.bottom); float horizFov = Mathf.Abs(planes.left) + Mathf.Abs(planes.right); var planeJitter = new Vector2(jitter.x * horizFov / screenWidth, jitter.y * vertFov / screenHeight); planes.left += planeJitter.x; planes.right += planeJitter.x; planes.top += planeJitter.y; planes.bottom += planeJitter.y; var jitteredMatrix = Matrix4x4.Frustum(planes); return jitteredMatrix; } } /// Generates a jittered projection matrix for a given camera. public Matrix4x4 GetJitteredProjectionMatrix(Camera camera) { Matrix4x4 cameraProj; jitter = GenerateRandomOffset(); jitter *= jitterSpread; cameraProj = camera.orthographic ? RuntimeUtilities.GetJitteredOrthographicProjectionMatrix(camera, jitter) : RuntimeUtilities.GetJitteredPerspectiveProjectionMatrix(camera, jitter); jitter = new Vector2(jitter.x / camera.pixelWidth, jitter.y / camera.pixelHeight); return cameraProj; } /// Prepares the jittered and non jittered projection matrices public void ConfigureJitteredProjectionMatrix(Camera camera) { // camera.nonJitteredProjectionMatrix = camera.projectionMatrix; // should this be here? it's in the stock postprocess code camera.projectionMatrix = GetJitteredProjectionMatrix(camera); camera.useJitteredProjectionMatrixForTransparentRendering = jitterTransparencies; } public void ConfigureStereoJitteredProjectionMatrices(Camera camera) { jitter = GenerateRandomOffset(); jitter *= jitterSpread; // see PostProcessRenderContext.camera set property int screenWidth, screenHeight; if (camera.stereoEnabled) { screenWidth = XRSettings.eyeTextureWidth; screenHeight = XRSettings.eyeTextureHeight; } else { screenWidth = camera.pixelWidth; screenHeight = camera.pixelHeight; } for (var eye = Camera.StereoscopicEye.Left; eye <= Camera.StereoscopicEye.Right; eye++) { // This saves off the device generated projection matrices as non-jittered camera.CopyStereoDeviceProjectionMatrixToNonJittered(eye); var originalProj = camera.GetStereoNonJitteredProjectionMatrix(eye); // Currently no support for custom jitter func, as VR devices would need to provide // original projection matrix as input along with jitter var jitteredMatrix = RuntimeUtilities.GenerateJitteredProjectionMatrixFromOriginal(screenWidth, screenHeight, originalProj, jitter); camera.SetStereoProjectionMatrix(eye, jitteredMatrix); } // jitter has to be scaled for the actual eye texture size, not just the intermediate texture size // which could be double-wide in certain stereo rendering scenarios jitter = new Vector2(jitter.x / screenWidth, jitter.y / screenHeight); camera.useJitteredProjectionMatrixForTransparentRendering = jitterTransparencies; } RenderTexture CheckHistory(int id, CommandBuffer cmd, int activeEye) { if (historyTextures[activeEye] == null) historyTextures[activeEye] = new RenderTexture[historyTexturesCount]; if (hdrEnabled != targetCamera.allowHDR) ResetHistory(); var historyRT = historyTextures[activeEye][id]; if (m_ResetHistory || historyRT == null || !historyRT.IsCreated()) { RenderTexture.ReleaseTemporary(historyRT); int width, height; if (targetCamera.activeTexture) { width = targetCamera.activeTexture.width; height = targetCamera.activeTexture.height; } else { width = Screen.width; height = Screen.height; } hdrEnabled = targetCamera.allowHDR; historyRT = RenderTexture.GetTemporary (width, height, 0, hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32); historyRT.name = "Temporal Anti-aliasing History id #" + id; historyRT.filterMode = FilterMode.Bilinear; historyTextures[activeEye][id] = historyRT; cmd.Blit(BuiltinRenderTextureType.CameraTarget, historyRT); } return historyTextures[activeEye][id]; } //adapted from the original render() method public void OnPreCull() { bool screenShotModeEnabled = GameSettings.TAKE_SCREENSHOT.GetKeyDown(false); float currentFps = 1.0f / Time.deltaTime; bool aboveFpsThreshold = currentFps >= Scatterer.Instance.mainSettings.disableTaaBelowFrameRateThreshold || !Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing; if (!screenShotModeEnabled && aboveFpsThreshold) { temporalAACommandBuffer.Clear(); int activeEye = targetCamera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right ? 1 : 0; int pingPongIndex = m_HistoryPingPong[activeEye]; RenderTexture historyRead = CheckHistory(++pingPongIndex % 2, temporalAACommandBuffer, activeEye); RenderTexture historyWrite = CheckHistory(++pingPongIndex % 2, temporalAACommandBuffer, activeEye); m_HistoryPingPong[activeEye] = ++pingPongIndex % 2; if (firstFrame) { temporalAACommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, historyWrite); } else { ConfigureJitteredProjectionMatrix(targetCamera); //TODO: move to shader properties if (checkOceanDepth) Utils.EnableOrDisableShaderKeywords(temporalAAMaterial, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", Scatterer.Instance.scattererCelestialBodiesManager.isCustomOceanEnabledOnScattererPlanet); temporalAAMaterial.SetTexture(ShaderProperties._HistoryTex_PROPERTY, historyRead); int pass = (int)Pass.SolverDilate; temporalAACommandBuffer.SetGlobalTexture(ShaderProperties._ScreenColor_PROPERTY, BuiltinRenderTextureType.CameraTarget); temporalAACommandBuffer.Blit(null, historyWrite, temporalAAMaterial, pass); temporalAACommandBuffer.Blit(historyWrite, BuiltinRenderTextureType.CameraTarget); } targetCamera.AddCommandBuffer (TAACameraEvent, temporalAACommandBuffer); m_ResetHistory = false; firstFrame = false; if (resetMotionVectors) { Shader.SetGlobalInt(keepPreviousMotionVectorsProperty, 0); } else { Shader.SetGlobalInt(keepPreviousMotionVectorsProperty, 1); } } else { firstFrame = true; } } public void OnPostRender() { ResetProjection(); targetCamera.RemoveCommandBuffer (TAACameraEvent, temporalAACommandBuffer); } // This is needed otherwise transparencies jitter public void ResetProjection() { targetCamera.ResetProjectionMatrix(); targetCamera.nonJitteredProjectionMatrix = targetCamera.projectionMatrix; } public void OnDestroy() { if (temporalAACommandBuffer != null) targetCamera.RemoveCommandBuffer (TAACameraEvent, temporalAACommandBuffer); targetCamera.depthTextureMode = originalDepthTextureMode; if (historyTextures != null) { for (int i = 0; i < historyTextures.Length; i++) { if (historyTextures[i] == null) continue; for (int j = 0; j < historyTextures[i].Length; j++) { RenderTexture.ReleaseTemporary(historyTextures[i][j]); historyTextures[i][j] = null; } historyTextures[i] = null; } } sampleIndex = 0; m_HistoryPingPong[0] = 0; m_HistoryPingPong[1] = 1; ResetHistory(); targetCamera.ResetProjectionMatrix(); } } } ================================================ FILE: scatterer/Effects/AntiAliasing/Utils/HaltonSeq.cs ================================================ namespace Scatterer { /// Halton sequence utility from unity post-processing stack V2 public static class HaltonSeq { /// /// Gets a value from the Halton sequence for a given index and radix. /// /// The sequence index /// The sequence base /// A number from the Halton sequence between 0 and 1. public static float Get(int index, int radix) { float result = 0f; float fraction = 1f / (float)radix; while (index > 0) { result += (float)(index % radix) * fraction; index /= radix; fraction /= (float)radix; } return result; } } } ================================================ FILE: scatterer/Effects/PlanetShine/PlanetShineLight.cs ================================================ using System; using UnityEngine; namespace Scatterer { public class PlanetShineLight : MonoBehaviour { public GameObject scaledLight, localLight; public bool isSun; public CelestialBody source, sunCelestialBody; public void updateLight() { scaledLight.gameObject.transform.position=ScaledSpace.LocalToScaledSpace(source.transform.position); localLight.gameObject.transform.position=(source.transform.position); if (!isSun) { localLight.gameObject.transform.LookAt(sunCelestialBody.transform.position); scaledLight.gameObject.transform.LookAt (ScaledSpace.LocalToScaledSpace (sunCelestialBody.transform.position)); } } public void OnDestroy() { UnityEngine.Object.Destroy (scaledLight); UnityEngine.Object.Destroy (localLight); } } } ================================================ FILE: scatterer/Effects/PlanetShine/PlanetshineManager.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Scatterer { public class PlanetshineManager { List celestialLightSources=new List {}; Cubemap planetShineCookieCubeMap; public PlanetshineManager () { //load planetshine "cookie" cubemap planetShineCookieCubeMap = new Cubemap (512, TextureFormat.ARGB32, true); Texture2D[] cubeMapFaces = new Texture2D[6]; for (int i = 0; i < 6; i++) { cubeMapFaces [i] = new Texture2D (512, 512); } cubeMapFaces [0].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_NegativeX.png"))); cubeMapFaces [1].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_PositiveX.png"))); cubeMapFaces [2].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_NegativeY.png"))); cubeMapFaces [3].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_PositiveY.png"))); cubeMapFaces [4].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_NegativeZ.png"))); cubeMapFaces [5].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_PositiveZ.png"))); planetShineCookieCubeMap.SetPixels (cubeMapFaces [0].GetPixels (), CubemapFace.NegativeX); planetShineCookieCubeMap.SetPixels (cubeMapFaces [1].GetPixels (), CubemapFace.PositiveX); planetShineCookieCubeMap.SetPixels (cubeMapFaces [2].GetPixels (), CubemapFace.NegativeY); planetShineCookieCubeMap.SetPixels (cubeMapFaces [3].GetPixels (), CubemapFace.PositiveY); planetShineCookieCubeMap.SetPixels (cubeMapFaces [4].GetPixels (), CubemapFace.NegativeZ); planetShineCookieCubeMap.SetPixels (cubeMapFaces [5].GetPixels (), CubemapFace.PositiveZ); planetShineCookieCubeMap.Apply (); foreach (PlanetShineLightSource _aSource in Scatterer.Instance.planetsConfigsReader.celestialLightSourcesData) { var celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == _aSource.bodyName); if (celBody) { PlanetShineLight aPsLight = new PlanetShineLight (); aPsLight.isSun = _aSource.isSun; aPsLight.source = celBody; if (!_aSource.isSun) aPsLight.sunCelestialBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == _aSource.mainSunCelestialBody); // GameObject ScaledPlanetShineLight = (UnityEngine.GameObject)Instantiate (Scatterer.Instance.scaledSpaceSunLight.gameObject); // GameObject LocalPlanetShineLight = (UnityEngine.GameObject)Instantiate (Scatterer.Instance.scaledSpaceSunLight.gameObject); //TODO: fix this if I ever come back to it GameObject ScaledPlanetShineLight = new GameObject(); GameObject LocalPlanetShineLight = new GameObject(); ScaledPlanetShineLight.GetComponent ().type = LightType.Point; if (!_aSource.isSun) ScaledPlanetShineLight.GetComponent ().cookie = planetShineCookieCubeMap; //ScaledPlanetShineLight.GetComponent().range=1E9f; ScaledPlanetShineLight.GetComponent ().range = _aSource.scaledRange; ScaledPlanetShineLight.GetComponent ().color = new Color (_aSource.color.x, _aSource.color.y, _aSource.color.z); ScaledPlanetShineLight.name = celBody.name + "PlanetShineLight(ScaledSpace)"; LocalPlanetShineLight.GetComponent ().type = LightType.Point; if (!_aSource.isSun) LocalPlanetShineLight.GetComponent ().cookie = planetShineCookieCubeMap; //LocalPlanetShineLight.GetComponent().range=1E9f; LocalPlanetShineLight.GetComponent ().range = _aSource.scaledRange * ScaledSpace.ScaleFactor; LocalPlanetShineLight.GetComponent ().color = new Color (_aSource.color.x, _aSource.color.y, _aSource.color.z); LocalPlanetShineLight.GetComponent ().cullingMask = 557591; LocalPlanetShineLight.GetComponent ().shadows = LightShadows.Soft; LocalPlanetShineLight.GetComponent ().shadowCustomResolution = 2048; LocalPlanetShineLight.name = celBody.name + "PlanetShineLight(LocalSpace)"; aPsLight.scaledLight = ScaledPlanetShineLight; aPsLight.localLight = LocalPlanetShineLight; celestialLightSources.Add (aPsLight); Utils.LogDebug ("Added celestialLightSource " + aPsLight.source.name); } } } public void UpdatePlanetshine () { foreach (PlanetShineLight _aLight in celestialLightSources) { _aLight.updateLight(); } } public void Cleanup() { foreach (PlanetShineLight _aLight in celestialLightSources) { _aLight.OnDestroy(); UnityEngine.Object.Destroy(_aLight); } } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Godrays/LegacyGodraysRenderer.cs ================================================ using UnityEngine; using UnityEngine.Rendering; using System.Collections.Generic; using System; namespace Scatterer { public class LegacyGodraysRenderer : MonoBehaviour { SkyNode parentSkyNode; Camera targetCamera; Light targetLight; ComputeBuffer inverseShadowMatricesBuffer; ComputeShader inverseShadowMatricesComputeShader; CommandBuffer shadowVolumeCB; Material volumeDepthMaterial; GameObject volumeDepthGO; public RenderTexture volumeDepthTexture; // GameObject cloudShadowGO; // MeshRenderer cloudShadowMR; // Dictionary> shadowRenderCommandBuffers = new Dictionary> (); // List> cloudsShadowsMaterials = new List>(); // RenderTexture cloudShadowMap; // CommandBuffer clearShadowMapCB; bool commandBufferAdded = false; public LegacyGodraysRenderer () { } public bool Init(Light inputLight, SkyNode inputParentSkyNode) { if (!SystemInfo.supportsComputeShaders) { Utils.LogError("Compute shaders not supported, godrays can't be added"); return false; } if (ShaderReplacer.Instance.LoadedComputeShaders.ContainsKey ("ComputeInverseShadowMatrices")) { inverseShadowMatricesComputeShader = ShaderReplacer.Instance.LoadedComputeShaders ["ComputeInverseShadowMatrices"]; } else { Utils.LogError("Godrays inverse shadow matrices compute shader can't be found, godrays can't be added"); return false; } if (ShaderReplacer.Instance.LoadedShaders.ContainsKey ("Scatterer/VolumeDepth")) { volumeDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders ["Scatterer/VolumeDepth"]); } else { Utils.LogError("Godrays depth shader can't be found, godrays can't be added"); return false; } if (!inputLight) { Utils.LogError("Godrays light is null, godrays can't be added"); return false; } targetLight = inputLight; parentSkyNode = inputParentSkyNode; Utils.EnableOrDisableShaderKeywords (volumeDepthMaterial, "OCEAN_INTERSECT_ANALYTICAL", "OCEAN_INTERSECT_OFF", parentSkyNode.prolandManager.hasOcean && Scatterer.Instance.mainSettings.useOceanShaders); volumeDepthMaterial.SetFloat ("Rt", parentSkyNode.Rt); volumeDepthMaterial.SetFloat ("Rg", parentSkyNode.Rg); Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "CLOUDSMAP_ON", "CLOUDSMAP_OFF", false); //Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "DOWNSCALE_DEPTH_ON", "DOWNSCALE_DEPTH_OFF", Scatterer.Instance.mainSettings.quarterResScattering); Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "DOWNSCALE_DEPTH_ON", "DOWNSCALE_DEPTH_OFF", false); volumeDepthGO = new GameObject ("GodraysVolumeDepth "+inputParentSkyNode.prolandManager.parentCelestialBody.name); volumeDepthMaterial.renderQueue = 2999; //for debugging only volumeDepthGO.layer = 15; MeshFilter _mf = volumeDepthGO.AddComponent (); _mf.mesh.Clear (); _mf.mesh = MeshFactory.MakePlane32BitIndexFormat (512, 512, MeshFactory.PLANE.XY, false, false); //fixed with 32bit indices //_mf.mesh = MeshFactory.MakePlane16BitIndexFormat (256, 256, MeshFactory.PLANE.XY, false, false); //Definitely need to subdivide more here and in the tesselation check edge length and culling _mf.mesh.bounds = new Bounds (Vector4.zero, new Vector3 (1e18f, 1e18f, 1e18f)); //apparently mathf.Infinity is bad, remember this MeshRenderer _mr = volumeDepthGO.AddComponent (); _mr.material = volumeDepthMaterial; _mr.receiveShadows = false; _mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; _mr.enabled = false; //disabled quarter res because I haven't fixed it for the sky and probably the perf hit from finding nearest depth in sky shader isn't worth it // if (Scatterer.Instance.mainSettings.quarterResScattering) // volumeDepthTexture = new RenderTexture (Screen.width / 2, Screen.height / 2, 0, RenderTextureFormat.RHalf); // else volumeDepthTexture = new RenderTexture (Screen.width, Screen.height, 0, RenderTextureFormat.RHalf); //seems to work if we divide the contents by 100, to keep under half's 65000 limit volumeDepthTexture.useMipMap = false; volumeDepthTexture.antiAliasing = 1; volumeDepthTexture.filterMode = FilterMode.Point; volumeDepthTexture.Create (); // if (Scatterer.Instance.mainSettings.integrateEVECloudsGodrays) // { // InitCloudShadowCommandBuffers (); // } //world to shadow matrices aren't exposed in the C# api so we can't compute the shadow to world matrices from them //since they are exposed in shaders we use a compute shader to do it inverseShadowMatricesBuffer = new ComputeBuffer (4, 16 * sizeof(float)); shadowVolumeCB = new CommandBuffer(); shadowVolumeCB.name = "Scatterer legacy godrays CommandBuffer"; shadowVolumeCB.SetComputeBufferParam (inverseShadowMatricesComputeShader, 0, "resultBuffer", inverseShadowMatricesBuffer); shadowVolumeCB.DispatchCompute(inverseShadowMatricesComputeShader, 0, 4, 1, 1); shadowVolumeCB.SetRenderTarget(volumeDepthTexture); //shadowVolumeCB.ClearRenderTarget(false, true, Color.black, 1f); //do this after rendering shadowVolumeCB.SetShadowSamplingMode (ShadowMapCopy.RenderTexture, ShadowSamplingMode.RawDepth); shadowVolumeCB.DrawRenderer (_mr, volumeDepthMaterial); targetCamera = gameObject.GetComponent (); return true; } // void InitCloudShadowCommandBuffers () // { // if (Scatterer.Instance.eveReflectionHandler.EVEClouds2dDictionary.ContainsKey (parentSkyNode.prolandManager.parentCelestialBody.name)) // { // foreach (EVEClouds2d clouds2d in Scatterer.Instance.eveReflectionHandler.EVEClouds2dDictionary [parentSkyNode.prolandManager.parentCelestialBody.name]) // { // if (clouds2d.CloudShadowMaterial != null) // { // Material cloudShadowDepthMaterial = new Material (ShaderReplacer.Instance.LoadedShaders ["Scatterer-EVE/CloudShadowMap"]); // cloudShadowDepthMaterial.CopyKeywordsFrom (clouds2d.CloudShadowMaterial); // if (cloudShadowGO == null) // { // cloudShadowGO = GameObject.CreatePrimitive (PrimitiveType.Sphere); // GameObject.Destroy (cloudShadowGO.GetComponent ()); // MeshFilter cloudShadowMF = cloudShadowGO.GetComponent (); // cloudShadowMF.mesh.Clear (); // cloudShadowMF.mesh = IcoSphere.CreateIcoSphereMesh (); // cloudShadowMR = cloudShadowGO.GetComponent (); // cloudShadowGO.transform.parent = parentSkyNode.prolandManager.parentCelestialBody.transform; // cloudShadowMR.receiveShadows = false; // cloudShadowMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; // cloudShadowMR.enabled = false; // // cloudShadowMap = new RenderTexture (2048, 2048, 0, RenderTextureFormat.RHalf); //replace size after // cloudShadowMap.useMipMap = false; // cloudShadowMap.antiAliasing = 1; // cloudShadowMap.filterMode = FilterMode.Point; // cloudShadowMap.Create (); // // clearShadowMapCB = new CommandBuffer(); // clearShadowMapCB.SetRenderTarget(cloudShadowMap); // clearShadowMapCB.ClearRenderTarget(false,true,Color.black); // // shadowRenderCommandBuffers[ShadowMapPass.DirectionalCascade0] = new List(); // shadowRenderCommandBuffers[ShadowMapPass.DirectionalCascade0].Add(clearShadowMapCB); // // Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "CLOUDSMAP_ON", "CLOUDSMAP_OFF", true); // volumeDepthMaterial.SetTexture("cloudShadowMap", cloudShadowMap); // } // RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade0, 0f, 0f, 0.5f, 0.5f); // RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade1, 0.5f, 0f, 0.5f, 0.5f); // RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade2, 0f, 0.5f, 0.5f, 0.5f); // RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade3, 0.5f, 0.5f, 0.5f, 0.5f); // // cloudsShadowsMaterials.Add (new Tuple (clouds2d, cloudShadowDepthMaterial)); // } // } // } // } // void RenderObjectInCustomCascade(Light targetLight, RenderTexture rt, MeshRenderer mr, Material mat , ShadowMapPass passMask, float startX, float startY, float width, float height) // { // CommandBuffer cloudShadowDepthCB = new CommandBuffer(); // Rect cascadeRect = new Rect ((int)(startX * rt.width), (int)(startY * rt.height), (int)(width * rt.width), (int)(height * rt.height)); // // cloudShadowDepthCB.SetRenderTarget(rt); // cloudShadowDepthCB.EnableScissorRect(cascadeRect); // cloudShadowDepthCB.SetViewport(cascadeRect); // cloudShadowDepthCB.DrawRenderer(mr, mat); // cloudShadowDepthCB.DisableScissorRect(); // // if (shadowRenderCommandBuffers.ContainsKey (passMask)) // { // shadowRenderCommandBuffers[passMask].Add(cloudShadowDepthCB); // } // else // { // shadowRenderCommandBuffers[passMask] = new List(); // shadowRenderCommandBuffers[passMask].Add(cloudShadowDepthCB); // } // } public void EnableRenderingForFrame() { if (!commandBufferAdded) { ShadowMapCopier.RequestShadowMapCopy(targetLight); targetCamera.AddCommandBuffer (CameraEvent.BeforeForwardOpaque, shadowVolumeCB); // foreach (ShadowMapPass pass in shadowRenderCommandBuffers.Keys) // { // foreach (CommandBuffer cb in shadowRenderCommandBuffers[pass]) // { // targetLight.AddCommandBuffer (LightEvent.AfterShadowMapPass, cb, pass); // } // } commandBufferAdded = true; } } public void RenderingDone() { if (commandBufferAdded && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left) { targetCamera.RemoveCommandBuffer (CameraEvent.BeforeForwardOpaque, shadowVolumeCB); // foreach (ShadowMapPass pass in shadowRenderCommandBuffers.Keys) { // foreach (CommandBuffer cb in shadowRenderCommandBuffers[pass]) { // targetLight.RemoveCommandBuffer (LightEvent.AfterShadowMapPass, cb); // } // } RenderTexture rt=RenderTexture.active; RenderTexture.active= volumeDepthTexture; GL.Clear(false,true,Color.black, 1f); RenderTexture.active=rt; commandBufferAdded = false; } } void OnPreCull() { if (parentSkyNode && !parentSkyNode.inScaledSpace) { EnableRenderingForFrame(); volumeDepthMaterial.SetMatrix(ShaderProperties.CameraToWorld_PROPERTY, targetCamera.cameraToWorldMatrix); volumeDepthMaterial.SetTexture(ShaderProperties._ShadowMapTextureCopyScatterer_PROPERTY, ShadowMapCopy.RenderTexture); volumeDepthMaterial.SetBuffer("inverseShadowMatricesBuffer", inverseShadowMatricesBuffer); //Calculate light's bounding Box englobing camera's frustum up to the shadows distance //The idea is to create a "projector" from the light's PoV, which is essentially a bounding box cover the whole range from near clip plance to the shadows, so we can project into the scene Vector3 lightDirForward = targetLight.transform.forward.normalized; Vector3 lightDirRight = targetLight.transform.right.normalized; Vector3 lightDirUp = targetLight.transform.up.normalized; Vector3[] frustumCornersNear = new Vector3[4]; Vector3[] frustumCornersFar = new Vector3[4]; //the corners appear to be in camera Space even though the documentation says in world Space targetCamera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), targetCamera.nearClipPlane, Camera.MonoOrStereoscopicEye.Mono, frustumCornersNear); targetCamera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), QualitySettings.shadowDistance, Camera.MonoOrStereoscopicEye.Mono, frustumCornersFar); //Kopernicus lights have the same position as their suns, so they are impossibly far, replace their position with something closer to get a useable matrix Matrix4x4 worldToLocalMatrix = parentSkyNode.prolandManager.mainSunLight.transform.worldToLocalMatrix; worldToLocalMatrix.m03 = Scatterer.Instance.nearCamera.transform.position.x; worldToLocalMatrix.m13 = Scatterer.Instance.nearCamera.transform.position.y; worldToLocalMatrix.m23 = Scatterer.Instance.nearCamera.transform.position.z; //now, calculate the corners positions in light Space List frustumCornersInLightSpace = new List(); foreach(Vector3 corner in frustumCornersNear) { frustumCornersInLightSpace.Add(worldToLocalMatrix.MultiplyPoint(targetCamera.transform.localToWorldMatrix.MultiplyPoint(corner))); } foreach(Vector3 corner in frustumCornersFar) { frustumCornersInLightSpace.Add(worldToLocalMatrix.MultiplyPoint(targetCamera.transform.localToWorldMatrix.MultiplyPoint(corner))); } Bounds bounds = GeometryUtility.CalculateBounds(frustumCornersInLightSpace.ToArray(), Matrix4x4.identity); //Create an orthogonal projection matrix from the bounding box Matrix4x4 shadowProjectionMatrix = Matrix4x4.Ortho( bounds.center.x-bounds.extents.x, bounds.center.x+bounds.extents.x, bounds.center.y-bounds.extents.y, bounds.center.y+bounds.extents.y, bounds.center.z-bounds.extents.z, bounds.center.z+bounds.extents.z); shadowProjectionMatrix = GL.GetGPUProjectionMatrix(shadowProjectionMatrix, false); //Transformation from world into our "shadow space" matrix Matrix4x4 VP = shadowProjectionMatrix * worldToLocalMatrix; //And inverse transformation from "shadow space" into world used to create our mesh Matrix4x4 lightToWorld = VP.inverse; volumeDepthMaterial.SetMatrix(ShaderProperties.lightToWorld_PROPERTY, lightToWorld); volumeDepthMaterial.SetVector(ShaderProperties.lightDirection_PROPERTY, targetLight.transform.forward); volumeDepthMaterial.SetVector (ShaderProperties._planetPos_PROPERTY, parentSkyNode.parentLocalTransform.position); // foreach(Tuple tuple in cloudsShadowsMaterials) // { // tuple.Item2.CopyPropertiesFromMaterial(tuple.Item1.CloudShadowMaterial); // tuple.Item2.SetVector(ShaderProperties.lightDirection_PROPERTY, targetLight.transform.forward); // tuple.Item2.SetFloat(ShaderProperties._godrayCloudThreshold_PROPERTY, parentSkyNode.godrayCloudAlphaThreshold); // } } } public void OnPostRender() { if (parentSkyNode) { RenderingDone (); } } public void OnDestroy() { RenderingDone (); if (inverseShadowMatricesBuffer != null) { inverseShadowMatricesBuffer.Dispose(); } if (volumeDepthTexture) { volumeDepthTexture.Release(); } if (volumeDepthGO) { DestroyImmediate(volumeDepthGO); } // if (cloudShadowGO) // { // DestroyImmediate(cloudShadowGO); // } } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Preprocessing/AtmoPreprocessor.cs ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. * * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. * Modified and ported to Unity by Justin Hawkins 2014 * Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2022 * */ using UnityEngine; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Collections; using System.Diagnostics; namespace Scatterer { [KSPAddon(KSPAddon.Startup.Instantly, true)] public class AtmoPreprocessor : MonoBehaviour { private static AtmoPreprocessor instance; public void Awake() { if (instance == null) { instance = this; instance.InitMaterials(); Utils.LogDebug("AtmoPreprocessor instance created"); } else { throw new UnityException("Attempted double instance!"); } } public static AtmoPreprocessor Instance { get { return instance; } } public void Start() { DontDestroyOnLoad(this); } private static bool atmoGenerationRunning = false; public static Vector4 ScatteringLutDimensionsDefault { get => Scatterer.Instance.mainSettings.useLowResolutionAtmosphere ? scatteringLutDimensionsPreview : scatteringLutDimensionsDefault; } const int READ = 0; const int WRITE = 1; float Rg = 60000.0f; float Rt = 71500.603f; //Dimensions of the tables const int TRANSMITTANCE_W = 512; const int TRANSMITTANCE_H = 128; const int SKY_W = 64; const int SKY_H = 16; private static Vector4 scatteringLutDimensionsDefault = new Vector4(32f, 128f, 32f, 16f); //the one from yusov, double the current one so should be 16 megs in half precision public static Vector4 scatteringLutDimensionsPreview = new Vector4(16f, 64f, 16f, 2f); //fast preview version, 32x smaller private static int xTilesDefault = 32, yTilesDefault = 64; private static int xTilesPreview = 32, yTilesPreview = 16; Vector4 scatteringLutDimensions = ScatteringLutDimensionsDefault; int xTiles = xTilesDefault, yTiles = yTilesDefault; float AVERAGE_GROUND_REFLECTANCE = 0.1f; Vector4 BETA_R = new Vector4(5.8e-3f, 1.35e-2f, 3.31e-2f, 0.0f); Vector4 BETA_MSca = new Vector4(4e-3f, 4e-3f, 4e-3f, 0.0f); float MIE_G = 0.8f; float HR = 8000.0f; float HM = 1200.0f; Vector3 ozoneAbsorption = new Vector3(0.0000003426f, 0.0000008298f, 0.000000036f); float ozoneHeight = 25000f; float ozoneFalloff = 15000f; RenderTexture ozoneTransmittanceRT; RenderTexture deltaET, deltaSRT, deltaSMT, deltaJT; public RenderTexture[] irradianceT, inscatterT; Material transmittanceMaterial, ozoneTransmittanceMaterial, irradianceNMaterial, irradiance1Material, inscatter1Material, inscatterNMaterial, inscatterSMaterial, copyInscatter1Material, copyInscatterNMaterial, copyIrradianceMaterial, atlasMaterial; int scatteringOrders = 4; //min is 2 unless you skip that step bool multipleScattering = true; bool useOzone = false; // Process in chunks and return if we spend more time than this // Otherwise windows thinks the GPU crashed on slower hardware // https://en.wikipedia.org/wiki/Timeout_Detection_and_Recovery long generationMsThreshold = 1000; private void InitMaterials() { transmittanceMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Transmittance")]); ozoneTransmittanceMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/OzoneTransmittance")]); irradianceNMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/IrradianceN")]); irradiance1Material = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Irradiance1")]); inscatter1Material = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Inscatter1")]); inscatterNMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/InscatterN")]); inscatterSMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/InscatterS")]); copyInscatter1Material = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/CopyInscatter1")]); copyInscatterNMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/CopyInscatterN")]); copyIrradianceMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/CopyIrradiance")]); atlasMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Atlas")]); } public static float CalculateRt(float inRg, float inHR, float inHM, Vector3 in_betaR, Vector3 in_BETA_MSca, bool useOzone, float ozoneHeight, float ozoneFalloff) { float RtHR = - 1000f * inHR * Mathf.Log(0.0000001f / in_betaR.magnitude); float RtHM = - 1000f * inHM * Mathf.Log(0.0000001f / in_BETA_MSca.magnitude); float maxHeight = Mathf.Max(RtHR, RtHM); if (useOzone) maxHeight = Mathf.Max(maxHeight, 1000f * (ozoneHeight + ozoneFalloff)); return inRg + maxHeight; } public static void DeleteCache() { string cachePath = Utils.GameDataPath + "/ScattererAtmosphereCache/PluginData"; Directory.Delete(cachePath, true); } [StructLayout(LayoutKind.Sequential)] struct AtmoHashData { public float Rg; public float Rt; public float AVERAGE_GROUND_REFLECTANCE; public Vector4 BETA_R; public Vector4 BETA_MSca; public Vector4 ScatteringLutDimensions; public float MIE_G; public float HR; public float HM; public Vector3 ozoneAbsorption; public float ozoneHeight; public float ozoneFalloff; public bool useOzone; public bool useMultipleScattering; public AtmoHashData(float rg, float rt, float averageGroundReflectance, Vector4 betaR, Vector4 betaMSca, Vector4 scatteringLutDimensions, float mieG, float hr,float hm,Vector3 ozoneAbsorption,float ozoneHeight,float ozoneFalloff,bool useOzone,bool useMultipleScattering) { Rg = rg; Rt = rt; AVERAGE_GROUND_REFLECTANCE = averageGroundReflectance; BETA_R = betaR; BETA_MSca = betaMSca; ScatteringLutDimensions = scatteringLutDimensions; MIE_G = mieG; HR = hr; HM = hm; this.ozoneAbsorption = ozoneAbsorption; this.ozoneHeight = ozoneHeight; this.ozoneFalloff = ozoneFalloff; this.useOzone = useOzone; this.useMultipleScattering = useMultipleScattering; } } public static string GetAtmoHash(float inRG, float inRT, Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inAverageGroundRreflectance, bool inMultiple, Vector4 inPRECOMPUTED_SCTR_LUT_DIM, bool inUseOzone, Vector4 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff) { AtmoHashData atmoHashData = new AtmoHashData( inRG, inRT, inAverageGroundRreflectance, inBETA_R, inBETA_MSca, inPRECOMPUTED_SCTR_LUT_DIM, inMIE_G, inHR, inHM, inUseOzone ? inOzoneAbsorption : Vector4.zero, inUseOzone ? inOzoneHeight : 0f, inUseOzone ? inOzoneFalloff : 0f, inUseOzone, inMultiple ); Hash128 result = new Hash128(); HashUtilities.ComputeHash128(ref atmoHashData, ref result); return result.ToString(); } public static void Generate(float inRG, float inRT, Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inGRref, bool inMultiple, Vector4 inScatteringLutDimensions, bool previewMode, string assetPath, bool inUseOzone, Vector4 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff, string bodyName) { if (!atmoGenerationRunning) { Utils.LogInfo("Generating new atmosphere for "+bodyName); instance.StartCoroutine(instance.GenerateAndSaveAtmoCoroutine(inRG, inRT, inBETA_R, inBETA_MSca, inMIE_G, inHR, inHM, inGRref, inMultiple, inScatteringLutDimensions, previewMode, assetPath, inUseOzone, inOzoneAbsorption, inOzoneHeight, inOzoneFalloff)); } } IEnumerator GenerateAndSaveAtmoCoroutine(float inRG, float inRT, Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inGRref, bool inMultiple, Vector4 inScatteringLutDimensions, bool previewMode, string assetPath, bool inUseOzone, Vector4 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff) { atmoGenerationRunning = true; //Rescale to a fixed radius which we know never causes issues float referenceRadius = 1000000f; float scaleFactor = referenceRadius / inRG; Rg = referenceRadius; Rt = inRT * scaleFactor; HR = inHR * 1000f * scaleFactor; HM = inHM * 1000f * scaleFactor; BETA_R = inBETA_R * 0.001f / scaleFactor; BETA_MSca = inBETA_MSca * 0.001f / scaleFactor; MIE_G = inMIE_G; if (inMultiple) MIE_G = Mathf.Min (MIE_G, 0.86f); //values of mie_G > 0.86 seem to break multiple scattering for some weird reason AVERAGE_GROUND_REFLECTANCE = inGRref; multipleScattering = inMultiple; scatteringLutDimensions = inScatteringLutDimensions; useOzone = inUseOzone; ozoneAbsorption = inOzoneAbsorption * 0.001f / scaleFactor; if (!useOzone) ozoneAbsorption = Vector4.zero; ozoneHeight = inOzoneHeight * 1000f * scaleFactor; ozoneFalloff = inOzoneFalloff * 1000f* scaleFactor; if (previewMode || Scatterer.Instance.mainSettings.useLowResolutionAtmosphere) { xTiles = xTilesPreview; yTiles = yTilesPreview; } else { xTiles = xTilesDefault; yTiles = yTilesDefault; } irradianceT = new RenderTexture[2]; inscatterT = new RenderTexture[2]; ozoneTransmittanceRT = new RenderTexture(TRANSMITTANCE_W, TRANSMITTANCE_H, 0, RenderTextureFormat.ARGBFloat); ozoneTransmittanceRT.wrapMode = TextureWrapMode.Clamp; ozoneTransmittanceRT.filterMode = FilterMode.Bilinear; ozoneTransmittanceRT.Create(); irradianceT[0] = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat); irradianceT[0].wrapMode = TextureWrapMode.Clamp; irradianceT[0].filterMode = FilterMode.Bilinear; irradianceT[0].Create(); irradianceT[1] = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat); irradianceT[1].wrapMode = TextureWrapMode.Clamp; irradianceT[1].filterMode = FilterMode.Bilinear; irradianceT[1].Create(); deltaET = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat); deltaET.Create(); inscatterT[0] = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat); inscatterT[0].wrapMode = TextureWrapMode.Clamp; inscatterT[0].filterMode = FilterMode.Bilinear; inscatterT[0].Create(); inscatterT[1] = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat); inscatterT[1].wrapMode = TextureWrapMode.Clamp; inscatterT[1].filterMode = FilterMode.Bilinear; inscatterT[1].Create(); deltaSRT = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat); deltaSRT.wrapMode = TextureWrapMode.Clamp; deltaSRT.filterMode = FilterMode.Bilinear; deltaSRT.Create(); deltaSMT = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat); deltaSMT.wrapMode = TextureWrapMode.Clamp; deltaSMT.filterMode = FilterMode.Bilinear; deltaSMT.Create(); deltaJT = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat); deltaJT.wrapMode = TextureWrapMode.Clamp; deltaJT.filterMode = FilterMode.Bilinear; deltaJT.Create(); SetParameters(ozoneTransmittanceMaterial); SetParameters(transmittanceMaterial); SetParameters(irradianceNMaterial); SetParameters(irradiance1Material); SetParameters(inscatter1Material); SetParameters(inscatterNMaterial); SetParameters(inscatterSMaterial); SetParameters(copyInscatter1Material); SetParameters(copyInscatterNMaterial); SetParameters(copyIrradianceMaterial); RTUtility.ClearColor(irradianceT); yield return Preprocess(assetPath); ReleaseTextures(); atmoGenerationRunning = false; } void SetParameters(Material mat) { mat.SetFloat("Rg", Rg); mat.SetFloat("Rt", Rt); mat.SetInt("TRANSMITTANCE_W", TRANSMITTANCE_W); mat.SetInt("TRANSMITTANCE_H", TRANSMITTANCE_H); mat.SetInt("SKY_W", SKY_W); mat.SetInt("SKY_H", SKY_H); mat.SetFloat("AVERAGE_GROUND_REFLECTANCE", AVERAGE_GROUND_REFLECTANCE); mat.SetFloat("HR", HR); mat.SetFloat("HM", HM); mat.SetVector("betaR", BETA_R); mat.SetVector("betaMSca", BETA_MSca); mat.SetVector("betaMEx", BETA_MSca / 0.9f); mat.SetFloat("mieG", Mathf.Clamp(MIE_G, 0.0f, 0.99f)); mat.SetFloat ("Sun_intensity", 10f); mat.SetVector("PRECOMPUTED_SCTR_LUT_DIM", scatteringLutDimensions); mat.SetVector ("tiles", new Vector2 (xTiles, yTiles)); mat.SetFloat("ozoneHeight", ozoneHeight); mat.SetFloat("ozoneFalloff", ozoneFalloff); mat.SetVector("ozoneAbsorption", new Vector4(ozoneAbsorption.x, ozoneAbsorption.y, ozoneAbsorption.z, 0.0f)); } IEnumerator Preprocess(string assetPath) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); ComputeTransmittance(); ComputeIrradiance(); yield return ComputeInscatter1(stopwatch); CopyIrradiance(); yield return CopyInscatter1(stopwatch); for (int scatteringOrder = 2; scatteringOrder <= (multipleScattering ? scatteringOrders : 2); scatteringOrder++) { yield return ComputeInscatterS(2, stopwatch); // is this a mistake? should it be scatteringOrder instead of 2? ComputeIrradianceN(2); yield return ComputeInscatterN(stopwatch); CopyIrradianceK1(); if (multipleScattering) { yield return CopyInscatterN(stopwatch); } } if (!Directory.Exists(assetPath)) Directory.CreateDirectory(assetPath); var atmosphereAtlas = PackTextures(new RenderTexture[] { inscatterT[READ], irradianceT[READ], ozoneTransmittanceRT }); SaveAsHalf(atmosphereAtlas, assetPath + "/atlas"); atmosphereAtlas.Release(); Utils.LogInfo("Atmo generation successful"); } private RenderTexture PackTextures(RenderTexture[] textures) { // Just do the simplest packing possible, top-left to bottom-left int width = textures.Max(texture => texture.width); int height = textures.Sum(texture => texture.height); RenderTexture rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, 0); rt.wrapMode = TextureWrapMode.Clamp; rt.Create(); atlasMaterial.SetInt("targetWidth", width); atlasMaterial.SetInt("targetHeight", height); int currentHeight = 0; for (int i = 0; i < textures.Length; i++) { var texture = textures[i]; atlasMaterial.SetTexture("inputTexture", texture); atlasMaterial.SetInt("width", texture.width); atlasMaterial.SetInt("height", texture.height); atlasMaterial.SetInt("horizontalOffset", 0); atlasMaterial.SetInt("verticalOffset", currentHeight); Graphics.Blit(null, rt, atlasMaterial); currentHeight += texture.height; } return rt; } public static List GetPackedTexturesScaleAndOffsets(List dimensions, Vector2 atlasDimensions) { var result = new List(); float currentHeight = 0; foreach(Vector2 dimension in dimensions) { Vector2 currentScale = new Vector2(dimension.x / atlasDimensions.x, dimension.y / atlasDimensions.y); Vector2 currentOffset = new Vector2(0f, currentHeight / atlasDimensions.y); result.Add(new Vector4(currentScale.x, currentScale.y, currentOffset.x, currentOffset.y)); currentHeight += dimension.y; } return result; } IEnumerator CopyInscatterN(Stopwatch stopwatch) { // adds deltaS into inscatter texture S(line 11 in algorithm 4.1) yield return ProcessInTiles(stopwatch, (int i, int j) => { copyInscatterNMaterial.SetVector("currentTile", new Vector2(i, j)); copyInscatterNMaterial.SetTexture("deltaSRead", deltaSRT); copyInscatterNMaterial.SetTexture("inscatterRead", inscatterT[READ]); Graphics.Blit(null, inscatterT[WRITE], copyInscatterNMaterial, 0); }); RTUtility.Swap(inscatterT); } private void CopyIrradianceK1() { // adds deltaE into irradiance texture E (line 10 in algorithm 4.1) copyIrradianceMaterial.SetFloat("k", 1.0f); copyIrradianceMaterial.SetTexture("deltaERead", deltaET); copyIrradianceMaterial.SetTexture("irradianceRead", irradianceT[READ]); Graphics.Blit(null, irradianceT[WRITE], copyIrradianceMaterial); RTUtility.Swap(irradianceT); } IEnumerator ComputeInscatterN(Stopwatch stopwatch) { // computes deltaS (line 9 in algorithm 4.1) yield return ProcessInTiles(stopwatch, (int i, int j) => { inscatterNMaterial.SetVector("currentTile", new Vector2(i, j)); inscatterNMaterial.SetTexture("transmittanceRead", ozoneTransmittanceRT); inscatterNMaterial.SetTexture("deltaJRead", deltaJT); inscatterNMaterial.SetTexture("deltaJReadSampler", deltaJT); Graphics.Blit(null, deltaSRT, inscatterNMaterial, 0); }); } IEnumerator ComputeInscatterS(int scatteringOrder, Stopwatch stopwatch) { yield return ProcessInTiles(stopwatch, (int i, int j) => { inscatterSMaterial.SetVector("currentTile", new Vector2(i, j)); inscatterSMaterial.SetInt("first", (scatteringOrder == 2) ? 1 : 0); inscatterSMaterial.SetTexture("transmittanceRead", ozoneTransmittanceRT); inscatterSMaterial.SetTexture("deltaERead", deltaET); inscatterSMaterial.SetTexture("deltaSRRead", deltaSRT); inscatterSMaterial.SetTexture("deltaSMRead", deltaSMT); inscatterSMaterial.SetTexture("deltaSRReadSampler", deltaSRT); inscatterSMaterial.SetTexture("deltaSMReadSampler", deltaSMT); Graphics.Blit(null, deltaJT, inscatterSMaterial, 0); }); } private void ComputeIrradianceN(int scatteringOrder) { // computes deltaE (line 8 in algorithm 4.1) irradianceNMaterial.SetInt("first", (scatteringOrder == 2) ? 1 : 0); irradianceNMaterial.SetTexture("deltaSRRead", deltaSRT); irradianceNMaterial.SetTexture("deltaSMRead", deltaSMT); irradianceNMaterial.SetTexture("deltaSRReadSampler", deltaSRT); irradianceNMaterial.SetTexture("deltaSMReadSampler", deltaSMT); Graphics.Blit(null, deltaET, irradianceNMaterial); } IEnumerator CopyInscatter1(Stopwatch stopwatch) { // copies deltaS into inscatter texture S (line 5 in algorithm 4.1) yield return ProcessInTiles(stopwatch, (int i, int j) => { copyInscatter1Material.SetVector("currentTile", new Vector2(i, j)); copyInscatter1Material.SetTexture("deltaSRRead", deltaSRT); copyInscatter1Material.SetTexture("deltaSMRead", deltaSMT); Graphics.Blit(null, inscatterT[WRITE], copyInscatter1Material, 0); }); RTUtility.Swap(inscatterT); } private void CopyIrradiance() { copyIrradianceMaterial.SetFloat("k", 0.0f); copyIrradianceMaterial.SetTexture("deltaERead", deltaET); copyIrradianceMaterial.SetTexture("irradianceRead", irradianceT[READ]); Graphics.Blit(null, irradianceT[WRITE], copyIrradianceMaterial, 0); RTUtility.Swap(irradianceT); } IEnumerator ComputeInscatter1(Stopwatch stopwatch) { // computes single scattering texture deltaS (line 3 in algorithm 4.1) // Rayleigh and Mie separated in deltaSR + deltaSM inscatter1Material.SetTexture("transmittanceRead", ozoneTransmittanceRT); yield return ProcessInTiles(stopwatch, (int i, int j) => { inscatter1Material.SetVector("currentTile", new Vector2(i, j)); Graphics.Blit(null, deltaSRT, inscatter1Material, 0); // rayleigh pass Graphics.Blit(null, deltaSMT, inscatter1Material, 1); // mie pass }); } private void ComputeIrradiance() { // computes irradiance texture deltaE (line 2 in algorithm 4.1) irradiance1Material.SetTexture("transmittanceRead", ozoneTransmittanceRT); Graphics.Blit(null, deltaET, irradiance1Material); } private void ComputeTransmittance() { Graphics.Blit(null, ozoneTransmittanceRT, ozoneTransmittanceMaterial); } //Process in tiles because older GPUs (series 7xx and integrated hd 3xxx) crash when rendering the full res IEnumerator ProcessInTiles(Stopwatch stopwatch, Action process) { for (int i = 0; i < xTiles; i++) { for (int j = 0; j < yTiles; j++) { process(i, j); } if (stopwatch.ElapsedMilliseconds > generationMsThreshold) { yield return new WaitForFixedUpdate(); stopwatch.Restart(); } } } public void OnDestroy() { ReleaseTextures(); } void ReleaseTextures() { ozoneTransmittanceRT.Release(); irradianceT[0].Release(); irradianceT[1].Release(); inscatterT[0].Release(); inscatterT[1].Release(); deltaET.Release(); deltaSRT.Release(); deltaSMT.Release(); deltaJT.Release(); } void SaveAsHalf(RenderTexture rtex, string fileName) { Texture2D temp = new Texture2D(rtex.width, rtex.height, TextureFormat.RGBAHalf, false, false); RenderTexture.active = rtex; temp.ReadPixels (new Rect (0, 0, rtex.width, rtex.height), 0, 0); temp.Apply (); byte[] byteArray = temp.GetRawTextureData(); System.IO.File.WriteAllBytes(fileName + ".half", byteArray); } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/SkyNode.cs ================================================ using UnityEngine; using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using KSP.IO; namespace Scatterer { public class SkyNode: MonoBehaviour { [Persistent] protected string name; public float Rg; //The radius of the planet public float Rt; //Radius of the atmosphere, calculated automatically from HR and HM and the scattering factors [Persistent] public float atmosphereStartRadiusScale = 1f; [Persistent] public float HR = 8.0f; //Half heights for the atmosphere air density (HR) and particle density (HM), this is the height in km that half the particles are found below [Persistent] public float HM = 1.2f; [Persistent] public Vector3 m_betaR = new Vector3 (5.8e-3f, 1.35e-2f, 3.31e-2f); [Persistent] public Vector3 BETA_MSca = new Vector3 (4e-3f, 4e-3f, 4e-3f); //scatter coefficient for mie [Persistent] public float m_mieG = 0.85f; //Asymmetry factor for the mie phase function, a higher number means more light is scattered in the forward direction [Persistent] public Vector3 ozoneAbsorption = new Vector3(0.0003426f, 0.0008298f, 0.000036f); // From Physically Based Sky, Atmosphere & Cloud Rendering in Frostbite (2016), these look better than other coefficients I found in the literature [Persistent] public float ozoneHeight = 25f; // Ozone density is highest at ozoneHeight(km) and decreases linearly away from that altitude until ozoneFalloff(km), as per Bruneton (2017) [Persistent] public float ozoneFalloff = 15f; // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/ [Persistent] public bool useOzone = false; [Persistent] public float averageGroundReflectance = 0.1f; [Persistent] public bool multipleScattering = true; public bool previewMode = false; public float mainMenuScaleFactor = 1f; [Persistent] public float godrayStrength = 0.8f; [Persistent] public float flattenScaledSpaceMesh = 0f; [Persistent] public float rimBlend = 20f; [Persistent] public float rimpower = 600f; [Persistent] public float specR = 0f; [Persistent] public float specG = 0f; [Persistent] public float specB = 0f; [Persistent] public float shininess = 0f; [Persistent] public float noonSunlightExtinctionStrength = 1f; [Persistent] public float cloudColorMultiplier=3f; [Persistent] public float cloudScatteringMultiplier=0.2f; [Persistent] public float cloudSkyIrradianceMultiplier=0.05f; [Persistent] public float volumetricsColorMultiplier = 1f; [Persistent] public bool EVEIntegration_preserveCloudColors = false; // [Persistent] public float godrayCloudAlphaThreshold = 0.25f; [Persistent] public List < ConfigPoint > configPoints = new List < ConfigPoint > (); [Persistent] public bool adjustScaledTexture = false; [Persistent] public float scaledLandBrightnessAdjust = 1f; [Persistent] public float scaledLandContrastAdjust = 1f; [Persistent] public float scaledLandSaturationAdjust = 1f; [Persistent] public float scaledOceanBrightnessAdjust = 1f; [Persistent] public float scaledOceanContrastAdjust = 1f; [Persistent] public float scaledOceanSaturationAdjust = 1f; //Texture2D m_inscatter, m_irradiance, m_ozoneTransmittance = Texture2D.whiteTexture; Texture2D atmosphereAtlas; // Combine all the lookup tables to save texture slots on Mac Vector2 atlasDimensions; List atlasScaleAndOffsets = new List { Vector4.zero, Vector4.zero, Vector4.zero, Vector4.zero}; //Dimensions of the tables const int TRANSMITTANCE_W = 512; const int TRANSMITTANCE_H = 128; Vector2 transmittanceTableDimensions = new Vector2(TRANSMITTANCE_W, TRANSMITTANCE_H); const int SKY_W = 64; const int SKY_H = 16; Vector4 scatteringLutDimensions = AtmoPreprocessor.ScatteringLutDimensionsDefault; string celestialBodyName; public Transform parentScaledTransform, parentLocalTransform; public ProlandManager prolandManager; public UrlDir.UrlConfig configUrl; public bool isConfigModuleManagerPatch = true; public bool usesCloudIntegration = true; public float altitude; public float percentage; public int currentConfigPoint; public ConfigPoint interpolatedSettings= new ConfigPoint(); public bool inScaledSpace = true, simulateOceanInteraction=false; Vector3 sunPosRelPlanet=Vector3.zero; Matrix4x4 castersMatrix1=Matrix4x4.zero; Matrix4x4 castersMatrix2=Matrix4x4.zero; SkySphereContainer skySphere; GameObject stockSkyGameObject; MeshRenderer stockScaledPlanetMeshRenderer; Mesh originalScaledMesh, tweakedScaledmesh; public ScaledScatteringContainer scaledScatteringContainer; public Material localScatteringMaterial, skyMaterial, scaledScatteringMaterial, sunflareExtinctionMaterial, scaledEclipseMaterial; public GenericLocalAtmosphereContainer localScatteringContainer; public LegacyGodraysRenderer legacyGodraysRenderer; public bool postprocessingEnabled = true; GameObject ringObject; float ringInnerRadius, ringOuterRadius; Texture2D ringTexture; bool hasRingObjectAndShadowActivated = false; bool skyNodeInitiated = false; bool precomputedAtmoLoaded = false; bool atmosphereShadersInitiated = false; public bool useEclipses = false; Texture2D originalPlanetTexture; RenderTexture adjustedPlanetTexture; public void Init () { InitOrRequestPrecomputedAtmo (); skyMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/SkySphere")]); scaledScatteringMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/ScaledPlanetScattering")]); localScatteringMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/DepthBufferScattering")]); skyMaterial.SetOverrideTag ("IgnoreProjector", "True"); scaledScatteringMaterial.SetOverrideTag ("IgnoreProjector", "True"); localScatteringMaterial.SetOverrideTag ("IgnoreProjector", "True"); useEclipses = Scatterer.Instance.mainSettings.useEclipses && (prolandManager.eclipseCasters.Count > 0) && HighLogic.LoadedScene != GameScenes.MAINMENU ; //disable bugged eclipses on main menu Utils.EnableOrDisableShaderKeywords (localScatteringMaterial, "ECLIPSES_ON", "ECLIPSES_OFF", useEclipses); Utils.EnableOrDisableShaderKeywords (localScatteringMaterial, "DISABLE_UNDERWATER_ON", "DISABLE_UNDERWATER_OFF", prolandManager.hasOcean); if (Scatterer.Instance.mainSettings.useLegacyTerrainGodrays && Scatterer.Instance.unifiedCameraMode && prolandManager.parentCelestialBody.pqsController && Scatterer.Instance.mainSettings.terrainShadows && (Scatterer.Instance.mainSettings.unifiedCamShadowResolutionOverride != 0)) { legacyGodraysRenderer = (LegacyGodraysRenderer)Utils.getEarliestLocalCamera().gameObject.AddComponent(typeof(LegacyGodraysRenderer)); if (!legacyGodraysRenderer.Init(prolandManager.mainSunLight, this)) { Component.Destroy(legacyGodraysRenderer); legacyGodraysRenderer = null; } } if (Scatterer.Instance.mainSettings.useRingShadows) { InitKopernicusRings (); } TweakScaledMesh (); if (prolandManager.parentCelestialBody.pqsController) { prolandManager.parentCelestialBody.pqsController.isActive = false; //sometimes the PQS is forgotten as "active" if a ship is loaded directly around another body, this would mess with the mod //this sets it to false, if it's really active it will be set to active automatically. EVE mod seems also to have a fix for this } if ((HighLogic.LoadedScene != GameScenes.MAINMENU) && (HighLogic.LoadedScene != GameScenes.TRACKSTATION)) // &&useLocalScattering { localScatteringContainer = new ScreenSpaceScatteringContainer(localScatteringMaterial, parentLocalTransform, Rt, prolandManager, Scatterer.Instance.mainSettings.quarterResScattering && !legacyGodraysRenderer); } if (Scatterer.Instance.mainSettings.fullLensFlareReplacement) { sunflareExtinctionMaterial = new Material (ShaderReplacer.Instance.LoadedShaders ["Scatterer/sunFlareExtinction"]); InitUniforms(sunflareExtinctionMaterial); if (hasRingObjectAndShadowActivated) { sunflareExtinctionMaterial.SetFloat (ShaderProperties.ringInnerRadius_PROPERTY, ringInnerRadius); sunflareExtinctionMaterial.SetFloat (ShaderProperties.ringOuterRadius_PROPERTY, ringOuterRadius); sunflareExtinctionMaterial.SetVector (ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up); sunflareExtinctionMaterial.SetTexture (ShaderProperties.ringTexture_PROPERTY, ringTexture); } Utils.EnableOrDisableShaderKeywords (sunflareExtinctionMaterial, "DISABLE_UNDERWATER_ON", "DISABLE_UNDERWATER_OFF", prolandManager.hasOcean); } if (useEclipses || hasRingObjectAndShadowActivated) { scaledEclipseMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/ScaledPlanetEclipse")]); scaledEclipseMaterial.renderQueue = 2001; Utils.EnableOrDisableShaderKeywords (scaledEclipseMaterial, "ECLIPSES_ON", "ECLIPSES_OFF", useEclipses); Utils.EnableOrDisableShaderKeywords (scaledEclipseMaterial, "RINGSHADOW_ON", "RINGSHADOW_OFF", hasRingObjectAndShadowActivated); InitUniforms(scaledEclipseMaterial); } stockScaledPlanetMeshRenderer = (MeshRenderer) parentScaledTransform.GetComponent(); skyNodeInitiated = true; Utils.LogDebug("Skynode initiated for "+celestialBodyName); } void InitSkySphere () { float skySphereSize = (1.5f * (Rt - Rg*atmosphereStartRadiusScale) + Rg*atmosphereStartRadiusScale) / ScaledSpace.ScaleFactor; skySphere = new SkySphereContainer (skySphereSize, skyMaterial, parentLocalTransform, parentScaledTransform); if (HighLogic.LoadedScene != GameScenes.MAINMENU) { if (prolandManager.parentCelestialBody.pqsController != null && prolandManager.parentCelestialBody.pqsController.isActive && HighLogic.LoadedScene != GameScenes.TRACKSTATION) { skySphere.SwitchLocalMode (); } else { skySphere.SwitchScaledMode (); } } skyMaterial.renderQueue = 2998; InitUniforms (skyMaterial); } public void InitScaledScattering () { scaledScatteringContainer = new ScaledScatteringContainer (parentScaledTransform.GetComponent ().sharedMesh, scaledScatteringMaterial, parentLocalTransform, parentScaledTransform); if (HighLogic.LoadedScene != GameScenes.MAINMENU) { if (prolandManager.parentCelestialBody.pqsController != null && prolandManager.parentCelestialBody.pqsController.isActive && HighLogic.LoadedScene != GameScenes.TRACKSTATION) { scaledScatteringContainer.SwitchLocalMode (); } else { scaledScatteringContainer.SwitchScaledMode (); } } scaledScatteringMaterial.renderQueue = 2997; InitUniforms (scaledScatteringMaterial); } public void OnPreRender() { UpdateGraphicsUniforms (); if (!MapView.MapIsEnabled && Scatterer.Instance.mainSettings.sunlightExtinction && precomputedAtmoLoaded) { UpdateLightExtinctions (); } } public void UpdateGraphicsUniforms() { if (!inScaledSpace && !MapView.MapIsEnabled && postprocessingEnabled && localScatteringContainer!=null) { UpdatePostProcessMaterialUniforms (localScatteringContainer.material); } if (useEclipses) { UpdateEclipseCasters (); } if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && usesCloudIntegration) { UpdateEVECloudMaterials (); } if (Scatterer.Instance.sunflareManager) { UpdateSunflareExtinctions (); } if (scaledScatteringContainer != null) scaledScatteringContainer.MeshRenderer.enabled = stockScaledPlanetMeshRenderer.enabled; if (localScatteringContainer != null) { localScatteringContainer.SetInScaledSpace (inScaledSpace); localScatteringContainer.UpdateContainer (); } SetUniforms (skyMaterial); SetUniforms (scaledScatteringMaterial); if (sunflareExtinctionMaterial) SetUniforms (sunflareExtinctionMaterial); if (scaledEclipseMaterial) { scaledEclipseMaterial.SetVector (ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToMainSun ()); scaledEclipseMaterial.SetMatrix (ShaderProperties.lightOccluders1_PROPERTY, castersMatrix1); scaledEclipseMaterial.SetMatrix (ShaderProperties.lightOccluders2_PROPERTY, castersMatrix2); scaledEclipseMaterial.SetVector (ShaderProperties.sunPosAndRadius_PROPERTY, new Vector4 (sunPosRelPlanet.x, sunPosRelPlanet.y, sunPosRelPlanet.z, (float)prolandManager.sunCelestialBody.Radius)); } } public void UpdateNode () { if ((prolandManager.parentCelestialBody.pqsController != null) && !(HighLogic.LoadedScene == GameScenes.TRACKSTATION)) { bool previousState = inScaledSpace; inScaledSpace = !prolandManager.parentCelestialBody.pqsController.isActive; //if we go from scaled to local space if (!inScaledSpace && previousState) { SwitchEffectsLocal(); } //if we go from local to scaled if (inScaledSpace && !previousState) { SwitchEffectsScaled(); } //For wave interactions, consider we are in scaledSpace only if we aren't in map view, otherwise we can be in the surface but pqsController is inactive if (!MapView.MapIsEnabled) simulateOceanInteraction = prolandManager.parentCelestialBody.pqsController.isActive; } else { inScaledSpace = true; simulateOceanInteraction = false; } if (skyNodeInitiated) { if (!precomputedAtmoLoaded) { InitOrRequestPrecomputedAtmo(); } else if (!atmosphereShadersInitiated) { InitSkySphere (); InitPostprocessMaterialUniforms (localScatteringMaterial); InitScaledScattering (); try {StartCoroutine(DelayedTweakStockPlanet ());} catch (Exception e){Utils.LogError("Error when starting SkyNode::DelayedTweakStockPlanet coroutine "+e.Message);}; if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && usesCloudIntegration) InitEVEClouds (); InitOceanMaterialUniforms(); atmosphereShadersInitiated = true; } InterpolateVariables (); if (prolandManager.hasOcean && !Scatterer.Instance.mainSettings.useOceanShaders) { skySphere.MeshRenderer.enabled = (altitude>=0f); stockSkyGameObject.SetActive(altitude<0f); //re-enable stock sky meshrenderer, for compatibility with stock underwater effect } } } public void SwitchEffectsScaled() { Utils.LogInfo ("Skynode switch effects to scaled mode: "+prolandManager.parentCelestialBody.name); if (skySphere != null) skySphere.SwitchScaledMode (); if (scaledScatteringContainer != null) scaledScatteringContainer.SwitchScaledMode (); if (localScatteringContainer != null) localScatteringContainer.SetActivated(false); } public void SwitchEffectsLocal() { Utils.LogInfo ("Skynode switch effects to local mode "+prolandManager.parentCelestialBody.name); if (skySphere != null) skySphere.SwitchLocalMode(); if (scaledScatteringContainer != null) scaledScatteringContainer.SwitchLocalMode (); if (localScatteringContainer != null) localScatteringContainer.SetActivated(true); } public void SetUniforms (Material mat) { mat.SetFloat(ShaderProperties._Alpha_Global_PROPERTY, interpolatedSettings.skyAlpha); mat.SetFloat(ShaderProperties._Extinction_Tint_PROPERTY, interpolatedSettings.skyExtinctionTint); mat.SetFloat(ShaderProperties.extinctionTint_PROPERTY, interpolatedSettings.extinctionTint); //extinctionTint for scaled+local mat.SetFloat(ShaderProperties.extinctionThickness_PROPERTY, interpolatedSettings.extinctionThickness); mat.SetFloat(ShaderProperties.Rg_PROPERTY, Rg * atmosphereStartRadiusScale); mat.SetFloat(ShaderProperties.Rt_PROPERTY, Rt); mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f)); mat.SetVector(ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToMainSun()); mat.SetFloat(ShaderProperties._SkyExposure_PROPERTY, interpolatedSettings.skyExposure); mat.SetFloat(ShaderProperties._ScatteringExposure_PROPERTY, interpolatedSettings.scatteringExposure); if ((prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine) { mat.SetMatrix(ShaderProperties.planetShineSources_PROPERTY, prolandManager.planetShineSourcesMatrix); mat.SetMatrix(ShaderProperties.planetShineRGB_PROPERTY, prolandManager.planetShineRGBMatrix); } UpdateEclipseAndRingUniforms(mat); if (legacyGodraysRenderer) { mat.SetFloat(ShaderProperties._godrayStrength_PROPERTY, godrayStrength); } mat.SetColor(ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor()); } private void UpdateEclipseAndRingUniforms(Material mat) { if (useEclipses) { mat.SetMatrix(ShaderProperties.lightOccluders1_PROPERTY, castersMatrix1); mat.SetMatrix(ShaderProperties.lightOccluders2_PROPERTY, castersMatrix2); mat.SetVector(ShaderProperties.sunPosAndRadius_PROPERTY, new Vector4(sunPosRelPlanet.x, sunPosRelPlanet.y, sunPosRelPlanet.z, (float)prolandManager.sunCelestialBody.Radius)); } if (hasRingObjectAndShadowActivated) { mat.SetVector(ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up); } } public void SetOceanUniforms (Material mat) { if (mat == null) return; mat.SetFloat (ShaderProperties._ScatteringExposure_PROPERTY, interpolatedSettings.scatteringExposure); mat.SetFloat (ShaderProperties.Rg_PROPERTY, Rg*atmosphereStartRadiusScale); mat.SetFloat (ShaderProperties.Rt_PROPERTY, Rt); mat.SetFloat (ShaderProperties.mieG_PROPERTY, Mathf.Clamp (m_mieG, 0.0f, 0.99f)); mat.SetVector (ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToMainSun ()); mat.SetVector(ShaderProperties._camForward_PROPERTY, Scatterer.Instance.nearCamera.transform.forward); mat.SetFloat (ShaderProperties._Alpha_Global_PROPERTY, interpolatedSettings.skyAlpha); mat.SetFloat (ShaderProperties._SkyExposure_PROPERTY, interpolatedSettings.skyExposure); UpdatePostProcessMaterialUniforms (mat); } public void InitPostprocessMaterialUniforms (Material mat) { if (mat == null || !precomputedAtmoLoaded) return; mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f)); mat.SetTexture(ShaderProperties.AtmosphereAtlas_PROPERTY, atmosphereAtlas); mat.SetVector(ShaderProperties.InscatterAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[0]); mat.SetVector(ShaderProperties.IrradianceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[1]); mat.SetVector(ShaderProperties.TransmittanceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[2]); mat.SetVector(ShaderProperties.AtmosphereAtlasDimensions_PROPERTY, new Vector2(atmosphereAtlas.width, atmosphereAtlas.height)); mat.SetFloat(ShaderProperties.M_PI_PROPERTY, Mathf.PI); mat.SetFloat(ShaderProperties.Rg_PROPERTY, Rg * atmosphereStartRadiusScale); mat.SetFloat(ShaderProperties.Rt_PROPERTY, Rt); mat.SetVector(ShaderProperties.PRECOMPUTED_SCTR_LUT_DIM_PROPERTY, scatteringLutDimensions); mat.SetFloat(ShaderProperties.TRANSMITTANCE_W_PROPERTY, TRANSMITTANCE_W); mat.SetFloat(ShaderProperties.TRANSMITTANCE_H_PROPERTY, TRANSMITTANCE_H); mat.SetFloat(ShaderProperties.SKY_W_PROPERTY, SKY_W); mat.SetFloat(ShaderProperties.SKY_H_PROPERTY, SKY_H); mat.SetVector(ShaderProperties.betaR_PROPERTY, m_betaR / 1000.0f / mainMenuScaleFactor); mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f)); mat.SetVector(ShaderProperties.betaMSca_PROPERTY, BETA_MSca / 1000.0f / mainMenuScaleFactor); mat.SetVector(ShaderProperties.betaMEx_PROPERTY, (BETA_MSca / 1000.0f / mainMenuScaleFactor) / 0.9f); mat.SetFloat(ShaderProperties.HR_PROPERTY, HR * 1000.0f * mainMenuScaleFactor); mat.SetFloat(ShaderProperties.HM_PROPERTY, HM * 1000.0f * mainMenuScaleFactor); mat.SetVector(ShaderProperties.SUN_DIR_PROPERTY, prolandManager.getDirectionToMainSun()); Utils.EnableOrDisableShaderKeywords(mat, "PLANETSHINE_ON", "PLANETSHINE_OFF", (prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine); //When using custom ocean shaders, we don't reuse the ocean mesh to render scattering separately: Instead ocean shader handles scattering internally //When the ocean starts fading out when transitioning to orbit, ocean shader stops doing scattering, and stops writing to z-buffer //The ocean floor vertexes are then used by the scattering shader, moving them to the surface to render scattering, this is not needed for stock ocean so disable it Utils.EnableOrDisableShaderKeywords(mat, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", Scatterer.Instance.mainSettings.useOceanShaders && prolandManager.hasOcean); Utils.EnableOrDisableShaderKeywords(mat, "DITHERING_ON", "DITHERING_OFF", Scatterer.Instance.mainSettings.useDithering); if (prolandManager.flatScaledSpaceModel && prolandManager.parentCelestialBody.pqsController) mat.SetFloat(ShaderProperties._PlanetOpacity_PROPERTY, 0f); else mat.SetFloat(ShaderProperties._PlanetOpacity_PROPERTY, 1f); mat.SetColor(ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor()); mat.SetColor(ShaderProperties.cloudSunColor_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.getIntensityModulatedSunColor() : prolandManager.mainScaledSunLight.color * prolandManager.mainScaledSunLight.intensity); float camerasOverlap = 0f; if (!Scatterer.Instance.unifiedCameraMode) camerasOverlap = Scatterer.Instance.nearCamera.farClipPlane - Scatterer.Instance.farCamera.nearClipPlane; mat.SetFloat(ShaderProperties._ScattererCameraOverlap_PROPERTY, camerasOverlap); InitGodraysUniforms(mat); Utils.SetToneMapping(mat); InitEclipseAndRingUniforms(mat); } public void UpdatePostProcessMaterialUniforms (Material mat) { mat.SetFloat (ShaderProperties._global_alpha_PROPERTY, interpolatedSettings.postProcessAlpha); mat.SetFloat (ShaderProperties._ScatteringExposure_PROPERTY, interpolatedSettings.scatteringExposure); mat.SetFloat (ShaderProperties._global_depth_PROPERTY, interpolatedSettings.postProcessDepth *1000000); if (prolandManager.flatScaledSpaceModel && prolandManager.parentCelestialBody.pqsController) { if (MapView.MapIsEnabled) mat.SetFloat (ShaderProperties._PlanetOpacity_PROPERTY, 0f); else mat.SetFloat (ShaderProperties._PlanetOpacity_PROPERTY, 1f - prolandManager.parentCelestialBody.pqsController.surfaceMaterial.GetFloat (ShaderProperties._PlanetOpacity_PROPERTY)); } mat.SetFloat (ShaderProperties._Post_Extinction_Tint_PROPERTY, interpolatedSettings.extinctionTint); mat.SetFloat (ShaderProperties.extinctionThickness_PROPERTY, interpolatedSettings.extinctionThickness); mat.SetVector (ShaderProperties.SUN_DIR_PROPERTY, prolandManager.getDirectionToMainSun ()); mat.SetVector (ShaderProperties._planetPos_PROPERTY, parentLocalTransform.position); mat.SetColor (ShaderProperties.cloudSunColor_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.getIntensityModulatedSunColor() : prolandManager.mainScaledSunLight.color * prolandManager.mainScaledSunLight.intensity ); if ((prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine) { mat.SetMatrix (ShaderProperties.planetShineSources_PROPERTY, prolandManager.planetShineSourcesMatrix); mat.SetMatrix (ShaderProperties.planetShineRGB_PROPERTY, prolandManager.planetShineRGBMatrix); mat.SetMatrix (ShaderProperties.cloudPlanetShineRGB_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.planetShineRGBMatrix : prolandManager.planetShineOriginalRGBMatrix ); } if (legacyGodraysRenderer) { mat.SetFloat(ShaderProperties._godrayStrength_PROPERTY, godrayStrength); } mat.SetColor (ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor()); UpdateEclipseAndRingUniforms(mat); } public void InitUniforms (Material mat) { if (mat == null || !precomputedAtmoLoaded) return; mat.SetFloat(ShaderProperties.M_PI_PROPERTY, Mathf.PI); mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f)); mat.SetVector(ShaderProperties.betaR_PROPERTY, m_betaR / 1000.0f / mainMenuScaleFactor); mat.SetTexture(ShaderProperties.AtmosphereAtlas_PROPERTY, atmosphereAtlas); mat.SetVector(ShaderProperties.InscatterAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[0]); mat.SetVector(ShaderProperties.IrradianceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[1]); mat.SetVector(ShaderProperties.TransmittanceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[2]); mat.SetVector(ShaderProperties.AtmosphereAtlasDimensions_PROPERTY, atlasDimensions); mat.SetFloat(ShaderProperties.Rg_PROPERTY, Rg * atmosphereStartRadiusScale); mat.SetFloat(ShaderProperties.Rt_PROPERTY, Rt); mat.SetFloat(ShaderProperties.TRANSMITTANCE_W_PROPERTY, TRANSMITTANCE_W); mat.SetFloat(ShaderProperties.TRANSMITTANCE_H_PROPERTY, TRANSMITTANCE_H); mat.SetFloat(ShaderProperties.SKY_W_PROPERTY, SKY_W); mat.SetFloat(ShaderProperties.SKY_H_PROPERTY, SKY_H); mat.SetVector(ShaderProperties.PRECOMPUTED_SCTR_LUT_DIM_PROPERTY, scatteringLutDimensions); mat.SetFloat(ShaderProperties.HR_PROPERTY, HR * 1000.0f * mainMenuScaleFactor); mat.SetFloat(ShaderProperties.HM_PROPERTY, HM * 1000.0f * mainMenuScaleFactor); mat.SetVector(ShaderProperties.betaMSca_PROPERTY, BETA_MSca / 1000.0f / mainMenuScaleFactor); mat.SetVector(ShaderProperties.betaMEx_PROPERTY, (BETA_MSca / 1000.0f / mainMenuScaleFactor) / 0.9f); InitEclipseAndRingUniforms(mat); Utils.EnableOrDisableShaderKeywords(mat, "PLANETSHINE_ON", "PLANETSHINE_OFF", (prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine); Utils.EnableOrDisableShaderKeywords(mat, "DITHERING_ON", "DITHERING_OFF", Scatterer.Instance.mainSettings.useDithering); mat.SetFloat(ShaderProperties.flatScaledSpaceModel_PROPERTY, prolandManager.flatScaledSpaceModel ? 1f : 0f); mat.SetColor(ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor()); mat.SetColor(ShaderProperties.cloudSunColor_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.getIntensityModulatedSunColor() : prolandManager.mainScaledSunLight.color * prolandManager.mainScaledSunLight.intensity); InitGodraysUniforms(mat); Utils.SetToneMapping(mat); } private void InitGodraysUniforms(Material mat) { if (legacyGodraysRenderer != null) { mat.SetTexture(ShaderProperties._godrayDepthTexture_PROPERTY, legacyGodraysRenderer.volumeDepthTexture); mat.EnableKeyword("GODRAYS_LEGACY"); mat.EnableKeyword("RAYMARCHED_GODRAYS_OFF"); mat.DisableKeyword("GODRAYS_OFF"); mat.SetFloat(ShaderProperties.godraysSoftwareSwitch_PROPERTY, 0f); } else { mat.EnableKeyword("RAYMARCHED_GODRAYS_OFF"); mat.EnableKeyword("GODRAYS_OFF"); mat.SetFloat(ShaderProperties.godraysSoftwareSwitch_PROPERTY, 0f); } } private void InitEclipseAndRingUniforms(Material mat) { if (hasRingObjectAndShadowActivated) { Utils.EnableOrDisableShaderKeywords(mat, "RINGSHADOW_ON", "RINGSHADOW_OFF", true); mat.SetFloat("useRingShadow", 1f); mat.SetFloat(ShaderProperties.ringInnerRadius_PROPERTY, ringInnerRadius); mat.SetFloat(ShaderProperties.ringOuterRadius_PROPERTY, ringOuterRadius); mat.SetVector(ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up); mat.SetTexture(ShaderProperties.ringTexture_PROPERTY, ringTexture); } else { Utils.EnableOrDisableShaderKeywords(mat, "RINGSHADOW_ON", "RINGSHADOW_OFF", false); mat.SetFloat("useRingShadow", 0f); } Utils.EnableOrDisableShaderKeywords(mat, "ECLIPSES_ON", "ECLIPSES_OFF", useEclipses); mat.SetFloat("useEclipses", useEclipses ? 1f : 0f); } public void TogglePostProcessing() { postprocessingEnabled = !postprocessingEnabled; } void InitOrRequestPrecomputedAtmo () { Rg = (float) prolandManager.GetRadius (); Rt = AtmoPreprocessor.CalculateRt (Rg*atmosphereStartRadiusScale, HR*mainMenuScaleFactor, HM*mainMenuScaleFactor, m_betaR/mainMenuScaleFactor, BETA_MSca/mainMenuScaleFactor, useOzone, ozoneHeight/mainMenuScaleFactor, ozoneFalloff/mainMenuScaleFactor); //Compute atmo hash and path string cachePath = Utils.GameDataPath + "/ScattererAtmosphereCache/PluginData"; float originalRt = AtmoPreprocessor.CalculateRt ((float) prolandManager.parentCelestialBody.Radius * atmosphereStartRadiusScale, HR, HM, m_betaR, BETA_MSca, useOzone, ozoneHeight, ozoneFalloff); string atmohash = AtmoPreprocessor.GetAtmoHash((float) prolandManager.parentCelestialBody.Radius * atmosphereStartRadiusScale, originalRt, m_betaR, BETA_MSca, m_mieG, HR, HM, averageGroundReflectance, multipleScattering, scatteringLutDimensions, useOzone, ozoneAbsorption, ozoneHeight, ozoneFalloff); cachePath += "/" + atmohash; string atlasPath = cachePath + "/atlas.half"; if (!System.IO.File.Exists (atlasPath)) { AtmoPreprocessor.Generate ((float) prolandManager.parentCelestialBody.Radius * atmosphereStartRadiusScale, originalRt, m_betaR, BETA_MSca, m_mieG, HR, HM, averageGroundReflectance, multipleScattering, scatteringLutDimensions, previewMode, cachePath, useOzone, ozoneAbsorption, ozoneHeight, ozoneFalloff, prolandManager.parentCelestialBody.name); precomputedAtmoLoaded = false; return; } LoadPrecomputedAtmo(atlasPath); precomputedAtmoLoaded = true; if (atmosphereShadersInitiated) ReinitAllMaterials(); } private void LoadPrecomputedAtmo(string atlasPath) { var textureDimensions = new List { new Vector2(scatteringLutDimensions.x * scatteringLutDimensions.y, scatteringLutDimensions.z* scatteringLutDimensions.w), new Vector2(SKY_W, SKY_H), new Vector2(TRANSMITTANCE_W, TRANSMITTANCE_H) }; // Textures are packed in the simplest way possible, top-left to bottom-left int atlasWidth = textureDimensions.Max(texture => (int)texture.x); int atlasHeight = textureDimensions.Sum(texture => (int)texture.y); atlasDimensions = new Vector2(atlasWidth, atlasHeight); atmosphereAtlas = new Texture2D(atlasWidth, atlasHeight, TextureFormat.RGBAHalf, false); atmosphereAtlas.wrapMode = TextureWrapMode.Clamp; atmosphereAtlas.filterMode = FilterMode.Bilinear; atmosphereAtlas.LoadRawTextureData(System.IO.File.ReadAllBytes(atlasPath)); atmosphereAtlas.Apply(); atlasScaleAndOffsets = AtmoPreprocessor.GetPackedTexturesScaleAndOffsets(textureDimensions, atlasDimensions); } public void ApplyAtmoFromUI(Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inGRref, bool inMultiple, bool inFastPreviewMode, float inAtmosphereStartRadiusScale, bool inUseOzone, Vector3 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff) { m_betaR = inBETA_R; BETA_MSca = inBETA_MSca; m_mieG = inMIE_G; HR = inHR; HM = inHM; averageGroundReflectance = inGRref; multipleScattering = inMultiple; previewMode = inFastPreviewMode; scatteringLutDimensions = inFastPreviewMode ? AtmoPreprocessor.scatteringLutDimensionsPreview : AtmoPreprocessor.ScatteringLutDimensionsDefault ; atmosphereStartRadiusScale = inAtmosphereStartRadiusScale; ozoneAbsorption = inOzoneAbsorption; ozoneHeight = inOzoneHeight; ozoneFalloff = inOzoneFalloff; useOzone = inUseOzone; InitOrRequestPrecomputedAtmo (); float skySphereSize = 2 * (4 * (Rt - Rg*atmosphereStartRadiusScale) + Rg*atmosphereStartRadiusScale) / ScaledSpace.ScaleFactor; skySphere.Resize (skySphereSize); } void ReinitAllMaterials() { if (scaledEclipseMaterial) InitUniforms(scaledEclipseMaterial); if (skyMaterial) InitUniforms(skyMaterial); if (scaledScatteringMaterial) InitUniforms(scaledScatteringMaterial); if (sunflareExtinctionMaterial) InitUniforms(sunflareExtinctionMaterial); if (localScatteringMaterial) InitPostprocessMaterialUniforms(localScatteringMaterial); ReInitMaterialUniformsOnRenderTexturesLoss(); // make the clouds2d material optional // add fields for volumetrics and raymarched volumetrics if (Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName)) { foreach (EVECloudLayer eveCloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName]) { if (eveCloudLayer.Clouds2dMaterial != null) { InitUniforms(eveCloudLayer.Clouds2dMaterial); InitPostprocessMaterialUniforms(eveCloudLayer.Clouds2dMaterial); } if (eveCloudLayer.ParticleVolumetricsMaterial != null) { InitUniforms(eveCloudLayer.ParticleVolumetricsMaterial); InitPostprocessMaterialUniforms(eveCloudLayer.ParticleVolumetricsMaterial); } } } InitOceanMaterialUniforms(); } public void InitOceanMaterialUniforms() { if (prolandManager.GetOceanNode()) { if (prolandManager.GetOceanNode().m_oceanMaterial) { InitUniforms(prolandManager.GetOceanNode().m_oceanMaterial); InitPostprocessMaterialUniforms(prolandManager.GetOceanNode().m_oceanMaterial); } if (prolandManager.GetOceanNode().underwaterMaterial) { InitPostprocessMaterialUniforms(prolandManager.GetOceanNode().underwaterMaterial); } } } public void OnDestroy() { try {StopAllCoroutines ();} catch (Exception){} if (Scatterer.Instance.mainSettings.autosavePlanetSettingsOnSceneChange && !isConfigModuleManagerPatch) { SaveToConfigNode (); } if (atmosphereAtlas) { UnityEngine.Object.DestroyImmediate(atmosphereAtlas); } if (skySphere != null) { skySphere.Cleanup (); } if (scaledScatteringContainer != null) { scaledScatteringContainer.Cleanup (); } if (localScatteringContainer != null) { localScatteringContainer.Cleanup(); } if (legacyGodraysRenderer) { Component.DestroyImmediate(legacyGodraysRenderer); } //disable eve integration scatterer flag if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && usesCloudIntegration) { try { if(Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName)) { foreach(var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName]) { if (cloudLayer.Clouds2dMaterial != null) { cloudLayer.Clouds2dMaterial.DisableKeyword("SCATTERER_ON"); cloudLayer.Clouds2dMaterial.EnableKeyword("SCATTERER_OFF"); } if (cloudLayer.ParticleVolumetricsMaterial != null) { cloudLayer.ParticleVolumetricsMaterial.DisableKeyword("SCATTERER_ON"); cloudLayer.ParticleVolumetricsMaterial.EnableKeyword("SCATTERER_OFF"); cloudLayer.ParticleVolumetricsMaterial.SetFloat("isUnderwater", 0f); } } } } catch (Exception) { //TODO } } if (originalScaledMesh && parentScaledTransform) { var mf = parentScaledTransform.GetComponent (); if (mf) mf.sharedMesh = originalScaledMesh; } RestoreStockScaledTexture (); } public bool LoadFromConfigNode () { ConfigNode cnToLoad = new ConfigNode(); ConfigNode[] configNodeArray; bool found = false; foreach (UrlDir.UrlConfig _url in Scatterer.Instance.planetsConfigsReader.atmoConfigs) { configNodeArray = _url.config.GetNodes("Atmo"); //if (_url.config.TryGetNode("Atmo",ref cnToLoad)) foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name") && _cn.GetValue("name") == celestialBodyName) { cnToLoad = _cn; configUrl = _url; found = true; break; } } } if (found) { Utils.LogDebug(" Atmosphere config found for: "+celestialBodyName); ConfigNode.LoadObjectFromConfig (this, cnToLoad); Rg = (float) prolandManager.GetRadius (); Rt = AtmoPreprocessor.CalculateRt (Rg * atmosphereStartRadiusScale, HR*mainMenuScaleFactor, HM*mainMenuScaleFactor, m_betaR/mainMenuScaleFactor, BETA_MSca/mainMenuScaleFactor, useOzone, ozoneHeight / mainMenuScaleFactor, ozoneFalloff / mainMenuScaleFactor); godrayStrength = Mathf.Min(godrayStrength,1.0f); //compare parentConfigNode with the one on disk to determine if it's a ModuleManager Patch string parentConfigNodePath = Utils.GameDataPath + configUrl.parent.url +".cfg"; if (System.IO.File.Exists(parentConfigNodePath)) { ConfigNode cnParentFromFile = ConfigNode.Load(Utils.GameDataPath + configUrl.parent.url +".cfg"); if (cnParentFromFile.HasNode("Scatterer_atmosphere")) { int comparisonResult = configUrl.config.ToString().CompareTo(cnParentFromFile.GetNode("Scatterer_atmosphere").ToString()); isConfigModuleManagerPatch = (comparisonResult != 0); } } } else { Utils.LogError(" Atmosphere config not found for: "+celestialBodyName); Utils.LogDebug(" Removing "+celestialBodyName +" from planets list"); Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Remove(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Find(_cb => _cb.celestialBodyName == celestialBodyName)); prolandManager.OnDestroy(); UnityEngine.Object.Destroy (prolandManager); UnityEngine.Object.Destroy (this); } return found; } public void SaveToConfigNode () { ConfigNode[] configNodeArray; bool found = false; configNodeArray = configUrl.config.GetNodes("Atmo"); foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name") && _cn.GetValue("name") == celestialBodyName) { ConfigNode cnTemp = ConfigNode.CreateConfigFromObject (this); _cn.ClearData(); ConfigNode.Merge (_cn, cnTemp); _cn.name="Atmo"; Utils.LogDebug(" saving "+celestialBodyName+" atmo config to: "+configUrl.parent.url); configUrl.parent.SaveConfigs (); found=true; break; } } if (!found) { Utils.LogDebug(" couldn't find config file to save to"); } } void DisableStockSky () { for (int i = 0; i < parentScaledTransform.childCount; i++) { if (parentScaledTransform.GetChild (i).gameObject.layer == 9) { if (parentScaledTransform.GetChild (i).gameObject.name == "Atmosphere") { stockSkyGameObject = parentScaledTransform.GetChild (i).gameObject; stockSkyGameObject.SetActive (false); break; } } } } IEnumerator DelayedTweakStockPlanet() { if (!stockScaledPlanetMeshRenderer.sharedMaterial.HasProperty ("_MainTex")) //this property is absent on gas giants { DisableStockSky(); if (adjustScaledTexture) TweakStockScaledTexture (); } else // Have to delay this until Kopernicus loads the on-demand textures and also check it's not a rendertexture (ie overridden by scatterer) { while (true) { Texture maintex = stockScaledPlanetMeshRenderer.sharedMaterial.GetTexture("_MainTex"); if (maintex != null && maintex is Texture2D) { if (adjustScaledTexture) TweakStockScaledTexture (); TweakStockAtmosphere (); yield return StartCoroutine(CheckOnDemandUnload()); //once loaded, wait for it to unload and resume checking again } yield return new WaitForSeconds(1f); } } } // Check if kopernicus on demand unloads the planet, then we have to start waiting for it to load it again IEnumerator CheckOnDemandUnload() { while (true) { if (stockScaledPlanetMeshRenderer.sharedMaterial.GetTexture("_MainTex") == null) { break; } yield return new WaitForSeconds(3f); } } public void TweakStockAtmosphere () //move to utils/scaledUtils etc { DisableStockSky (); List materials = new List(stockScaledPlanetMeshRenderer.sharedMaterials); materials.RemoveAll(x => x.shader.name == "Scatterer/ScaledPlanetEclipse"); if (useEclipses) { var deferred = ReflectionUtils.getType("Deferred.Deferred"); bool deferredInstalled = deferred != null; // Split the main pass and the additive light passes into separate materials with different renderqueues so we can inject eclipses after the first pass, and make it apply only to the main pass // But only if deferred is not installed, otherwise this breaks deferred rendering if (parentScaledTransform.GetComponent() == null && !deferredInstalled) { List materialsNoCityLights = new List(materials); materialsNoCityLights.RemoveAll(x => x.shader.name == "EVE/PlanetCityLight"); Material planetScaledSpaceMaterial = materialsNoCityLights.ElementAt(0); planetScaledSpaceMaterial.SetShaderPassEnabled("ForwardBase", true); planetScaledSpaceMaterial.SetShaderPassEnabled("ForwardAdd", false); materials.Add(Material.Instantiate(planetScaledSpaceMaterial)); materials.Last().CopyPropertiesFromMaterial(materialsNoCityLights.ElementAt(0)); materials.Last().SetShaderPassEnabled("ForwardBase", false); materials.Last().SetShaderPassEnabled("ForwardAdd", true); materials.Last().renderQueue = 2002; PlanetSecondaryLightUpdater secondaryLightUpdater = parentScaledTransform.gameObject.AddComponent(); secondaryLightUpdater.Init(planetScaledSpaceMaterial, materials.Last()); } materials.Add(scaledEclipseMaterial); } stockScaledPlanetMeshRenderer.sharedMaterials = materials.ToArray (); foreach (Material sharedMaterial in materials) { sharedMaterial.SetFloat (Shader.PropertyToID ("_rimBlend"), rimBlend / 100f); sharedMaterial.SetFloat (Shader.PropertyToID ("_rimPower"), rimpower / 100f); if (sharedMaterial.shader.name == "Terrain/Scaled Planet (RimAerial) Standard") { sharedMaterial.SetColor ("_SpecColor", new Color (specR / 255f, specG / 255f, specB / 255f)); if (HighLogic.LoadedScene == GameScenes.MAINMENU) { sharedMaterial.SetFloat ("_Shininess", shininess / 140f); //for some reason still too strong in main menu } else { sharedMaterial.SetFloat ("_Shininess", shininess / 120f); } } else { sharedMaterial.SetColor ("_SpecColor", new Color (specR / 100f, specG / 100f, specB / 100f)); sharedMaterial.SetFloat ("_Shininess", shininess / 100f); } } if (prolandManager.parentCelestialBody.pqsController != null) { Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.fallbackMaterial,"AERIAL_ON", "AERIAL_OFF", false); Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.lowQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false); Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.mediumQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false); Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.highQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false); Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.ultraQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false); } } public void TweakStockScaledTexture () //move to utils/scaledUtils etc { if (HighLogic.LoadedScene != GameScenes.MAINMENU) { List materials = new List(stockScaledPlanetMeshRenderer.sharedMaterials); foreach (Material sharedMaterial in materials) { if (sharedMaterial.shader.name.Contains("Terrain/Scaled Planet (RimAerial)")) { if (!originalPlanetTexture) { Texture maintex = sharedMaterial.GetTexture("_MainTex"); if (maintex is Texture2D) { originalPlanetTexture = (Texture2D)maintex; } } if (originalPlanetTexture) { if (!adjustedPlanetTexture) { adjustedPlanetTexture = new RenderTexture(originalPlanetTexture.width, originalPlanetTexture.height, 0, RenderTextureFormat.ARGB32); adjustedPlanetTexture.name = "ScattererAdjustedPlanetMap"; adjustedPlanetTexture.autoGenerateMips = true; adjustedPlanetTexture.Create(); } Material imageAdjustMat = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/ScaledTextureAdjust")]); imageAdjustMat.SetTexture("inputTexture", originalPlanetTexture); imageAdjustMat.SetFloat("_scaledLandBrightnessAdjust", scaledLandBrightnessAdjust); imageAdjustMat.SetFloat("_scaledLandContrastAdjust", scaledLandContrastAdjust); imageAdjustMat.SetFloat("_scaledLandSaturationAdjust", scaledLandSaturationAdjust); imageAdjustMat.SetFloat("_scaledOceanBrightnessAdjust", scaledOceanBrightnessAdjust); imageAdjustMat.SetFloat("_scaledOceanContrastAdjust", scaledOceanContrastAdjust); imageAdjustMat.SetFloat("_scaledOceanSaturationAdjust", scaledOceanSaturationAdjust); Graphics.Blit(originalPlanetTexture, adjustedPlanetTexture, imageAdjustMat); sharedMaterial.SetTexture("_MainTex", adjustedPlanetTexture); } } } } } public void RestoreStockScaledTexture () //move to utils/scaledUtils etc { if (originalPlanetTexture && stockScaledPlanetMeshRenderer) { List materials = new List(stockScaledPlanetMeshRenderer.sharedMaterials); foreach (Material sharedMaterial in materials) { if (sharedMaterial.shader.name.Contains("Terrain/Scaled Planet (RimAerial)")) { sharedMaterial.SetTexture("_MainTex", originalPlanetTexture); } } } if (adjustedPlanetTexture) { adjustedPlanetTexture.Release(); } } public void TweakScaledMesh() //move to utils/scaledUtils etc { if (!originalScaledMesh) { originalScaledMesh = parentScaledTransform.GetComponent ().sharedMesh; } tweakedScaledmesh = (Mesh)Instantiate (originalScaledMesh); double scaledRadius = prolandManager.GetRadius () / (ScaledSpace.ScaleFactor * parentScaledTransform.localScale.x); Vector3[] verts = tweakedScaledmesh.vertices; for (int i=0; i scaledRadius) { verts [i] = verts [i].normalized * (Mathf.Lerp (verts [i].magnitude, (float)scaledRadius, flattenScaledSpaceMesh)); } } tweakedScaledmesh.vertices = verts; tweakedScaledmesh.RecalculateNormals (); tweakedScaledmesh.RecalculateTangents (); tweakedScaledmesh.RecalculateBounds (); parentScaledTransform.GetComponent ().sharedMesh = tweakedScaledmesh; } public void InterpolateVariables () { if(!(HighLogic.LoadedScene == GameScenes.TRACKSTATION)) { altitude = Vector3.Distance (Scatterer.Instance.nearCamera.transform.position, parentLocalTransform.position) - Rg; } if ((HighLogic.LoadedScene == GameScenes.MAINMENU) || (HighLogic.LoadedScene == GameScenes.TRACKSTATION) || MapView.MapIsEnabled) { interpolatedSettings.getValuesFrom(configPoints [configPoints.Count - 1]); currentConfigPoint = configPoints.Count; return; } if (altitude <= configPoints [0].altitude) { interpolatedSettings.getValuesFrom(configPoints [0]); currentConfigPoint = 0; } else if (altitude > configPoints [configPoints.Count - 1].altitude) { interpolatedSettings.getValuesFrom(configPoints [configPoints.Count - 1]); currentConfigPoint = configPoints.Count; } else { //TODO, replace this with binary search, implement method directly in configPoints class, which will implement a list of config points for (int j = 1; j < configPoints.Count; j++) { if ((altitude > configPoints [j - 1].altitude) && (altitude <= configPoints [j].altitude)) { percentage = (altitude - configPoints [j - 1].altitude) / (configPoints [j].altitude - configPoints [j - 1].altitude); interpolatedSettings.interpolateValuesFrom(configPoints [j - 1], configPoints [j], percentage); currentConfigPoint = j; } } } } void UpdateLightExtinctions () { Vector3 sunDirection = prolandManager.getDirectionToMainSun(); Vector3 extinctionPosition = (FlightGlobals.ActiveVessel ? FlightGlobals.ActiveVessel.transform.position : Scatterer.Instance.nearCamera.transform.position) - parentLocalTransform.position; Color extinction = AtmosphereUtils.getExtinction (extinctionPosition, sunDirection, Rt, Rg * atmosphereStartRadiusScale, HR*1000f, HM*1000f, m_betaR / 1000f, BETA_MSca / 1000f / 0.9f, useOzone, atmosphereAtlas, transmittanceTableDimensions, atlasScaleAndOffsets[2], atlasDimensions); extinction = Color.Lerp(Color.white, extinction, interpolatedSettings.extinctionThickness); float extinctionSunsetToNoonTransition = Vector3.Dot(sunDirection, extinctionPosition.normalized); extinctionSunsetToNoonTransition = Mathf.Clamp01( ((extinctionSunsetToNoonTransition-0.2f) / 0.8f) * (1f - noonSunlightExtinctionStrength) ); extinction = Color.Lerp(extinction, Color.white, extinctionSunsetToNoonTransition); Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByColor (prolandManager.mainSunLight, extinction); foreach(SecondarySun secondarySun in prolandManager.secondarySuns) { if (secondarySun.sunLight) { extinction = AtmosphereUtils.getExtinction (extinctionPosition, (secondarySun.celestialBody.GetTransform().position - prolandManager.parentCelestialBody.GetTransform().position).normalized, Rt, Rg * atmosphereStartRadiusScale, HR*1000f, HM*1000f, m_betaR / 1000f, BETA_MSca / 1000f / 0.9f, useOzone, atmosphereAtlas, transmittanceTableDimensions, atlasScaleAndOffsets[2], atlasDimensions); extinction = Color.Lerp(Color.white, extinction, interpolatedSettings.extinctionThickness); //consider getting rid of extinction thickness and tint now Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByColor (secondarySun.sunLight, extinction); } } } void UpdateSunflareExtinctions () { foreach (SunFlare customSunFlare in Scatterer.Instance.sunflareManager.scattererSunFlares.Values) { if (customSunFlare.FlareRendering) //not sure if it's worth it to try and add more intelligent culling here, like checking if a ray to the flare intersects the planet/atmo? { sunflareExtinctionMaterial.SetVector (ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToCelestialBody (customSunFlare.source).normalized); if (!MapView.MapIsEnabled) sunflareExtinctionMaterial.SetVector (ShaderProperties._Globals_WorldCameraPos_PROPERTY, Scatterer.Instance.nearCamera.transform.position - parentLocalTransform.position); else sunflareExtinctionMaterial.SetVector (ShaderProperties._Globals_WorldCameraPos_PROPERTY, (Vector3)ScaledSpace.ScaledToLocalSpace (Scatterer.Instance.scaledSpaceCamera.transform.position) - parentLocalTransform.position); Graphics.Blit (null, customSunFlare.extinctionTexture, sunflareExtinctionMaterial, 0); if (hasRingObjectAndShadowActivated) { sunflareExtinctionMaterial.SetVector (ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up); Graphics.Blit (null, customSunFlare.extinctionTexture, sunflareExtinctionMaterial, 1); } } } } void UpdateEclipseCasters () { float scaleFactor = ScaledSpace.ScaleFactor; sunPosRelPlanet = Vector3.zero; sunPosRelPlanet = Vector3.Scale (ScaledSpace.LocalToScaledSpace (prolandManager.sunCelestialBody.transform.position), new Vector3 (scaleFactor, scaleFactor, scaleFactor)); castersMatrix1 = Matrix4x4.zero; castersMatrix2 = Matrix4x4.zero; Vector3 casterPosRelPlanet; float eclipseTerm = 1f; for (int i = 0; i < Mathf.Min (4, prolandManager.eclipseCasters.Count); i++) { casterPosRelPlanet = Vector3.Scale (ScaledSpace.LocalToScaledSpace (prolandManager.eclipseCasters [i].transform.position), new Vector3 (scaleFactor, scaleFactor, scaleFactor)); //wtf is this? this is doing local to scaled and back to local? castersMatrix1.SetRow (i, new Vector4 (casterPosRelPlanet.x, casterPosRelPlanet.y, casterPosRelPlanet.z, (float)prolandManager.eclipseCasters [i].Radius)); eclipseTerm *= AtmosphereUtils.getEclipseShadow(Scatterer.Instance.nearCamera.transform.position, sunPosRelPlanet, casterPosRelPlanet, (float)prolandManager.eclipseCasters[i].Radius, (float)prolandManager.sunCelestialBody.Radius); } for (int i = 4; i < Mathf.Min (8, prolandManager.eclipseCasters.Count); i++) { casterPosRelPlanet = Vector3.Scale (ScaledSpace.LocalToScaledSpace (prolandManager.eclipseCasters [i].transform.position), new Vector3 (scaleFactor, scaleFactor, scaleFactor)); castersMatrix2.SetRow (i - 4, new Vector4 (casterPosRelPlanet.x, casterPosRelPlanet.y, casterPosRelPlanet.z, (float)prolandManager.eclipseCasters [i].Radius)); eclipseTerm *= AtmosphereUtils.getEclipseShadow(Scatterer.Instance.nearCamera.transform.position, sunPosRelPlanet, casterPosRelPlanet, (float)prolandManager.eclipseCasters[i].Radius, (float)prolandManager.sunCelestialBody.Radius); } Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByAttenuation(prolandManager.mainSunLight, eclipseTerm); } void InitKopernicusRings () { ringObject = GameObject.Find (celestialBodyName + "Ring"); if (ringObject) { Utils.LogDebug (" Found ring for " + celestialBodyName); Material ringMat = ringObject.GetComponent ().material; hasRingObjectAndShadowActivated = true; MonoBehaviour[] scripts = (MonoBehaviour[])ringObject.GetComponents (); foreach (MonoBehaviour _script in scripts) { if (_script.GetType ().ToString ().Contains ("Ring")) { const BindingFlags flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; FieldInfo[] fields = _script.GetType ().GetFields (flags); foreach (FieldInfo fi in fields) { //Utils.Log("fi.Name "+fi.Name+" fi.GetType() "+fi.GetType()); } try { ringTexture = _script.GetType ().GetField ("texture", flags).GetValue (_script) as Texture2D; Utils.LogDebug (" ring texture fetch successful"); Utils.LogDebug (" ringTexture.width " + ringTexture.width.ToString ()); Utils.LogDebug (" ringTexture.height " + ringTexture.height.ToString ()); MeshRenderer ringMR = _script.GetType ().GetField ("ringMr", flags).GetValue (_script) as MeshRenderer; Utils.LogDebug (" ring MeshRenderer fetch successful"); ringInnerRadius = ringMR.material.GetFloat ("innerRadius"); ringOuterRadius = ringMR.material.GetFloat ("outerRadius"); Utils.LogDebug (" ring innerRadius (with parent scale) " + ringInnerRadius.ToString ()); Utils.LogDebug (" ring outerRadius (with parent scale) " + ringOuterRadius.ToString ()); int tiles = (int)_script.GetType ().GetField ("tiles", flags).GetValue (_script); if (tiles > 0) { throw new Exception ("Scatterer doesn't support tiled/thick Kopernicus rings (not implemented)"); } ringInnerRadius *= ScaledSpace.ScaleFactor; ringInnerRadius = Mathf.Max(ringInnerRadius,(float)(prolandManager.m_radius)* (1f + 10f/600000f)); //prevent inner ring radius from intersecting planet's radius because that's stupid and it breaks the shader ringOuterRadius *= ScaledSpace.ScaleFactor; } catch (Exception e) { Utils.LogError ("Kopernicus ring exception: " + e.ToString ()); Utils.LogDebug ("Disabling ring shadows for " + celestialBodyName); hasRingObjectAndShadowActivated = false; } } } } } public void InitEVEClouds() { if ((Scatterer.Instance.eveReflectionHandler.EVEInstance != null) && Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName)) { try { Scatterer.Instance.eveReflectionHandler.invokeClouds2dReassign(celestialBodyName); // After the shader has been replaced by the modified scatterer shader, the properties are lost, this sets them again foreach (var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName]) { if (cloudLayer.Clouds2dMaterial != null) { Utils.EnableOrDisableShaderKeywords(cloudLayer.Clouds2dMaterial, "SCATTERER_ON", "SCATTERER_OFF", true); InitUniforms (cloudLayer.Clouds2dMaterial); InitPostprocessMaterialUniforms (cloudLayer.Clouds2dMaterial); if (HighLogic.LoadedScene == GameScenes.MAINMENU) { //Wrongly defined to ON in mainmenu by EVE, causing messed up extinction calculations Utils.EnableOrDisableShaderKeywords(cloudLayer.Clouds2dMaterial, "WORLD_SPACE_ON", "WORLD_SPACE_OFF", false); } } if (cloudLayer.ParticleVolumetricsMaterial != null) { Utils.EnableOrDisableShaderKeywords(cloudLayer.ParticleVolumetricsMaterial, "SCATTERER_ON", "SCATTERER_OFF", true); InitUniforms(cloudLayer.ParticleVolumetricsMaterial); InitPostprocessMaterialUniforms(cloudLayer.ParticleVolumetricsMaterial); cloudLayer.ParticleVolumetricsMaterial.SetFloat("isUnderwater", 0f); } if (cloudLayer.CloudShadowMaterial != null) { Utils.EnableOrDisableShaderKeywords(cloudLayer.CloudShadowMaterial, "SCATTERER_OCEAN_ON", "SCATTERER_OCEAN_OFF", Scatterer.Instance.mainSettings.useOceanShaders && prolandManager.hasOcean); } } } catch (Exception e) { Utils.LogError ("Error initiating EVE Clouds on planet: " + celestialBodyName + " Exception returned: " + e.ToString ()); } } } void UpdateEVECloudMaterials () { if (Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey (celestialBodyName)) { foreach (var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName]) { if (cloudLayer.Clouds2dMaterial != null) { SetUniforms (cloudLayer.Clouds2dMaterial); UpdatePostProcessMaterialUniforms(cloudLayer.Clouds2dMaterial); cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.cloudColorMultiplier_PROPERTY, cloudColorMultiplier); cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.cloudScatteringMultiplier_PROPERTY, cloudScatteringMultiplier); cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.cloudSkyIrradianceMultiplier_PROPERTY, cloudSkyIrradianceMultiplier); cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.preserveCloudColors_PROPERTY, EVEIntegration_preserveCloudColors ? 1f : 0f); } if (cloudLayer.ParticleVolumetricsMaterial != null) { SetUniforms(cloudLayer.ParticleVolumetricsMaterial); UpdatePostProcessMaterialUniforms(cloudLayer.ParticleVolumetricsMaterial); cloudLayer.ParticleVolumetricsMaterial.SetVector(ShaderProperties._PlanetWorldPos_PROPERTY, parentLocalTransform.position); cloudLayer.ParticleVolumetricsMaterial.SetFloat(ShaderProperties.cloudColorMultiplier_PROPERTY, volumetricsColorMultiplier); } } } } public void TogglePreserveCloudColors() { EVEIntegration_preserveCloudColors =!EVEIntegration_preserveCloudColors; } public void SetCelestialBodyName(string name) { celestialBodyName = name; } public void SetParentScaledTransform(Transform parentTransform) { parentScaledTransform = parentTransform; } public void SetParentLocalTransform(Transform parentTransform) { parentLocalTransform = parentTransform; } //to be called on loss of rendertextures, ie alt-enter public void ReInitMaterialUniformsOnRenderTexturesLoss() { if (localScatteringContainer != null) { InitPostprocessMaterialUniforms (localScatteringContainer.material); } } public void SetUnderwater(bool value) { if (localScatteringContainer != null) localScatteringContainer.SetUnderwater(value); if ((Scatterer.Instance.eveReflectionHandler.EVEInstance != null) && Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName)) { foreach (var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName]) { if (cloudLayer.ParticleVolumetricsMaterial != null) { cloudLayer.ParticleVolumetricsMaterial.SetFloat("isUnderwater", value ? 1f : 0f); } } } } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/AtmospherePQS.cs ================================================ //note: allows adding a material to PQS, not currently in use as projector works better //could be adapted for use with future grass/trees shader however using System; using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; using System.Collections.Generic; namespace Scatterer { public class AtmospherePQS : PQSMod { Material atmosphereMaterial; public override void OnSphereActive() { } public override void OnQuadCreate(PQ quad) { List materials = new List (quad.meshRenderer.sharedMaterials); materials.Add (atmosphereMaterial); quad.meshRenderer.sharedMaterials= materials.ToArray(); } public override void OnQuadDestroy(PQ quad) { List materials = new List (quad.meshRenderer.sharedMaterials); materials.Remove(materials.Find(mat => mat.shader.name == "Scatterer/AtmosphericLocalScatter")); //probably slow quad.meshRenderer.sharedMaterials = materials.ToArray (); } public void Apply(PQS pqs) { if (pqs != null) { this.sphere = pqs; this.transform.parent = pqs.transform; this.requirements = PQS.ModiferRequirements.Default; this.modEnabled = true; this.order = 10; //? this.transform.localPosition = Vector3.zero; this.transform.localRotation = Quaternion.identity; this.transform.localScale = Vector3.one; atmosphereMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/AtmosphericLocalScatter")]); Utils.LogDebug ("AtmospherePQS applied"); } } public void Cleanup() { Utils.LogDebug ("AtmospherePQS removed"); } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/AtmosphereProjectorContainer.cs ================================================ using System; using UnityEngine; namespace Scatterer { public class AtmosphereProjectorContainer : GenericLocalAtmosphereContainer { public Projector projector = null; public AtmosphereProjectorContainer (Material atmosphereMaterial, Transform parentTransform, float Rt, ProlandManager parentManager) : base (atmosphereMaterial, parentTransform, Rt, parentManager) { scatteringGO = new GameObject("Scatterer atmosphere projector "+atmosphereMaterial.name); projector = scatteringGO.AddComponent(); projector.aspectRatio = 1; projector.orthographic = true; projector.orthographicSize = 2*Rt; projector.nearClipPlane = 1; projector.farClipPlane = 4*Rt; projector.ignoreLayers = ~((1<<0) | (1<<1) | (1<<4) | (1<<15) | (1<<16) | (1<<19)); //ignore all except 4 water 15 local 16 kerbals and 19 parts scatteringGO.layer = 15; scatteringGO.transform.position = parentTransform.forward * 2*Rt + parentTransform.position; scatteringGO.transform.forward = parentTransform.position - scatteringGO.transform.position; scatteringGO.transform.parent = parentTransform; projector.material = atmosphereMaterial; projector.material.CopyKeywordsFrom (atmosphereMaterial); } public override void UpdateContainer () { bool isEnabled = !underwater && !inScaledSpace && activated; projector.enabled = isEnabled; scatteringGO.SetActive(isEnabled); } public override void Cleanup () { SetActivated (false); if(scatteringGO) { if(scatteringGO.transform && scatteringGO.transform.parent) { scatteringGO.transform.parent = null; } Component.Destroy(projector); GameObject.DestroyImmediate(scatteringGO); projector = null; scatteringGO = null; } } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/AtmosphereUtils.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using KSP.IO; namespace Scatterer { public static class AtmosphereUtils { private static float Limit(float r, float mu, float Rg, float Rt) { float dout = -r * mu + Mathf.Sqrt(r * r * (mu * mu - 1f) + Rt * Rt); float delta2 = r * r * (mu * mu - 1f) + (Rg) * (Rg); if (delta2 >= 0f) { float din = -r * mu - Mathf.Sqrt(delta2); if (din >= 0f) { dout = Mathf.Min(dout, din); } } return dout; } // optical depth for ray (r,mu) of length d, using analytic formula // (mu=cos(view zenith angle)), intersections with ground ignored // H=height scale of exponential density function private static float OpticalDepth(float H, float r, float mu, float d, float Rg, float Rt) { float a = Mathf.Sqrt((0.5f/H)*r); Vector2 a01 = a*new Vector2(mu, mu + d / r); Vector2 a01s = new Vector2(Mathf.Sign(a01.x),Mathf.Sign(a01.y)); Vector2 a01sq = a01*a01; float x = a01s.y > a01s.x ? Mathf.Exp(a01sq.x) : 0f; Vector2 y = a01s / (2.3193f* new Vector2(Mathf.Abs(a01.x), Mathf.Abs(a01.y)) + new Vector2(Mathf.Sqrt(1.52f*a01sq.x + 4f), Mathf.Sqrt(1.52f*a01sq.y + 4f))) * new Vector2(1f, Mathf.Exp(-d/H*(d/(2f*r)+mu))); return Mathf.Sqrt((6.2831f*H)*r) * Mathf.Exp((Rg-r)/H) * (x + Vector2.Dot(y, new Vector2(1f, -1f))); } private static float OpticalDepthToBoundaries(float H, float r, float mu, float Rg, float Rt) { float result = 0f; float d = Limit(r, mu, Rg, Rt); result = OpticalDepth(H, r, mu, d, Rg, Rt); return mu < -Mathf.Sqrt(1f - (Rg / r) * (Rg / r)) ? 1e9f : result; } private static Color AnalyticTransmittance(float r, float mu, float Rt, float Rg, float HR, float HM, Vector3 betaR, Vector3 betaMEx) { Vector3 depth = betaR * OpticalDepthToBoundaries(HR, r, mu, Rg, Rt) + betaMEx * OpticalDepthToBoundaries(HM, r, mu, Rg, Rt); depth.x = Mathf.Clamp (Mathf.Exp (-depth.x), 1e-36f, 1f); depth.y = Mathf.Clamp (Mathf.Exp(-depth.y), 1e-36f, 1f); depth.z = Mathf.Clamp (Mathf.Exp(-depth.z), 1e-36f, 1f); return new Color (depth.x,depth.y,depth.z,1f); } private static Vector2 GetTransmittanceUV(float r, float mu, float Rt, float Rg) { float uR, uMu; uR = Mathf.Sqrt(Mathf.Max(0, (r - Rg)) / (Rt - Rg)); uMu = Mathf.Atan((mu + 0.15f) / (1.0f + 0.15f) * Mathf.Tan(1.5f)) / 1.5f; return new Vector2(uMu, uR); } public static Color getOzoneExtinction(float r, float mu, float Rt, float Rg, Texture2D atmosphereAtlas, Vector2 ozoneTextureDimensions, Vector4 textureScaleAndOffsetInAtlas, Vector2 AtmosphereAtlasDimensions) { Vector2 uv = GetTransmittanceUV(r, mu, Rt, Rg); uv = remapUVToAtlas(uv, ozoneTextureDimensions, textureScaleAndOffsetInAtlas, AtmosphereAtlasDimensions); // Unity's get pixel Bilinear doesn't work exactly like shader-based bilinear sampling // See thread https://forum.unity.com/threads/confusion-about-texture-getpixelbinear.1236826/ // Therefore manually remap from shader-based UV to unity-style UV to be able to sample bilinear correctly here // The equivalent transformation is just to remove a half-texel offset // Note that I checked all the math 10 times and compared GetPixelBilinear() to what the shader tex2Dlod outputs and confirmed // There is always a half texel offset uv -= new Vector2(0.5f, 0.5f) / AtmosphereAtlasDimensions; return atmosphereAtlas.GetPixelBilinear(uv.x, uv.y); } private static Vector2 remapUVToAtlas(Vector2 uv, Vector2 oldTexDimensions, Vector4 textureScaleAndOffsetInAtlas, Vector2 AtmosphereAtlasDimensions) { // Remove half pixel offset uv -= new Vector2(0.5f, 0.5f) / oldTexDimensions; // Clamp, note the half pixel offset is taken into account on both sides uv.x = Mathf.Clamp(uv.x, 0f, 1f - 1.0f / oldTexDimensions.x); uv.y = Mathf.Clamp(uv.y, 0f, 1f - 1.0f / oldTexDimensions.y); // Scale, offset and add new half pixel offset uv = uv * new Vector2(textureScaleAndOffsetInAtlas.x, textureScaleAndOffsetInAtlas.y) + new Vector2(textureScaleAndOffsetInAtlas.z, textureScaleAndOffsetInAtlas.w) + new Vector2(0.5f, 0.5f) / AtmosphereAtlasDimensions; return uv; } public static Color getExtinction(Vector3 camera, Vector3 viewdir, float Rt, float Rg, float HR, float HM, Vector3 betaR, Vector3 betaMEx, bool useOzone, Texture2D atmosphereAtlas, Vector2 ozoneTextureDimensions, Vector4 textureScaleAndOffsetInAtlas, Vector2 AtmosphereAtlasDimensions) { float r = camera.magnitude; float rMu = Vector3.Dot(camera, viewdir); float mu = rMu / r; float deltaSq = Mathf.Sqrt(rMu * rMu - r * r + Rt*Rt); float din = Mathf.Max(-rMu - deltaSq, 0f); if (din > 0f) { camera += din * viewdir; rMu += din; mu = rMu / Rt; r = Rt; } Color extinction = (r > Rt) ? Color.white : AnalyticTransmittance(r, mu, Rt, Rg, HR, HM, betaR, betaMEx); if (useOzone && r < Rt) extinction *= getOzoneExtinction(r, mu, Rt, Rg, atmosphereAtlas, ozoneTextureDimensions, textureScaleAndOffsetInAtlas, AtmosphereAtlasDimensions); return extinction; } public static Color Hdr(Color L, float exposure) { L = L * exposure; L.r = L.r < 1.413 ? Mathf.Pow(L.r * 0.38317f, 1.0f / 2.2f) : 1.0f - Mathf.Exp(-L.r); L.g = L.g < 1.413 ? Mathf.Pow(L.g * 0.38317f, 1.0f / 2.2f) : 1.0f - Mathf.Exp(-L.g); L.b = L.b < 1.413 ? Mathf.Pow(L.b * 0.38317f, 1.0f / 2.2f) : 1.0f - Mathf.Exp(-L.b); return L; } public static Color SimpleSkyirradiance(Vector3 worldP, Vector3 worldS, float Rt, float Rg, Color sunColor, Texture2D m_irradiance) { float r = worldP.magnitude; if (r < 0.9 * Rg) { worldP.z += Rg; r = worldP.magnitude; } Vector3 worldV = worldP.normalized; // vertical vector float muS = Vector3.Dot(worldV, worldS.normalized); // factor 2.0 : hack to increase sky contribution (numerical simulation of // "precompued atmospheric scattering" gives less luminance than in reality) Color skyE = 2.0f * SkyIrradiance(r, muS, Rt, Rg, sunColor, m_irradiance); return skyE; } // incident sky light at given position, integrated over the hemisphere (irradiance) // r=length(x) // muS=dot(x,s) / r private static Color SkyIrradiance(float r, float muS, float Rt, float Rg, Color sunColor, Texture2D m_irradiance) { return Irradiance(r, muS, Rt, Rg, m_irradiance) * sunColor; } private static Color Irradiance(float r, float muS, float Rt, float Rg, Texture2D m_irradiance) { Vector2 uv = GetIrradianceUV(r, muS, Rt, Rg); return m_irradiance.GetPixelBilinear(uv.x, uv.y); } private static Vector2 GetIrradianceUV(float r, float muS, float Rt, float Rg) { float uR = (r - Rg) / (Rt - Rg); float uMuS = (muS + 0.2f) / (1.0f + 0.2f); return new Vector2(uMuS, uR); } public static float getEclipseShadow(Vector3 worldPos, Vector3 worldLightPos, Vector3 occluderSpherePosition, float occluderSphereRadius, float lightSourceRadius) { var lightDirection = worldLightPos - worldPos; float lightDistance = lightDirection.magnitude; lightDirection = lightDirection / lightDistance; // computation of level of shadowing w var sphereDirection = occluderSpherePosition - worldPos; //occluder planet float sphereDistance = sphereDirection.magnitude; sphereDirection = sphereDirection / sphereDistance; float dd = lightDistance * (Mathf.Asin(Mathf.Min(1.0f, (Vector3.Cross(lightDirection, sphereDirection)).magnitude)) - Mathf.Asin(Mathf.Min(1.0f, occluderSphereRadius / sphereDistance))); float w = smoothstep(-1.0f, 1.0f, -dd / lightSourceRadius); w = w * smoothstep(0.0f, 0.2f, Vector3.Dot(lightDirection, sphereDirection)); return (1 - w); } // Reimplement because the Mathf Smoothstep doesn't match what is done in shaders public static float smoothstep(float a, float b, float x) { float t = Mathf.Clamp01((x - a) / (b - a)); return t * t * (3.0f - (2.0f * t)); } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/GenericLocalAtmosphereContainer.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public abstract class GenericLocalAtmosphereContainer { protected GameObject scatteringGO = null; protected bool inScaledSpace = true; protected bool underwater = false; protected bool activated = false; public Material material; public ProlandManager manager; public GenericLocalAtmosphereContainer (Material atmosphereMaterial, Transform parentTransform, float Rt, ProlandManager parentManager) { material = atmosphereMaterial; manager = parentManager; } public void SetActivated (bool pEnabled) { activated = pEnabled; } public void SetInScaledSpace (bool pInScaledSpace) { inScaledSpace = pInScaledSpace; } public void SetUnderwater (bool pUnderwater) { underwater = pUnderwater; } public abstract void UpdateContainer (); public abstract void Cleanup (); } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/ScaledScatteringContainer.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Scatterer { public class ScaledScatteringContainer { GameObject scaledScatteringGO; MeshRenderer scaledScatteringMR; public GameObject GameObject { get { return scaledScatteringGO; } } public MeshRenderer MeshRenderer { get { return scaledScatteringMR; } } Transform parentLocalTransform, parentScaledTransform; public ScaledScatteringContainer(Mesh planetMesh, Material material, Transform inParentLocalTransform, Transform inParentScaledTransform) { parentScaledTransform = inParentScaledTransform; parentLocalTransform = inParentLocalTransform; string goName = "Scatterer scaled atmo"; var existingGoTransform = parentScaledTransform.FindChild(goName); if (existingGoTransform != null) { GameObject.DestroyImmediate(existingGoTransform.gameObject); } scaledScatteringGO = new GameObject (goName); //if depthBufferMode + new blending etc etc scaledScatteringGO.AddComponent (); scaledScatteringGO.transform.SetParent (parentScaledTransform, false); MeshFilter skySphereMF = scaledScatteringGO.AddComponent(); skySphereMF.mesh = (Mesh) Mesh.Instantiate (planetMesh); scaledScatteringMR = scaledScatteringGO.AddComponent(); scaledScatteringMR.sharedMaterial = material; Utils.EnableOrDisableShaderKeywords (scaledScatteringMR.sharedMaterial, "LOCAL_MODE_ON", "LOCAL_MODE_OFF", false); scaledScatteringMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; scaledScatteringMR.receiveShadows = false; scaledScatteringMR.motionVectorGenerationMode = MotionVectorGenerationMode.Camera; scaledScatteringMR.enabled = true; if (HighLogic.LoadedScene == GameScenes.MAINMENU) scaledScatteringGO.layer = 15; else scaledScatteringGO.layer = 10; } public void ApplyNewMesh(Mesh planetMesh) { MeshFilter skySphereMF = scaledScatteringGO.GetComponent(); skySphereMF.mesh.Clear (); skySphereMF.mesh = (Mesh) Mesh.Instantiate (planetMesh); } public void SwitchLocalMode() { scaledScatteringGO.layer = 15; scaledScatteringGO.transform.localScale = parentScaledTransform.localScale * ScaledSpace.ScaleFactor; scaledScatteringGO.transform.localPosition = Vector3.zero; scaledScatteringGO.transform.SetParent(parentLocalTransform, false); Utils.EnableOrDisableShaderKeywords (scaledScatteringMR.sharedMaterial, "LOCAL_MODE_ON", "LOCAL_MODE_OFF", true); } public void SwitchScaledMode() { scaledScatteringGO.layer = 10; scaledScatteringGO.transform.localScale = Vector3.one; scaledScatteringGO.transform.localPosition = Vector3.zero; scaledScatteringGO.transform.localRotation = Quaternion.identity; scaledScatteringGO.transform.SetParent(parentScaledTransform, false); Utils.EnableOrDisableShaderKeywords (scaledScatteringMR.sharedMaterial, "LOCAL_MODE_ON", "LOCAL_MODE_OFF", false); } public void Cleanup() { if (scaledScatteringMR != null) { scaledScatteringMR.enabled = false; UnityEngine.Component.Destroy (scaledScatteringMR); } if (scaledScatteringGO != null) { scaledScatteringGO.SetActive(false); UnityEngine.Object.Destroy(scaledScatteringGO); } } } public class ScaledScatteringScreenCopy : MonoBehaviour { void OnWillRenderObject() { Camera cam = Camera.current; if (!cam) return; ScreenCopyCommandBuffer.EnableScreenCopyForFrame (cam); } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/ScreenSpaceScatteringContainer.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using UnityEngine.Rendering; using KSP.IO; namespace Scatterer { public class ScreenSpaceScattering : MonoBehaviour { public Material material; MeshRenderer scatteringMR; public bool hasOcean = false; bool quarterRes = false; //Dictionary to check if we added the ScatteringCommandBuffer to the camera private Dictionary cameraToScatteringCommandBuffer = new Dictionary(); public void Init(bool inQuarterRes) { scatteringMR = gameObject.GetComponent(); material.SetOverrideTag("IgnoreProjector", "True"); scatteringMR.sharedMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/invisible")]); scatteringMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; scatteringMR.receiveShadows = false; scatteringMR.enabled = true; GetComponent().mesh.bounds = new Bounds (Vector4.zero, new Vector3 (Mathf.Infinity, Mathf.Infinity, Mathf.Infinity)); gameObject.layer = (int) 15; quarterRes = inQuarterRes; } public void SetActive(bool active) { scatteringMR.enabled = active; } void OnWillRenderObject() { if (scatteringMR.enabled && material != null) { Camera cam = Camera.current; if (!cam) return; if (!hasOcean) ScreenCopyCommandBuffer.EnableScreenCopyForFrame (cam); if (cameraToScatteringCommandBuffer.ContainsKey (cam)) { if (cameraToScatteringCommandBuffer[cam] != null) { cameraToScatteringCommandBuffer[cam].EnableForThisFrame(); } } else { //we add null to the cameras we don't want to render on so we don't do a string compare every time if ((cam.name == "TRReflectionCamera") || (cam.name=="Reflection Probes Camera")) //I think this should be this way to scattering as well but test I guess { cameraToScatteringCommandBuffer[cam] = null; } else { ScatteringCommandBuffer scatteringCommandBuffer = (ScatteringCommandBuffer) cam.gameObject.AddComponent(typeof(ScatteringCommandBuffer)); scatteringCommandBuffer.targetRenderer = scatteringMR; scatteringCommandBuffer.targetMaterial = material; scatteringCommandBuffer.Initialize(hasOcean, quarterRes); scatteringCommandBuffer.EnableForThisFrame(); cameraToScatteringCommandBuffer[cam] = scatteringCommandBuffer; } } } } public void OnDestroy() { foreach (var scatteringCommandBuffer in cameraToScatteringCommandBuffer.Values) { if (scatteringCommandBuffer) { Component.DestroyImmediate(scatteringCommandBuffer); } } } } public class ScatteringCommandBuffer : MonoBehaviour { bool renderingEnabled = false; public MeshRenderer targetRenderer; public Material targetMaterial; private Camera targetCamera; private CommandBuffer rendererCommandBuffer, quarterResRendererCommandBuffer; // cached values; if these change we need to recreate the RTs int m_width, m_height; bool m_hdrEnabled; bool m_hasOcean; //downscaledRenderTexture0 will hold scattering.RGB in RGB channels and extinction.R in alpha, downscaledRenderTexture1 will hold extinction.GB in RG private RenderTexture downscaledRenderTexture0, downscaledRenderTexture1, downscaledDepthRenderTexture; private Material downscaleDepthMaterial, compositeScatteringMaterial; public void Initialize(bool inHasOcean, bool quarterRes) { targetCamera = GetComponent (); targetCamera.depthTextureMode = targetCamera.depthTextureMode | DepthTextureMode.Depth; m_hasOcean = inHasOcean; //if no depth downscaling, render directly to screen rendererCommandBuffer = new CommandBuffer(); rendererCommandBuffer.name = "Scatterer screen-space scattering CommandBuffer"; targetMaterial.SetInt(ShaderProperties._ZwriteVariable_PROPERTY, inHasOcean ? 1 : 0); rendererCommandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); rendererCommandBuffer.DrawRenderer(targetRenderer, targetMaterial, 0, 0); //pass 0 render to screen if (quarterRes) { quarterResRendererCommandBuffer = new CommandBuffer(); quarterResRendererCommandBuffer.name = "Scatterer 1/4 res screen-space scattering CommandBuffer"; downscaleDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders [("Scatterer/DownscaleDepth")]); compositeScatteringMaterial = new Material(ShaderReplacer.Instance.LoadedShaders [("Scatterer/CompositeDownscaledScattering")]); Utils.EnableOrDisableShaderKeywords(compositeScatteringMaterial, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", inHasOcean); compositeScatteringMaterial.SetInt (ShaderProperties._ZwriteVariable_PROPERTY, inHasOcean ? 1 : 0); Utils.SetToneMapping(compositeScatteringMaterial); int width, height; GetRenderDimensions(out width, out height); SetupQuarterResCommandBuffer(width, height); } } void SetupQuarterResCommandBuffer(int width, int height) { CreateRenderTextures(width, height); quarterResRendererCommandBuffer.Clear(); //1) Downscale depth if (m_hasOcean) quarterResRendererCommandBuffer.Blit(null, downscaledDepthRenderTexture, downscaleDepthMaterial, 1); //ocean depth buffer downsample else quarterResRendererCommandBuffer.Blit(null, downscaledDepthRenderTexture, downscaleDepthMaterial, 0); //default depth buffer downsample quarterResRendererCommandBuffer.SetGlobalTexture("ScattererDownscaledScatteringDepth", downscaledDepthRenderTexture); //2) Render 1/4 res scattering+extinction to 1 RGBA + 1 RG texture RenderTargetIdentifier[] downscaledRenderTextures = { new RenderTargetIdentifier(downscaledRenderTexture0), new RenderTargetIdentifier(downscaledRenderTexture1) }; quarterResRendererCommandBuffer.SetRenderTarget(downscaledRenderTextures, downscaledRenderTexture0.depthBuffer); quarterResRendererCommandBuffer.ClearRenderTarget(false, true, Color.clear); quarterResRendererCommandBuffer.DrawRenderer(targetRenderer, targetMaterial, 0, 1); //pass 1 render to textures quarterResRendererCommandBuffer.SetGlobalTexture("DownscaledScattering0", downscaledRenderTexture0); quarterResRendererCommandBuffer.SetGlobalTexture("DownscaledScattering1", downscaledRenderTexture1); //3) Render quad to screen that reads from downscaled textures and full res depth and performs near-depth upsampling quarterResRendererCommandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); quarterResRendererCommandBuffer.DrawRenderer(targetRenderer, compositeScatteringMaterial, 0, 0); } void GetRenderDimensions(out int width, out int height) { if (targetCamera.activeTexture) { width = targetCamera.activeTexture.width; height = targetCamera.activeTexture.height; } else { width = targetCamera.pixelWidth; height = targetCamera.pixelHeight; } } void CreateRenderTextures (int width, int height) { m_width = width; m_height = height; m_hdrEnabled = targetCamera.allowHDR; width /= 2; height /= 2; if (downscaledRenderTexture0 != null) downscaledRenderTexture0.Release(); if (downscaledRenderTexture1 != null) downscaledRenderTexture1.Release(); if (downscaledDepthRenderTexture != null) downscaledDepthRenderTexture.Release(); downscaledRenderTexture0 = new RenderTexture (width, height, 0, m_hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32); downscaledRenderTexture0.anisoLevel = 1; downscaledRenderTexture0.antiAliasing = 1; downscaledRenderTexture0.volumeDepth = 0; downscaledRenderTexture0.useMipMap = false; downscaledRenderTexture0.autoGenerateMips = false; downscaledRenderTexture0.filterMode = FilterMode.Point; downscaledRenderTexture0.Create (); downscaledRenderTexture1 = new RenderTexture (width, height, 0, m_hdrEnabled ? RenderTextureFormat.RGHalf : RenderTextureFormat.RG16); downscaledRenderTexture1.anisoLevel = 1; downscaledRenderTexture1.antiAliasing = 1; downscaledRenderTexture1.volumeDepth = 0; downscaledRenderTexture1.useMipMap = false; downscaledRenderTexture1.autoGenerateMips = false; downscaledRenderTexture1.filterMode = FilterMode.Point; downscaledRenderTexture1.Create (); downscaledDepthRenderTexture = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat); downscaledDepthRenderTexture.anisoLevel = 1; downscaledDepthRenderTexture.antiAliasing = 1; downscaledDepthRenderTexture.volumeDepth = 0; downscaledDepthRenderTexture.useMipMap = false; downscaledDepthRenderTexture.autoGenerateMips = false; downscaledDepthRenderTexture.filterMode = FilterMode.Point; downscaledDepthRenderTexture.Create(); } public void EnableForThisFrame() { if (!renderingEnabled) { bool screenShotModeEnabled = GameSettings.TAKE_SCREENSHOT.GetKeyDown(false); if (quarterResRendererCommandBuffer != null && !screenShotModeEnabled) { int width, height; GetRenderDimensions(out width, out height); if (width != m_width || height != m_height || targetCamera.allowHDR != m_hdrEnabled) { SetupQuarterResCommandBuffer(width, height); } targetCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, quarterResRendererCommandBuffer); } else targetCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, rendererCommandBuffer); renderingEnabled = true; } } void OnPreRender() { targetMaterial.SetMatrix(ShaderProperties.CameraToWorld_PROPERTY, targetCamera.cameraToWorldMatrix); } void OnPostRender() { if (renderingEnabled && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left) { targetCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, rendererCommandBuffer); if (quarterResRendererCommandBuffer != null) targetCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, quarterResRendererCommandBuffer); renderingEnabled = false; } } public void OnDestroy () { if (targetCamera && rendererCommandBuffer != null) { targetCamera.RemoveCommandBuffer (CameraEvent.BeforeForwardAlpha, rendererCommandBuffer); rendererCommandBuffer = null; if (quarterResRendererCommandBuffer != null) { targetCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, quarterResRendererCommandBuffer); quarterResRendererCommandBuffer = null; } renderingEnabled = true; if (downscaledDepthRenderTexture) downscaledDepthRenderTexture.Release(); if (downscaledRenderTexture0) downscaledRenderTexture0.Release(); if (downscaledRenderTexture1) downscaledRenderTexture1.Release(); } } } public class ScreenSpaceScatteringContainer : GenericLocalAtmosphereContainer { ScreenSpaceScattering screenSpaceScattering; public ScreenSpaceScatteringContainer (Material atmosphereMaterial, Transform parentTransform, float Rt, ProlandManager parentManager, bool quarterRes) : base (atmosphereMaterial, parentTransform, Rt, parentManager) { scatteringGO = GameObject.CreatePrimitive(PrimitiveType.Quad); scatteringGO.name = "Scatterer screenspace scattering " + parentManager.parentCelestialBody.name; GameObject.Destroy (scatteringGO.GetComponent ()); scatteringGO.transform.localScale = Vector3.one; //for now just disable this from reflection probe because no idea how to add the effect on it, no access to depth buffer and I don't feel like the perf hit would be worth to enable it //this will be handled by the ocean if it is present //TODO: remove this after finalizing 1/4 res since now we just use commandbuffer if (!manager.hasOcean || !Scatterer.Instance.mainSettings.useOceanShaders) { DisableEffectsChecker disableEffectsChecker = scatteringGO.AddComponent (); disableEffectsChecker.manager = this.manager; } screenSpaceScattering = scatteringGO.AddComponent(); scatteringGO.transform.position = parentTransform.position; scatteringGO.transform.parent = parentTransform; screenSpaceScattering.material = atmosphereMaterial; screenSpaceScattering.material.CopyKeywordsFrom (atmosphereMaterial); screenSpaceScattering.hasOcean = manager.hasOcean && Scatterer.Instance.mainSettings.useOceanShaders; screenSpaceScattering.Init(quarterRes); } public override void UpdateContainer () { bool isEnabled = !underwater && !inScaledSpace && activated; screenSpaceScattering.SetActive(isEnabled); scatteringGO.SetActive(isEnabled); } public override void Cleanup () { SetActivated (false); if(scatteringGO) { if(scatteringGO.transform && scatteringGO.transform.parent) { scatteringGO.transform.parent = null; } Component.DestroyImmediate(screenSpaceScattering); GameObject.DestroyImmediate(scatteringGO); } } } } ================================================ FILE: scatterer/Effects/Proland/Atmosphere/Utils/SkySphereContainer.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Scatterer { public class SkySphereContainer { GameObject skySphereGO; MeshRenderer skySphereMR; public GameObject GameObject { get { return skySphereGO; } } public MeshRenderer MeshRenderer { get { return skySphereMR; } } Transform parentLocalTransform, parentScaledTransform; MeshFilter skySphereMF; public SkySphereContainer(float size, Material material, Transform inParentLocalTransform, Transform inParentScaledTransform) { skySphereGO = GameObject.CreatePrimitive(PrimitiveType.Sphere); GameObject.Destroy (skySphereGO.GetComponent ()); skySphereGO.transform.localScale = Vector3.one; skySphereMF = skySphereGO.GetComponent(); Vector3[] verts = skySphereMF.mesh.vertices; for (int i = 0; i < verts.Length; i++) { verts[i] = verts[i].normalized * size; } skySphereMF.mesh.vertices = verts; skySphereMF.mesh.RecalculateBounds(); skySphereMF.mesh.RecalculateNormals(); skySphereMR = skySphereGO.GetComponent(); skySphereMR.sharedMaterial = material; Utils.EnableOrDisableShaderKeywords (skySphereMR.sharedMaterial, "LOCAL_SKY_ON", "LOCAL_SKY_OFF", false); skySphereMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; skySphereMR.receiveShadows = false; skySphereMR.motionVectorGenerationMode = MotionVectorGenerationMode.Camera; skySphereMR.enabled = true; if (HighLogic.LoadedScene == GameScenes.MAINMENU) skySphereGO.layer = 15; else skySphereGO.layer = 9; skySphereGO.transform.position = inParentScaledTransform.position; skySphereGO.transform.parent = inParentScaledTransform; parentScaledTransform = inParentScaledTransform; parentLocalTransform = inParentLocalTransform; } public void SwitchLocalMode() { skySphereGO.layer = 15; skySphereGO.transform.parent = null; skySphereGO.transform.position = parentLocalTransform.position; skySphereGO.transform.localScale = new Vector3(ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor); skySphereGO.transform.parent = parentLocalTransform; Utils.EnableOrDisableShaderKeywords (skySphereMR.sharedMaterial, "LOCAL_SKY_ON", "LOCAL_SKY_OFF", true); skySphereGO.AddComponent ().Init(skySphereMR.sharedMaterial); } public void SwitchScaledMode() { skySphereGO.layer = 9; skySphereGO.transform.parent = null; skySphereGO.transform.position = parentScaledTransform.position; skySphereGO.transform.localScale = Vector3.one; skySphereGO.transform.parent = parentScaledTransform; Utils.EnableOrDisableShaderKeywords (skySphereMR.sharedMaterial, "LOCAL_SKY_ON", "LOCAL_SKY_OFF", false); var scrCopy = skySphereGO.GetComponent (); if (scrCopy) UnityEngine.Component.DestroyImmediate (scrCopy); } public void Resize(float size) { Vector3[] verts = skySphereMF.mesh.vertices; for (int i = 0; i < verts.Length; i++) { verts[i] = verts[i].normalized * size; } skySphereMF.mesh.vertices = verts; skySphereMF.mesh.RecalculateBounds(); skySphereMF.mesh.RecalculateNormals(); } public void Cleanup() { if (skySphereMR != null) { skySphereMR.enabled = false; UnityEngine.Component.DestroyImmediate (skySphereMR); } if (skySphereGO != null) { UnityEngine.Object.DestroyImmediate(skySphereGO); } } } public class SkySphereScreenCopy : MonoBehaviour { Material material; public void Init(Material material) { this.material = material; } void OnWillRenderObject() { Camera cam = Camera.current; if (!cam) return; if (cam == Scatterer.Instance.nearCamera && !Scatterer.Instance.unifiedCameraMode) { material.SetFloat(ShaderProperties.renderSkyOnCurrentCamera_PROPERTY, 0f); } else { material.SetFloat(ShaderProperties.renderSkyOnCurrentCamera_PROPERTY, 1f); } ScreenCopyCommandBuffer.EnableScreenCopyForFrame (cam); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Caustics/CausticsLightRaysRenderer.cs ================================================ using UnityEngine; using UnityEngine.Rendering; using System.Collections.Generic; using System; namespace Scatterer { // First class inits the material and OnWillRender adds a script to relevant cameras, the given script adds and removes commandbuffers before and after rendering? yes, also enables only OnWillRender and if underwater public class CausticsLightRaysRenderer : MonoBehaviour { public Material CausticsLightRaysMaterial; Texture2D causticsTexture; public bool isEnabled = false; public bool commandBufferAdded = false; public OceanNode oceanNode; private Dictionary CameraToLightRaysScript = new Dictionary(); public CausticsLightRaysRenderer () { } //Todo refactor and make caustics class which handles the common code of lightrays and shadowmask? public bool Init(string causticsTexturePath,Vector2 causticsLayer1Scale,Vector2 causticsLayer1Speed,Vector2 causticsLayer2Scale, Vector2 causticsLayer2Speed, float causticsMultiply, float causticsMinBrightness, float oceanRadius, float blurDepth, OceanNode oceanNodeIn, float lightRaysStrength) { if (string.IsNullOrEmpty (causticsTexturePath) || !System.IO.File.Exists (Utils.GameDataPath+causticsTexturePath)) { Utils.LogInfo("Caustics texture "+ Utils.GameDataPath+causticsTexturePath +" not found, disabling caustics light rays for current planet"); return false; } else { if (CausticsLightRaysMaterial == null) { CausticsLightRaysMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/CausticsGodraysRaymarch")]); } causticsTexture = new Texture2D (1, 1); causticsTexture.LoadImage (System.IO.File.ReadAllBytes (Utils.GameDataPath+causticsTexturePath)); causticsTexture.wrapMode = TextureWrapMode.Repeat; CausticsLightRaysMaterial.SetTexture ("_CausticsTexture", causticsTexture); CausticsLightRaysMaterial.SetVector ("layer1Scale", causticsLayer1Scale); CausticsLightRaysMaterial.SetVector ("layer1Speed", causticsLayer1Speed); CausticsLightRaysMaterial.SetVector ("layer2Scale", causticsLayer2Scale); CausticsLightRaysMaterial.SetVector ("layer2Speed", causticsLayer2Speed); CausticsLightRaysMaterial.SetFloat ("causticsMultiply", causticsMultiply); CausticsLightRaysMaterial.SetFloat ("causticsMinBrightness", causticsMinBrightness); CausticsLightRaysMaterial.SetFloat ("oceanRadius", oceanRadius); CausticsLightRaysMaterial.SetFloat ("causticsBlurDepth", blurDepth); CausticsLightRaysMaterial.SetFloat ("transparencyDepth", oceanNodeIn.transparencyDepth); CausticsLightRaysMaterial.SetFloat ("lightRaysStrength", lightRaysStrength); CausticsLightRaysMaterial.EnableKeyword ("SPHERE_PLANET"); CausticsLightRaysMaterial.DisableKeyword ("FLAT_PLANET"); //for testing in unity editor only, obviously, Kerbin is not flat I swear oceanNode = oceanNodeIn; isEnabled = true; return true; } } public void OnWillRenderObject() { if (isEnabled && oceanNode.isUnderwater) { Camera cam = Camera.current; if (!cam || MapView.MapIsEnabled || oceanNode.prolandManager.skyNode.inScaledSpace) return; if (!CameraToLightRaysScript.ContainsKey (cam)) { if ((cam.name == "Reflection Probes Camera") || (cam.name == "ScattererPartialDepthBuffer")) { //we add it anyway to avoid doing a string compare CameraToLightRaysScript [cam] = null; } else { CameraToLightRaysScript [cam] = (CausticsLightRaysCameraScript)cam.gameObject.AddComponent (typeof(CausticsLightRaysCameraScript)); CameraToLightRaysScript [cam].CausticsLightRaysMaterial = CausticsLightRaysMaterial; CameraToLightRaysScript [cam].Init (oceanNode); } } else { if (CameraToLightRaysScript [cam] != null) { CameraToLightRaysScript [cam].EnableForThisFrame (); } } } } public void OnDestroy () { foreach (CausticsLightRaysCameraScript script in CameraToLightRaysScript.Values) { if (script != null) { script.CleanUp(); Component.Destroy(script); } } } } public class CausticsLightRaysCameraScript : MonoBehaviour { public Material CausticsLightRaysMaterial, compositeLightRaysMaterial; CommandBuffer commandBuffer; Camera targetCamera; private RenderTexture targetRT, targetRT2; private RenderTexture downscaledDepthRT; private Material downscaleDepthMaterial; bool isInitialized = false; bool renderingEnabled = false; Light targetLight; private OceanNode oceanNode; public CausticsLightRaysCameraScript () { } public void Init(OceanNode oceanNodeIn) { targetCamera = GetComponent(); if (targetCamera.targetTexture) { targetRT = new RenderTexture (targetCamera.targetTexture.width / 4, targetCamera.targetTexture.height / 4, 0, RenderTextureFormat.R8); } else { targetRT = new RenderTexture (Screen.width / 4, Screen.height / 4, 0, RenderTextureFormat.R8); } targetRT.anisoLevel = 1; targetRT.antiAliasing = 1; targetRT.volumeDepth = 0; targetRT.useMipMap = true; targetRT.autoGenerateMips = false; targetRT.filterMode = FilterMode.Bilinear; targetRT.Create(); targetRT2 = new RenderTexture (targetRT.width, targetRT.height, 0, RenderTextureFormat.R8); targetRT2.anisoLevel = 1; targetRT2.antiAliasing = 1; targetRT2.volumeDepth = 0; targetRT2.useMipMap = true; targetRT2.autoGenerateMips = false; targetRT2.filterMode = FilterMode.Bilinear; targetRT2.Create(); downscaledDepthRT = new RenderTexture(targetRT.width, targetRT.height, 0, RenderTextureFormat.RFloat); downscaledDepthRT.anisoLevel = 1; downscaledDepthRT.antiAliasing = 1; downscaledDepthRT.volumeDepth = 0; downscaledDepthRT.useMipMap = false; downscaledDepthRT.autoGenerateMips = false; downscaledDepthRT.filterMode = FilterMode.Point; downscaledDepthRT.Create(); downscaleDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders [("Scatterer/DownscaleDepth")]); compositeLightRaysMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/CompositeCausticsGodrays")]); compositeLightRaysMaterial.SetTexture ("LightRaysTexture", targetRT); compositeLightRaysMaterial.SetColor(ShaderProperties._sunColor_PROPERTY, oceanNodeIn.prolandManager.getIntensityModulatedSunColor()); compositeLightRaysMaterial.SetVector ("_Underwater_Color", oceanNodeIn.m_UnderwaterColor); commandBuffer = new CommandBuffer(); commandBuffer.name = "Scatterer caustics renderer CommandBuffer"; //downscale depth to 1/16 commandBuffer.Blit(null, downscaledDepthRT, downscaleDepthMaterial, 0); commandBuffer.SetGlobalTexture("ScattererDownscaledDepth", downscaledDepthRT); //render commandBuffer.Blit(null, targetRT, CausticsLightRaysMaterial); //bilateral blur, 2 taps seems enough commandBuffer.SetGlobalVector ("BlurDir", new Vector2(0,1)); commandBuffer.SetGlobalTexture ("TextureToBlur", targetRT); commandBuffer.Blit(null, targetRT2, downscaleDepthMaterial, 2); commandBuffer.SetGlobalVector ("BlurDir", new Vector2(1,0)); commandBuffer.SetGlobalTexture ("TextureToBlur", targetRT2); commandBuffer.Blit(null, targetRT, downscaleDepthMaterial, 2); //copy to screen commandBuffer.Blit(null, BuiltinRenderTextureType.CameraTarget, compositeLightRaysMaterial); targetLight = oceanNodeIn.prolandManager.mainSunLight; oceanNode = oceanNodeIn; isInitialized = true; } public void EnableForThisFrame() { if (isInitialized) { targetCamera.AddCommandBuffer(CameraEvent.AfterForwardAlpha, commandBuffer); //TODO: move this out of here float warpTime = (TimeWarp.CurrentRate > 1) ? (float) Planetarium.GetUniversalTime() : 0f; CausticsLightRaysMaterial.SetFloat (ShaderProperties.warpTime_PROPERTY, warpTime); // If we use sunlightExtinction, reuse already computed extinction color if (Scatterer.Instance.mainSettings.sunlightExtinction) { compositeLightRaysMaterial.SetColor(ShaderProperties._sunColor_PROPERTY, oceanNode.prolandManager.getIntensityModulatedSunColor() * Scatterer.Instance.sunlightModulatorsManagerInstance.GetLastModulateColor(targetLight)); } renderingEnabled = true; } } public void OnPostRender() { if (renderingEnabled && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left) { targetCamera.RemoveCommandBuffer(CameraEvent.AfterForwardAlpha, commandBuffer); renderingEnabled = false; } } public void CleanUp() { renderingEnabled = false; if (commandBuffer != null) { if (targetCamera) { targetCamera.RemoveCommandBuffer (CameraEvent.AfterForwardAlpha, commandBuffer); } commandBuffer.Dispose (); } targetRT.Release (); targetRT2.Release (); downscaledDepthRT.Release (); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Caustics/CausticsShadowMaskModulate.cs ================================================ // after light's screenspace shadow mask is computed, apply caustics to it using UnityEngine; using UnityEngine.Rendering; using System.Collections.Generic; using System; namespace Scatterer { //transform this to general caustics class, pass to it the light and once of the ocean's meshrenderers? //how to handle the lightrays? do we need to render a quad to screen? do we set it as texture which the underwaterProjector reads from? public class CausticsShadowMaskModulate : MonoBehaviour { private CommandBuffer m_Buffer; private Light sunLight; public Material CausticsShadowMaskModulateMaterial; Texture2D causticsTexture; public bool isEnabled = false; public bool commandBufferAdded = false; public CausticsShadowMaskModulate () { } public bool Init(string causticsTexturePath,Vector2 causticsLayer1Scale,Vector2 causticsLayer1Speed,Vector2 causticsLayer2Scale, Vector2 causticsLayer2Speed, float causticsMultiply, float causticsMinBrightness, float oceanRadius, float blurDepth, Light inputSunlight) { if (string.IsNullOrEmpty (causticsTexturePath) || !System.IO.File.Exists (Utils.GameDataPath+causticsTexturePath)) { Utils.LogInfo("Caustics texture "+ Utils.GameDataPath+causticsTexturePath +" not found, disabling caustics for current planet"); return false; } else { if (!CausticsShadowMaskModulateMaterial) { CausticsShadowMaskModulateMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/CausticsOcclusion")]); } causticsTexture = new Texture2D (1, 1); causticsTexture.LoadImage (System.IO.File.ReadAllBytes (Utils.GameDataPath+causticsTexturePath)); causticsTexture.wrapMode = TextureWrapMode.Repeat; CausticsShadowMaskModulateMaterial.SetTexture ("_CausticsTexture", causticsTexture); CausticsShadowMaskModulateMaterial.SetVector ("layer1Scale", causticsLayer1Scale); CausticsShadowMaskModulateMaterial.SetVector ("layer1Speed", causticsLayer1Speed); CausticsShadowMaskModulateMaterial.SetVector ("layer2Scale", causticsLayer2Scale); CausticsShadowMaskModulateMaterial.SetVector ("layer2Speed", causticsLayer2Speed); CausticsShadowMaskModulateMaterial.SetFloat ("causticsMultiply", causticsMultiply); CausticsShadowMaskModulateMaterial.SetFloat ("causticsMinBrightness", causticsMinBrightness); CausticsShadowMaskModulateMaterial.SetFloat ("oceanRadius", oceanRadius); CausticsShadowMaskModulateMaterial.SetFloat ("causticsBlurDepth", blurDepth); CausticsShadowMaskModulateMaterial.EnableKeyword ("SPHERE_PLANET"); CausticsShadowMaskModulateMaterial.DisableKeyword ("FLAT_PLANET"); //for testing in unity editor only, obviously, Kerbin is not flat I swear sunLight = inputSunlight; m_Buffer = new CommandBuffer (); m_Buffer.name = "Scatterer caustics shadowMask modulate CommandBuffer"; m_Buffer.Blit (null, BuiltinRenderTextureType.CurrentActive, CausticsShadowMaskModulateMaterial); AddCommandBuffer (); isEnabled = true; return true; } } public void AddCommandBuffer() { sunLight.AddCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer); commandBufferAdded = true; } public void UpdateCaustics() { if (isEnabled) { float warpTime = (TimeWarp.CurrentRate > 1) ? (float) Planetarium.GetUniversalTime() : 0f; CausticsShadowMaskModulateMaterial.SetFloat (ShaderProperties.warpTime_PROPERTY, warpTime); } if (commandBufferAdded && !isEnabled) { RemoveCommandBuffer(); } else if (!commandBufferAdded && isEnabled) { AddCommandBuffer(); } } public void RemoveCommandBuffer () { if (sunLight) sunLight.RemoveCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer); commandBufferAdded = false; } public void OnDestroy () { RemoveCommandBuffer (); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/FourierCPU.cs ================================================ using UnityEngine; using System.Collections; namespace Scatterer { public class FourierCPU { int m_size; float m_fsize; int m_passes; public float[] m_butterflyLookupTable = null; public FourierCPU(int size) { if (!Mathf.IsPowerOfTwo(size)) { Utils.LogDebug("Fourier grid size must be pow2 number, changing to nearest pow2 number"); size = Mathf.NextPowerOfTwo(size); } m_size = size; //must be pow2 num m_fsize = (float)m_size; m_passes = (int)(Mathf.Log(m_fsize) / Mathf.Log(2.0f)); } //Performs two FFTs on two complex numbers packed in a vector4 Vector4 FFT(Vector2 w, Vector4 input1, Vector4 input2) { input1.x += w.x * input2.x - w.y * input2.y; input1.y += w.y * input2.x + w.x * input2.y; input1.z += w.x * input2.z - w.y * input2.w; input1.w += w.y * input2.z + w.x * input2.w; return input1; } //Performs one FFT on a complex number Vector2 FFT(Vector2 w, Vector2 input1, Vector2 input2) { input1.x += w.x * input2.x - w.y * input2.y; input1.y += w.y * input2.x + w.x * input2.y; return input1; } public int PeformFFT(int startIdx, Vector4[,] data0, Vector4[,] data1, Vector4[,] data2) { int x; int y; int i; int idx = 0; int idx1; int bftIdx; int X; int Y; Vector2 w; int j = startIdx; for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; for (x = 0; x < m_size; x++) { for (y = 0; y < m_size; y++) { bftIdx = 4 * (x + i * m_size); X = (int)m_butterflyLookupTable[bftIdx + 0]; Y = (int)m_butterflyLookupTable[bftIdx + 1]; w.x = m_butterflyLookupTable[bftIdx + 2]; w.y = m_butterflyLookupTable[bftIdx + 3]; data0[idx, x + y * m_size] = FFT(w, data0[idx1, X + y * m_size], data0[idx1, Y + y * m_size]); data1[idx, x + y * m_size] = FFT(w, data1[idx1, X + y * m_size], data1[idx1, Y + y * m_size]); data2[idx, x + y * m_size] = FFT(w, data2[idx1, X + y * m_size], data2[idx1, Y + y * m_size]); } } } for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; for (x = 0; x < m_size; x++) { for (y = 0; y < m_size; y++) { bftIdx = 4 * (y + i * m_size); X = (int)m_butterflyLookupTable[bftIdx + 0]; Y = (int)m_butterflyLookupTable[bftIdx + 1]; w.x = m_butterflyLookupTable[bftIdx + 2]; w.y = m_butterflyLookupTable[bftIdx + 3]; data0[idx, x + y * m_size] = FFT(w, data0[idx1, x + X * m_size], data0[idx1, x + Y * m_size]); data1[idx, x + y * m_size] = FFT(w, data1[idx1, x + X * m_size], data1[idx1, x + Y * m_size]); data2[idx, x + y * m_size] = FFT(w, data2[idx1, x + X * m_size], data2[idx1, x + Y * m_size]); } } } return idx; } public int PeformFFT(int startIdx, Vector4[,] data0, Vector4[,] data1) { int x; int y; int i; int idx = 0; int idx1; int bftIdx; int X; int Y; Vector2 w; int j = startIdx; for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; for (x = 0; x < m_size; x++) { for (y = 0; y < m_size; y++) { bftIdx = 4 * (x + i * m_size); X = (int)m_butterflyLookupTable[bftIdx + 0]; Y = (int)m_butterflyLookupTable[bftIdx + 1]; w.x = m_butterflyLookupTable[bftIdx + 2]; w.y = m_butterflyLookupTable[bftIdx + 3]; data0[idx, x + y * m_size] = FFT(w, data0[idx1, X + y * m_size], data0[idx1, Y + y * m_size]); data1[idx, x + y * m_size] = FFT(w, data1[idx1, X + y * m_size], data1[idx1, Y + y * m_size]); } } } for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; for (x = 0; x < m_size; x++) { for (y = 0; y < m_size; y++) { bftIdx = 4 * (y + i * m_size); X = (int)m_butterflyLookupTable[bftIdx + 0]; Y = (int)m_butterflyLookupTable[bftIdx + 1]; w.x = m_butterflyLookupTable[bftIdx + 2]; w.y = m_butterflyLookupTable[bftIdx + 3]; data0[idx, x + y * m_size] = FFT(w, data0[idx1, x + X * m_size], data0[idx1, x + Y * m_size]); data1[idx, x + y * m_size] = FFT(w, data1[idx1, x + X * m_size], data1[idx1, x + Y * m_size]); } } } return idx; } public int PeformFFT(int startIdx, Vector4[,] data0) { int x; int y; int i; int idx = 0; int idx1; int bftIdx; int X; int Y; Vector2 w; int j = startIdx; for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; for (x = 0; x < m_size; x++) { for (y = 0; y < m_size; y++) { bftIdx = 4 * (x + i * m_size); X = (int)m_butterflyLookupTable[bftIdx + 0]; Y = (int)m_butterflyLookupTable[bftIdx + 1]; w.x = m_butterflyLookupTable[bftIdx + 2]; w.y = m_butterflyLookupTable[bftIdx + 3]; data0[idx, x + y * m_size] = FFT(w, data0[idx1, X + y * m_size], data0[idx1, Y + y * m_size]); } } } for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; for (x = 0; x < m_size; x++) { for (y = 0; y < m_size; y++) { bftIdx = 4 * (y + i * m_size); X = (int)m_butterflyLookupTable[bftIdx + 0]; Y = (int)m_butterflyLookupTable[bftIdx + 1]; w.x = m_butterflyLookupTable[bftIdx + 2]; w.y = m_butterflyLookupTable[bftIdx + 3]; data0[idx, x + y * m_size] = FFT(w, data0[idx1, x + X * m_size], data0[idx1, x + Y * m_size]); } } } return idx; } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/FourierGPU.cs ================================================ using UnityEngine; using System.Collections; namespace Scatterer { public class FourierGPU { const int PASS_X_1 = 0, PASS_Y_1 = 1; const int PASS_X_2 = 2, PASS_Y_2 = 3; const int PASS_X_3 = 4, PASS_Y_3 = 5; int m_size; float m_fsize; int m_passes; Texture2D[] m_butterflyLookupTable = null; Material m_fourier; public FourierGPU(int size) { if(size > 256) { Utils.LogDebug("FourierGPU::FourierGPU - fourier grid size must not be greater than 256, changing to 256"); size = 256; } if(!Mathf.IsPowerOfTwo(size)) { Utils.LogDebug("FourierGPU::FourierGPU - fourier grid size must be pow2 number, changing to nearest pow2 number"); size = Mathf.NextPowerOfTwo(size); } Shader shader = ShaderReplacer.Instance.LoadedShaders[("Scatterer/Fourier")]; if(shader == null) Utils.LogDebug("FourierGPU::FourierGPU - Could not find shader Math/Fourier"); m_fourier = new Material(shader); m_size = size; //must be pow2 num m_fsize = (float)m_size; m_passes = (int)(Mathf.Log(m_fsize)/Mathf.Log(2.0f)); m_butterflyLookupTable = new Texture2D[m_passes]; ComputeButterflyLookupTable(); m_fourier.SetFloat("_Size", m_fsize); } int BitReverse(int i) { int j = i; int Sum = 0; int W = 1; int M = m_size / 2; while(M != 0) { j = ((i&M) > M-1) ? 1 : 0; Sum += j * W; W *= 2; M /= 2; } return Sum; } Texture2D Make1DTex(int i) { Texture2D tex = new Texture2D(m_size, 1, TextureFormat.ARGB32, false, true); tex.filterMode = FilterMode.Point; tex.wrapMode = TextureWrapMode.Clamp; return tex; } void ComputeButterflyLookupTable() { for(int i = 0; i < m_passes; i++) { int nBlocks = (int) Mathf.Pow(2, m_passes - 1 - i); int nHInputs = (int) Mathf.Pow(2, i); m_butterflyLookupTable[i] = Make1DTex(i); for (int j = 0; j < nBlocks; j++) { for (int k = 0; k < nHInputs; k++) { int i1, i2, j1, j2; if (i == 0) { i1 = j * nHInputs * 2 + k; i2 = j * nHInputs * 2 + nHInputs + k; j1 = BitReverse(i1); j2 = BitReverse(i2); } else { i1 = j * nHInputs * 2 + k; i2 = j * nHInputs * 2 + nHInputs + k; j1 = i1; j2 = i2; } m_butterflyLookupTable[i].SetPixel(i1, 0, new Color( (float)j1 / 255.0f, (float)j2 / 255.0f, (float)(k*nBlocks) / 255.0f, 0)); m_butterflyLookupTable[i].SetPixel(i2, 0, new Color( (float)j1 / 255.0f, (float)j2 / 255.0f, (float)(k*nBlocks) / 255.0f, 1)); } } m_butterflyLookupTable[i].Apply(); } } public int PeformFFT(RenderTexture[] data0, RenderTexture[] data1) { RenderTexture[] pass0 = new RenderTexture[]{ data0[0], data1[0] }; RenderTexture[] pass1 = new RenderTexture[]{ data0[1], data1[1] }; int i; int idx = 0; int idx1; int j = 0; for(i = 0; i < m_passes; i++, j++) { idx = j%2; idx1 = (j+1)%2; m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]); m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]); m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]); if(idx == 0) RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_X_2); else RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_X_2); } for(i = 0; i < m_passes; i++, j++) { idx = j%2; idx1 = (j+1)%2; m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]); m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]); m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]); if(idx == 0) RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_Y_2); else RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_Y_2); } return idx; } public int PeformFFT(RenderTexture[] data0, RenderTexture[] data1, RenderTexture[] data2) { RenderTexture[] pass0 = new RenderTexture[]{ data0[0], data1[0], data2[0] }; RenderTexture[] pass1 = new RenderTexture[]{ data0[1], data1[1], data2[1] }; int i; int idx = 0; int idx1; int j = 0; for(i = 0; i < m_passes; i++, j++) { idx = j%2; idx1 = (j+1)%2; m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]); m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]); m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]); m_fourier.SetTexture("_ReadBuffer2", data2[idx1]); if(idx == 0) RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_X_3); else RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_X_3); } for(i = 0; i < m_passes; i++, j++) { idx = j%2; idx1 = (j+1)%2; m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]); m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]); m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]); m_fourier.SetTexture("_ReadBuffer2", data2[idx1]); if(idx == 0) RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_Y_3); else RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_Y_3); } return idx; } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/GPUWaveInteractionHandler.cs ================================================ using UnityEngine; using System.Collections.Generic; using System.Reflection; using UnityEngine.Rendering; namespace Scatterer { public class GPUWaveInteractionHandler { private ComputeShader findHeightsShader; private List partsBuoyancies = new List(); private bool heightsRequestInProgress = false; private bool cameraHeightRequested = false; private float[] heights = { }; private ComputeBuffer positionsBuffer, heightsBuffer; private int frameLatencyCounter = 1; private bool paused = false; private KSP.UI.Screens.AltimeterSliderButtons altimeterRecoveryButton; private bool altimeterRecoveryButtonOverriden = false; private MethodInfo recoveryButtonSetUnlockMethod; private object[] setUnlockParametersArray; private float maxWaveInteractionShipAltitude = 500.0f; private bool isHomeworld = false; public GPUWaveInteractionHandler(float inMaxWaveInteractionShipAltitude, bool inIsHomeworld) { maxWaveInteractionShipAltitude = inMaxWaveInteractionShipAltitude; isHomeworld = inIsHomeworld; findHeightsShader = ShaderReplacer.Instance.LoadedComputeShaders["FindHeights"]; if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance) { PhysicsGlobals.BuoyancyCrashToleranceMult = Scatterer.Instance.mainSettings.buoyancyCrashToleranceMultOverride; } if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag) { PhysicsGlobals.BuoyancyWaterDragTimer = double.NegativeInfinity; // this is needed to avoid the excessive drag that is applied when first hitting the water and which basically kills seaplanes with the smallest waves } if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity) { GameEvents.onGamePause.Add(ForcePauseMenuSaving); GameEvents.onGameUnpause.Add(UnPause); if (inIsHomeworld) { KSP.UI.Screens.AltimeterSliderButtons[] sliderButtons = Resources.FindObjectsOfTypeAll(); if (sliderButtons.Length > 0) { altimeterRecoveryButton = sliderButtons[0]; BindingFlags Flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; recoveryButtonSetUnlockMethod = altimeterRecoveryButton.GetType().GetMethod("setUnlock", Flags); if (recoveryButtonSetUnlockMethod == null) { Utils.LogError("No setUnlock method found in AltimeterSliderButtons"); altimeterRecoveryButton = null; return; } setUnlockParametersArray = new object[] { 2 }; //The state for unlocking the altimeterSliderButtons } } } } public void SetMaterialProperties(Vector4 choppyness, Vector4 gridSizes, RenderTexture map0, RenderTexture map3, RenderTexture map4) { findHeightsShader.SetVector(ShaderProperties._Ocean_Choppyness_PROPERTY, choppyness); findHeightsShader.SetVector(ShaderProperties._Ocean_GridSizes_PROPERTY, gridSizes); findHeightsShader.SetTexture(0, ShaderProperties._Ocean_Map0_PROPERTY, map0); findHeightsShader.SetTexture(0, ShaderProperties._Ocean_Map3_PROPERTY, map3); findHeightsShader.SetTexture(0, ShaderProperties._Ocean_Map4_PROPERTY, map4); } public float UpdateInteractions(double cameraHeight, float waterHeightAtCameraPosition, Vector3 ux, Vector3 uy, Vector3 offsetVector3) { UpdateRecoveryButton(); return UpdateHeights(cameraHeight, waterHeightAtCameraPosition, ux, uy, offsetVector3); } private float UpdateHeights(double cameraHeight, float waterHeightAtCameraPosition, Vector3 ux, Vector3 uy, Vector3 offsetVector3) { if (!heightsRequestInProgress) { waterHeightAtCameraPosition = ApplyWaterLevelHeights(waterHeightAtCameraPosition); List positionsList = new List(); BuildPartsPositionsList(positionsList, partsBuoyancies, ux, uy, offsetVector3); AddCameraPosition(positionsList, cameraHeight, new Vector2(offsetVector3.x, offsetVector3.y)); RequestAsyncWaterLevelHeights(positionsList); } else { frameLatencyCounter++; } return waterHeightAtCameraPosition; } private void UpdateRecoveryButton() { if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity && !paused && FlightGlobals.ActiveVessel != null) { if ((altimeterRecoveryButton != null) && (FlightGlobals.ActiveVessel.altitude <= Mathf.Abs(maxWaveInteractionShipAltitude)) && (FlightGlobals.ActiveVessel.IsClearToSave() == ClearToSaveStatus.CLEAR) && (FlightGlobals.ActiveVessel.situation == Vessel.Situations.SPLASHED) && (FlightGlobals.ActiveVessel.srf_velocity.sqrMagnitude < Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity * Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity)) { FlightGlobals.ActiveVessel.srf_velocity = Vector3d.zero; if (!altimeterRecoveryButton.led.IsOn || (altimeterRecoveryButton.led.color != KSP.UI.Screens.LED.colorIndices.green)) { recoveryButtonSetUnlockMethod.Invoke(altimeterRecoveryButton, setUnlockParametersArray); altimeterRecoveryButton.StopAllCoroutines(); altimeterRecoveryButtonOverriden = true; } } else if (altimeterRecoveryButtonOverriden) { altimeterRecoveryButton.StartCoroutine("UnlockRecovery", FlightGlobals.ActiveVessel); altimeterRecoveryButton.StartCoroutine("UnlockReturnToKSC", FlightGlobals.ActiveVessel); altimeterRecoveryButtonOverriden = false; } } } void BuildPartsPositionsList(List positionsList, List partsBuoyanciesList, Vector3 ux, Vector3 uy, Vector3 offsetVector3) { foreach (Vessel vessel in FlightGlobals.VesselsLoaded) { if (vessel.altitude <= Mathf.Abs(maxWaveInteractionShipAltitude)) { foreach (Part part in vessel.parts) { if (part.partBuoyancy) { //To be more accurate I'd need to take ceter of buoyancy and transform it to worldPos but that would add a matrix multiply for every part, which I'm not about to do Vector3 relativePartPos = part.transform.position - Scatterer.Instance.nearCamera.transform.position; Vector2 oceanPos = new Vector2(Vector3.Dot(relativePartPos, ux) + offsetVector3.x, Vector3.Dot(relativePartPos, uy) + offsetVector3.y); positionsList.Add(oceanPos); partsBuoyanciesList.Add(part.partBuoyancy); } } } } } void AddCameraPosition(List positionsList, double cameraHeight, Vector2 cameraOceanPosition) { if (cameraHeight <= Mathf.Abs(maxWaveInteractionShipAltitude)) { positionsList.Add(cameraOceanPosition); cameraHeightRequested = true; } } float ApplyWaterLevelHeights(float waterHeightAtCameraPosition) { //partBuoyancy has no way to override the force direction (it uses -g direction directly) however, maybe do a parent addforce at position with the buoyancy effective position with the normal? will always be hacky probably if (cameraHeightRequested) { waterHeightAtCameraPosition = heights[heights.Length - 1]; } if (partsBuoyancies!=null) { for (int i = 0; i < partsBuoyancies.Count; i++) { if (partsBuoyancies[i] != null) { partsBuoyancies[i].waterLevel = heights[i]; if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag) { partsBuoyancies[i].wasSplashed = true; // changing these is also need so the game doesn't apply excessive drag on splashes which makes seaplanes unusable partsBuoyancies[i].splashed = true; } } } } partsBuoyancies.Clear(); cameraHeightRequested = false; return waterHeightAtCameraPosition; } void RequestAsyncWaterLevelHeights(List positionsList) { int size = positionsList.Count; if (size > 0) { positionsBuffer = new ComputeBuffer(size, 2 * sizeof(float)); positionsBuffer.SetData(positionsList); findHeightsShader.SetBuffer(0, "positions", positionsBuffer); heightsBuffer = new ComputeBuffer(size, sizeof(float)); findHeightsShader.SetBuffer(0, "result", heightsBuffer); findHeightsShader.Dispatch(0, size, 1, 1); //worry about figuring out threads and groups later AsyncGPUReadback.Request(heightsBuffer, OnCompletePartHeightsReadback); frameLatencyCounter = 1; heightsRequestInProgress = true; } } void OnCompletePartHeightsReadback(AsyncGPUReadbackRequest request) { if (request.hasError) { Utils.LogError("GPU readback error detected."); return; } heights = request.GetData().ToArray(); heightsRequestInProgress = false; positionsBuffer.Dispose(); heightsBuffer.Dispose(); } public void ForcePauseMenuSaving() { if (!paused && FlightGlobals.ActiveVessel != null && (FlightGlobals.ActiveVessel.altitude <= Mathf.Abs(maxWaveInteractionShipAltitude)) && (FlightGlobals.ActiveVessel.IsClearToSave() == ClearToSaveStatus.CLEAR) && (FlightGlobals.ActiveVessel.situation == Vessel.Situations.SPLASHED) && (FlightGlobals.ActiveVessel.srf_velocity.sqrMagnitude < Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity * Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity)) { Utils.LogInfo("Overriding pause menu recovery and save options"); paused = true; FlightGlobals.ActiveVessel.srf_velocity = Vector3d.zero; PauseMenu.Display(); } } public void UnPause() { paused = false; } public void Cleanup() { GameEvents.onGamePause.Remove(ForcePauseMenuSaving); GameEvents.onGameUnpause.Remove(UnPause); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/OceanCameraUpdateHook.cs ================================================ using UnityEngine; using System; namespace Scatterer { public class OceanCameraUpdateHook : MonoBehaviour { public OceanNode oceanNode; Matrix4x4 cameraToScreen,screenToCamera; Matrix4x4d m_oldlocalToOcean = Matrix4x4d.Identity (); // Whenever any camera will render us, call the method which updates the material with the right params public void OnWillRenderObject() { Camera cam = Camera.current; if (!cam || MapView.MapIsEnabled || !oceanNode.prolandManager.skyNode.simulateOceanInteraction) return; updateCameraSpecificUniforms (oceanNode.m_oceanMaterial, cam); if (Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions && (cam == Scatterer.Instance.farCamera || cam == Scatterer.Instance.nearCamera)) { if (Scatterer.Instance.unifiedCameraMode) { oceanNode.m_oceanMaterial.EnableKeyword("REFRACTIONS_AND_TRANSPARENCY_ON"); oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_MERGED_DEPTH"); } else { oceanNode.m_oceanMaterial.EnableKeyword("REFRACTIONS_AND_TRANSPARENCY_MERGED_DEPTH"); oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_ON"); } oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_OFF"); } else { oceanNode.m_oceanMaterial.EnableKeyword("REFRACTIONS_AND_TRANSPARENCY_OFF"); oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_ON"); oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_MERGED_DEPTH"); } } public void updateCameraSpecificUniforms (Material oceanMaterial, Camera inCamera) { cameraToScreen = GL.GetGPUProjectionMatrix (inCamera.projectionMatrix, false); screenToCamera = cameraToScreen.inverse; oceanNode.m_oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, cameraToScreen); oceanNode.m_oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, screenToCamera); //Calculates the required data for the projected grid // compute ltoo = localToOcean transform, where ocean frame = tangent space at // camera projection on sphere radius in local space //move these to dedicated projected grid class? Matrix4x4 ctol1 = inCamera.cameraToWorldMatrix; Matrix4x4d cameraToWorld = new Matrix4x4d (ctol1.m00, ctol1.m01, ctol1.m02, ctol1.m03, ctol1.m10, ctol1.m11, ctol1.m12, ctol1.m13, ctol1.m20, ctol1.m21, ctol1.m22, ctol1.m23, ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33); Vector3d translation; if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { translation = oceanNode.prolandManager.parentLocalTransform.position; //have to use this in space center or get the tsunami bug } else { translation = oceanNode.prolandManager.parentCelestialBody.position; //more precise, especially with RSS, but breaks a bit in KSC } Matrix4x4d worldToLocal = new Matrix4x4d(1, 0, 0, -translation.x, 0, 1, 0, -translation.y, 0, 0, 1, -translation.z, 0, 0, 0, 1); Matrix4x4d camToLocal = worldToLocal * cameraToWorld; Matrix4x4d localToCam = camToLocal.Inverse (); // camera in local space relative to planet's origin Vector3d2 cl = new Vector3d2 (); cl = camToLocal * Vector3d2.Zero (); double radius = oceanNode.prolandManager.GetRadius (); oceanNode.uz = cl.Normalized (); // unit z vector of ocean frame, in local space if (m_oldlocalToOcean != Matrix4x4d.Identity ()) { oceanNode.ux = (new Vector3d2 (m_oldlocalToOcean.m [1, 0], m_oldlocalToOcean.m [1, 1], m_oldlocalToOcean.m [1, 2])).Cross (oceanNode.uz).Normalized (); } else { oceanNode.ux = Vector3d2.UnitZ ().Cross (oceanNode.uz).Normalized (); } oceanNode.uy = oceanNode.uz.Cross (oceanNode.ux); // unit y vector //Wind moves in -Ux direction, which by default points north for some reason, can rotate it to any desired direction this way oceanNode.oo = oceanNode.uz * (radius); // origin of ocean frame, in local space //local to ocean transform //computed from oo and ux, uy, uz should be correct Matrix4x4d localToOcean = new Matrix4x4d ( oceanNode.ux.x, oceanNode.ux.y, oceanNode.ux.z, -oceanNode.ux.Dot (oceanNode.oo), oceanNode.uy.x, oceanNode.uy.y, oceanNode.uy.z, -oceanNode.uy.Dot (oceanNode.oo), oceanNode.uz.x, oceanNode.uz.y, oceanNode.uz.z, -oceanNode.uz.Dot (oceanNode.oo), 0.0, 0.0, 0.0, 1.0); Matrix4x4d cameraToOcean = localToOcean * camToLocal; Matrix4x4d worldToOcean = localToOcean * worldToLocal; Vector3d2 delta = new Vector3d2 (0, 0, 0); if (m_oldlocalToOcean != Matrix4x4d.Identity ()) { delta = localToOcean * (m_oldlocalToOcean.Inverse () * Vector3d2.Zero ()); oceanNode.m_Offset += delta; } //reset offset when bigger than 20000 to avoid floating point issues when later casting the offset to float if (Mathf.Max (Mathf.Abs ((float)oceanNode.m_Offset.x), Mathf.Abs ((float)oceanNode.m_Offset.y)) > 20000f) { oceanNode.m_Offset.x=0.0; oceanNode.m_Offset.y=0.0; } m_oldlocalToOcean = localToOcean; // Matrix4x4d ctos = ModifiedProjectionMatrix (inCamera); //moved to command buffer // Matrix4x4d stoc = ctos.Inverse (); Vector3d2 oc = cameraToOcean * Vector3d2.Zero (); oceanNode.height = oc.z; oceanNode.offset = new Vector3d2 (-oceanNode.m_Offset.x, -oceanNode.m_Offset.y, oceanNode.height); //old horizon code //This breaks down when you tilt the camera by 90 degrees in any direction //I made some new horizon code down, scroll down // Vector4d stoc_w = (stoc * Vector4d.UnitW ()).XYZ0 (); // Vector4d stoc_x = (stoc * Vector4d.UnitX ()).XYZ0 (); // Vector4d stoc_y = (stoc * Vector4d.UnitY ()).XYZ0 (); // // Vector3d2 A0 = (cameraToOcean * stoc_w).XYZ (); // Vector3d2 dA = (cameraToOcean * stoc_x).XYZ (); // Vector3d2 B = (cameraToOcean * stoc_y).XYZ (); // // Vector3d2 horizon1, horizon2; // // double h1 = h * (h + 2.0 * radius); // double h2 = (h + radius) * (h + radius); // double alpha = B.Dot (B) * h1 - B.z * B.z * h2; // // double beta0 = (A0.Dot (B) * h1 - B.z * A0.z * h2) / alpha; // double beta1 = (dA.Dot (B) * h1 - B.z * dA.z * h2) / alpha; // // double gamma0 = (A0.Dot (A0) * h1 - A0.z * A0.z * h2) / alpha; // double gamma1 = (A0.Dot (dA) * h1 - A0.z * dA.z * h2) / alpha; // double gamma2 = (dA.Dot (dA) * h1 - dA.z * dA.z * h2) / alpha; // // horizon1 = new Vector3d2 (-beta0, -beta1, 0.0); // horizon2 = new Vector3d2 (beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2); Vector3d2 sunDir = new Vector3d2 (oceanNode.prolandManager.getDirectionToMainSun ()); Vector3d2 oceanSunDir = localToOcean.ToMatrix3x3d () * sunDir; oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToWorld_PROPERTY, cameraToWorld .ToMatrix4x4()); oceanMaterial.SetVector (ShaderProperties._Ocean_SunDir_PROPERTY, oceanSunDir.ToVector3 ()); oceanMaterial.SetMatrix (ShaderProperties._Ocean_CameraToOcean_PROPERTY, cameraToOcean.ToMatrix4x4 ()); oceanMaterial.SetMatrix (ShaderProperties._Ocean_OceanToCamera_PROPERTY, cameraToOcean.Inverse ().ToMatrix4x4 ()); // oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, ctos.ToMatrix4x4 ()); // oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, stoc.ToMatrix4x4 ()); oceanMaterial.SetMatrix (ShaderProperties._Globals_WorldToOcean_PROPERTY, worldToOcean.ToMatrix4x4 ()); oceanMaterial.SetMatrix (ShaderProperties._Globals_OceanToWorld_PROPERTY, worldToOcean.Inverse ().ToMatrix4x4 ()); oceanMaterial.SetVector (ShaderProperties._Ocean_CameraPos_PROPERTY, oceanNode.offset.ToVector3 ()); //horizon calculations //these are used to find where the horizon line is on screen //and "clamp" vertexes that are above it back to it //as the grid is projected on the whole screen, vertexes over the horizon need to be dealt with //simply passing a flag to drop fragments or moving these vertexes offscreen will cause issues //as the horizon line can be between two vertexes and the horizon line will appear "pixelated" //as whole chunks go missing //these need to be done here //1)for double precision //2)for speed Vector3d2 sphereDir=localToCam * Vector3d2.Zero (); //vector to center of planet double OHL = sphereDir.Magnitude (); //distance to center of planet sphereDir = sphereDir.Normalized (); //direction to center of planet double rHorizon = Math.Sqrt(OHL * OHL - radius * radius); //distance to the horizon, i.e distance to ocean sphere tangent //Theta=angle to horizon, now all that is left to do is check the viewdir against this angle in the shader double cosTheta= rHorizon / (OHL); double sinTheta= Math.Sqrt (1- cosTheta*cosTheta); oceanMaterial.SetVector (ShaderProperties.sphereDir_PROPERTY, sphereDir.ToVector3 ()); oceanMaterial.SetFloat (ShaderProperties.cosTheta_PROPERTY, (float) cosTheta); oceanMaterial.SetFloat (ShaderProperties.sinTheta_PROPERTY, (float) sinTheta); //planetshine properties if ((oceanNode.prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine) { Matrix4x4 planetShineSourcesMatrix=oceanNode.prolandManager.planetShineSourcesMatrix; Vector3d2 oceanSunDir2; for (int i=0;i<4;i++) { Vector4 row = planetShineSourcesMatrix.GetRow(i); if (row.w != 0f) { oceanSunDir2=localToOcean.ToMatrix3x3d () * new Vector3d2(row.x,row.y,row.z); planetShineSourcesMatrix.SetRow(i,new Vector4((float)oceanSunDir2.x,(float)oceanSunDir2.y,(float)oceanSunDir2.z,row.w)); } } oceanMaterial.SetMatrix (ShaderProperties.planetShineSources_PROPERTY, planetShineSourcesMatrix); oceanMaterial.SetMatrix (ShaderProperties.planetShineRGB_PROPERTY, oceanNode.prolandManager.planetShineRGBMatrix); } Matrix4x4 worldToLightMatrix = oceanNode.prolandManager.mainSunLight.transform.worldToLocalMatrix; if (oceanNode.prolandManager.parentCelestialBody.transform.position.sqrMagnitude < oceanNode.prolandManager.mainSunLight.transform.position.sqrMagnitude) { worldToLightMatrix.m03 = oceanNode.prolandManager.parentCelestialBody.transform.position.x; worldToLightMatrix.m13 = oceanNode.prolandManager.parentCelestialBody.transform.position.y; worldToLightMatrix.m23 = oceanNode.prolandManager.parentCelestialBody.transform.position.z; } if (oceanNode.causticsShadowMaskModulator) { oceanNode.causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix (ShaderProperties.CameraToWorld_PROPERTY, inCamera.cameraToWorldMatrix); oceanNode.causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix (ShaderProperties.WorldToLight_PROPERTY, worldToLightMatrix); oceanNode.causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetVector (ShaderProperties.PlanetOrigin_PROPERTY, oceanNode.prolandManager.parentLocalTransform.position); } if (oceanNode.causticsLightRaysRenderer) { oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetMatrix (ShaderProperties.CameraToWorld_PROPERTY, inCamera.cameraToWorldMatrix); oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetMatrix (ShaderProperties.WorldToLight_PROPERTY, worldToLightMatrix); oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetVector (ShaderProperties.LightDir_PROPERTY, oceanNode.prolandManager.mainSunLight.transform.forward); oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetVector (ShaderProperties.PlanetOrigin_PROPERTY, oceanNode.prolandManager.parentLocalTransform.position); } } public void OnDestroy() { } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/OceanFFTcpu.cs ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. * * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. * Modified and ported to Unity by Justin Hawkins 2014 * * */ using UnityEngine; using System; using System.Collections; using System.Threading; namespace Scatterer { /* * Unused CPU FFT version, ship interaction is better done with async GPU readback so this CPU version is not needed. Kept for reference * Extend the base class OceanNode to provide the data need * to create the waves using fourier transform which can then be applied * to the projected grid handled by the OceanNode. * All the fourier transforms are performed on the CPU */ public class OceanFFTcpu: OceanNode { WriteFloat m_writeFloat; Vector2 m_varianceMax; public float WAVE_CM = 0.23f; // Eq 59 public float WAVE_KM = 370.0f; // Eq 59 [Persistent] public float AMP = 1.0f; Material m_initSpectrumMat; Material m_initDisplacementMat; public int m_ansio = 2; [Persistent] public float m_windSpeed = 5.0f; //A higher wind speed gives greater swell to the waves [Persistent] public float m_omega = 0.84f; //A lower number means the waves last longer and will build up larger waves public Vector4 m_gridSizes = new Vector4(5488, 392, 28, 2); //Size in meters (i.e. in spatial domain) of each grid public Vector4 m_choppyness = new Vector4(2.3f, 2.1f, 1.3f, 0.9f); //Strength of sideways displacement for each grid public int m_fourierGridSize = 64; //This is the fourier transform size, must pow2 number. Recommend no higher or lower than 64, 128 or 256. [Persistent] public int m_varianceSize = 4; float m_fsize; float m_maxSlopeVariance; protected int m_idx = 0; protected Vector4 m_spectrumOffset; protected Vector4 m_inverseGridSizes; protected RenderTexture m_spectrum01, m_spectrum23; protected RenderTexture m_WTable; public bool rendertexturesCreated { get { return (m_WTable.IsCreated()); } } RenderTexture[] m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2; RenderTexture[] m_fourierBuffer3, m_fourierBuffer4; public RenderTexture m_map0, m_map1, m_map2, m_map3, m_map4; public Texture3D variance { get { return m_variance; } } Texture3D m_variance; protected FourierGPU m_fourier; public override float GetMaxSlopeVariance() { return m_maxSlopeVariance; } //CPU wave stuff float FFTtimer=0; volatile int m_bufferIdx = 0; public volatile bool done0=true,done1=true,done2=true,done3=true,done4=true,done5=true; public volatile bool done=true; int m_passes; float[] m_butterflyLookupTable = null; Vector4[,] m_fourierBuffer0vector; Vector4[,] m_fourierBuffer1vector, m_fourierBuffer2vector,m_fourierBuffer3vector,m_fourierBuffer4vector; Vector4[] m_spectrum01vector, m_spectrum23vector, m_WTablevector; // volatile Vector4[,] m_fourierBuffer0vectorResults, m_fourierBuffer3vectorResults,m_fourierBuffer4vectorResults; Vector4[,] m_fourierBuffer0vectorResults, m_fourierBuffer3vectorResults,m_fourierBuffer4vectorResults; protected FourierCPU m_CPUfourier; public override void Init(ProlandManager manager) { base.Init(manager); m_initSpectrumMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitSpectrum")]); m_initDisplacementMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitDisplacement")]); m_fourierGridSize = Scatterer.Instance.mainSettings.m_fourierGridSize; if (m_fourierGridSize > 256) { Utils.LogDebug("Proland::OceanFFTcpu::Start - fourier grid size must not be greater than 256, changing to 256"); m_fourierGridSize = 256; } if (!Mathf.IsPowerOfTwo(m_fourierGridSize)) { Utils.LogDebug("Proland::OceanFFTcpu::Start - fourier grid size must be pow2 number, changing to nearest pow2 number"); m_fourierGridSize = Mathf.NextPowerOfTwo(m_fourierGridSize); } m_fsize = (float) m_fourierGridSize; m_spectrumOffset = new Vector4(1.0f + 0.5f / m_fsize, 1.0f + 0.5f / m_fsize, 0, 0); float factor = 2.0f * Mathf.PI * m_fsize; m_inverseGridSizes = new Vector4(factor / m_gridSizes.x, factor / m_gridSizes.y, factor / m_gridSizes.z, factor / m_gridSizes.w); m_fourier = new FourierGPU(m_fourierGridSize); m_writeFloat = new WriteFloat(m_fourierGridSize, m_fourierGridSize); //#if CPUmode if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { m_CPUfourier = new FourierCPU (m_fourierGridSize); m_passes = (int)(Mathf.Log (m_fsize) / Mathf.Log (2.0f)); ComputeButterflyLookupTable (); m_CPUfourier.m_butterflyLookupTable = m_butterflyLookupTable; m_fourierBuffer0vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer0vectorResults = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer1vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer2vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer3vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer4vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer3vectorResults = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; m_fourierBuffer4vectorResults = new Vector4[2, m_fourierGridSize * m_fourierGridSize]; } //#endif //Create the data needed to make the waves each frame CreateRenderTextures(); GenerateWavesSpectrum(); CreateWTable(); m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum01_PROPERTY, m_spectrum01); m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum23_PROPERTY, m_spectrum23); m_initSpectrumMat.SetTexture (ShaderProperties._WTable_PROPERTY, m_WTable); m_initSpectrumMat.SetVector (ShaderProperties._Offset_PROPERTY, m_spectrumOffset); m_initSpectrumMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes); m_initDisplacementMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes); //#if CPUmode if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { CreateWTableForCPU (); } //#endif } Vector2 GetSlopeVariances(Vector2 k, float A, float B, float C, float spectrumX, float spectrumY) { float w = 1.0f - Mathf.Exp(A * k.x * k.x + B * k.x * k.y + C * k.y * k.y); return new Vector2((k.x * k.x) * w, (k.y * k.y) * w) * (spectrumX * spectrumX + spectrumY * spectrumY) * 2.0f; } /// /// Iterate over the spectrum and find the variance. /// Use in the BRDF equations. /// Vector2 ComputeVariance(float slopeVarianceDelta, float[] inSpectrum01, float[] inSpectrum23, float idxX, float idxY, float idxZ) { const float SCALE = 10.0f; float A = Mathf.Pow(idxX / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE; float C = Mathf.Pow(idxZ / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE; float B = (2.0f * idxY / ((float) m_varianceSize - 1.0f) - 1.0f) * Mathf.Sqrt(A * C); A = -0.5f * A; B = -B; C = -0.5f * C; Vector2 slopeVariances = new Vector2(slopeVarianceDelta, slopeVarianceDelta); for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { int i = x >= m_fsize / 2.0f ? x - m_fourierGridSize : x; int j = y >= m_fsize / 2.0f ? y - m_fourierGridSize : y; Vector2 k = new Vector2(i, j) * 2.0f * Mathf.PI; slopeVariances += GetSlopeVariances(k / m_gridSizes.x, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 1]); slopeVariances += GetSlopeVariances(k / m_gridSizes.y, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 3]); slopeVariances += GetSlopeVariances(k / m_gridSizes.z, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 1]); slopeVariances += GetSlopeVariances(k / m_gridSizes.w, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 3]); } } return slopeVariances; } /* * Initializes the data to the shader that needs to * have the fourier transform applied to it this frame. */ protected virtual void InitWaveSpectrum(float t) { // init heights (0) and slopes (1,2) RenderTexture[] buffers012 = new RenderTexture[] { m_fourierBuffer0[1], m_fourierBuffer1[1], m_fourierBuffer2[1] }; m_initSpectrumMat.SetFloat (ShaderProperties._T_PROPERTY, t); // RTUtility.MultiTargetBlit(buffers012, m_initSpectrumMat); RTUtility.MultiTargetBlit(buffers012, m_initSpectrumMat, 0); // Init displacement (3,4) RenderTexture[] buffers34 = new RenderTexture[] { m_fourierBuffer3[1], m_fourierBuffer4[1] }; m_initDisplacementMat.SetTexture (ShaderProperties._Buffer1_PROPERTY, m_fourierBuffer1[1]); m_initDisplacementMat.SetTexture (ShaderProperties._Buffer2_PROPERTY, m_fourierBuffer2[1]); // RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat); RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat, 0); } void InitWaveSpectrumCPU(float time) { Vector2 uv, st, k1, k2, k3, k4, h1, h2, h3, h4, h12, h34, n1, n2, n3, n4; Vector4 s12, s34, s12c, s34c; int rx, ry; // init heights (0) and slopes (1,2) for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { uv.x = x / m_fsize; uv.y = y / m_fsize; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; rx = x; ry = y; s12 = m_spectrum01vector[rx + ry * m_fourierGridSize]; s34 = m_spectrum23vector[rx + ry * m_fourierGridSize]; rx = (m_fourierGridSize - x) % m_fourierGridSize; ry = (m_fourierGridSize - y) % m_fourierGridSize; s12c = m_spectrum01vector[rx + ry * m_fourierGridSize]; s34c = m_spectrum23vector[rx + ry * m_fourierGridSize]; k1 = st * m_inverseGridSizes.x; k2 = st * m_inverseGridSizes.y; k3 = st * m_inverseGridSizes.z; k4 = st * m_inverseGridSizes.w; h1 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].x, s12.x, s12.y, s12c.x, s12c.y); h2 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].y, s12.z, s12.w, s12c.z, s12c.w); h3 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].z, s34.x, s34.y, s34c.x, s34c.y); h4 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].w, s34.z, s34.w, s34c.z, s34c.w); //heights h12 = h1 + COMPLEX(h2); h34 = h3 + COMPLEX(h4); //slopes (normals) n1 = COMPLEX(k1.x * h1) - k1.y * h1; n2 = COMPLEX(k2.x * h2) - k2.y * h2; n3 = COMPLEX(k3.x * h3) - k3.y * h3; n4 = COMPLEX(k4.x * h4) - k4.y * h4; //Heights in last two channels (h34) have been removed as I found they arent really need for the shader //h3 and h4 still needs to be calculated for the slope but they are no longer save and transformed by the fourier step //m_fourierBuffer0vector[1, x+y*m_fourierGridSize] = new Vector4(h12.x, h12.y, h34.x, h34.y); //I put this back int i = x + y * m_fourierGridSize; // m_fourierBuffer0vector[1, i] = h12; m_fourierBuffer0vector[1, i] = new Vector4(h12.x, h12.y, h34.x, h34.y); m_fourierBuffer1vector[1, i] = new Vector4(n1.x, n1.y, n2.x, n2.y); m_fourierBuffer2vector[1, i] = new Vector4(n3.x, n3.y, n4.x, n4.y); // Init displacement (3,4) float K1 = (k1).magnitude; float K2 = (k2).magnitude; float K3 = (k3).magnitude; float K4 = (k4).magnitude; float IK1 = K1 == 0.0f ? 0.0f : 1.0f / K1; float IK2 = K2 == 0.0f ? 0.0f : 1.0f / K2; float IK3 = K3 == 0.0f ? 0.0f : 1.0f / K3; float IK4 = K4 == 0.0f ? 0.0f : 1.0f / K4; Vector4 result = new Vector4(0f,0f,0f,0f); result.x=m_fourierBuffer1vector[1,i].x * IK1; result.y=m_fourierBuffer1vector[1,i].y * IK1; result.z=m_fourierBuffer1vector[1,i].z * IK2; result.w=m_fourierBuffer1vector[1,i].w * IK2; m_fourierBuffer3vector[1, i] = result; Vector4 result2 = new Vector4(0f,0f,0f,0f); result.x=m_fourierBuffer2vector[1,i].x * IK3; result.y=m_fourierBuffer2vector[1,i].y * IK3; result.z=m_fourierBuffer2vector[1,i].z * IK4; result.w=m_fourierBuffer2vector[1,i].w * IK4; m_fourierBuffer4vector[1, i] = result2; } } } public override void UpdateNode() { // if (!m_spectrum01.IsCreated()) { // waitBeforeReloadCnt++; // if (waitBeforeReloadCnt >= 2) { // // CreateRenderTextures(); // GenerateWavesSpectrum(); // CreateWTable(); // // Utils.Log("Recreated OceanFFTcpu Data"); // waitBeforeReloadCnt = 0; // } // } // // else { float t; if (TimeWarp.CurrentRate > 4) { t = (float) Planetarium.GetUniversalTime(); } else { t = Time.time; } // t = Time.realtimeSinceStartup; if (!MapView.MapIsEnabled) { InitWaveSpectrum(t); //Perform fourier transform and record what is the current index m_idx = m_fourier.PeformFFT(m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2); m_fourier.PeformFFT(m_fourierBuffer3, m_fourierBuffer4); Graphics.Blit(m_fourierBuffer0[m_idx], m_map0); Graphics.Blit(m_fourierBuffer1[m_idx], m_map1); Graphics.Blit(m_fourierBuffer2[m_idx], m_map2); Graphics.Blit(m_fourierBuffer3[m_idx], m_map3); Graphics.Blit(m_fourierBuffer4[m_idx], m_map4); m_oceanMaterial.SetVector (ShaderProperties._Ocean_MapSize_PROPERTY, new Vector2(m_fsize, m_fsize)); m_oceanMaterial.SetVector (ShaderProperties._Ocean_Choppyness_PROPERTY, m_choppyness); m_oceanMaterial.SetVector (ShaderProperties._Ocean_GridSizes_PROPERTY, m_gridSizes); m_oceanMaterial.SetFloat (ShaderProperties._Ocean_HeightOffset_PROPERTY, 0f); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Variance_PROPERTY, m_variance); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map0_PROPERTY, m_map0); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map1_PROPERTY, m_map1); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map2_PROPERTY, m_map2); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map3_PROPERTY, m_map3); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map4_PROPERTY, m_map4); m_oceanMaterial.SetVector (ShaderProperties._VarianceMax_PROPERTY, m_varianceMax); } //#if CPUmode if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { if(!(done0&&done1&&done2&&done3&&done4&&done5)) { base.UpdateNode(); return; } done0 = false; done1 = false; done2 = false; done3 = false; done4 = false; done5 = false; FFTtimer = Time.realtimeSinceStartup; Nullable time = t; ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded), time); CommitResults (ref m_fourierBuffer0vector, ref m_fourierBuffer0vectorResults); CommitResults (ref m_fourierBuffer3vector, ref m_fourierBuffer3vectorResults); CommitResults (ref m_fourierBuffer4vector, ref m_fourierBuffer4vectorResults); } //#endif base.UpdateNode(); } } //Craft-wave interactions //Note: This version was a proof of concept, the final version is the GPU readback version in OceanFFTgpu, this is only kept here for reference public void FixedUpdate() { if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { foreach (Vessel vessel in FlightGlobals.VesselsLoaded) { foreach (Part part in vessel.parts) { if (part.partBuoyancy) { Vector3 relativePartPos = part.partBuoyancy.transform.position-Scatterer.Instance.nearCamera.transform.position; float newheight= findHeight(new Vector3(Vector3.Dot(relativePartPos,ux.ToVector3())+offsetVector3.x, Vector3.Dot(relativePartPos,uy.ToVector3())+offsetVector3.y, 0f),0.02f); part.partBuoyancy.waterLevel=newheight; part.partBuoyancy.wasSplashed=part.partBuoyancy.splashed; part.partBuoyancy.slow=true; } } } } } public override void OnDestroy() { base.OnDestroy(); m_map0.Release(); m_map1.Release(); m_map2.Release(); m_map3.Release(); m_map4.Release(); m_spectrum01.Release(); m_spectrum23.Release(); m_WTable.Release(); for (int i = 0; i < 2; i++) { m_fourierBuffer0[i].Release(); m_fourierBuffer1[i].Release(); m_fourierBuffer2[i].Release(); m_fourierBuffer3[i].Release(); m_fourierBuffer4[i].Release(); } } protected virtual void CreateRenderTextures() { RenderTextureFormat mapFormat = RenderTextureFormat.ARGBHalf; RenderTextureFormat format = RenderTextureFormat.ARGBHalf; //These texture hold the actual data use in the ocean renderer CreateMap(ref m_map0, mapFormat, m_ansio, true); CreateMap(ref m_map1, mapFormat, m_ansio, true); CreateMap(ref m_map2, mapFormat, m_ansio, true); CreateMap(ref m_map3, mapFormat, m_ansio, true); CreateMap(ref m_map4, mapFormat, m_ansio, true); //These textures are used to perform the fourier transform CreateBuffer(ref m_fourierBuffer0, format); //heights CreateBuffer(ref m_fourierBuffer1, format); // slopes X CreateBuffer(ref m_fourierBuffer2, format); // slopes Y CreateBuffer(ref m_fourierBuffer3, format); // displacement X CreateBuffer(ref m_fourierBuffer4, format); // displacement Y //These textures hold the specturm the fourier transform is performed on m_spectrum01 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); m_spectrum01.filterMode = FilterMode.Point; m_spectrum01.wrapMode = TextureWrapMode.Repeat; // m_spectrum01.enableRandomWrite = false; m_spectrum01.enableRandomWrite = false; m_spectrum01.Create(); m_spectrum23 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); m_spectrum23.filterMode = FilterMode.Point; m_spectrum23.wrapMode = TextureWrapMode.Repeat; m_spectrum23.enableRandomWrite = false; m_spectrum23.Create(); m_WTable = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); m_WTable.filterMode = FilterMode.Point; m_WTable.wrapMode = TextureWrapMode.Clamp; m_WTable.enableRandomWrite = false; m_WTable.Create(); m_variance = new Texture3D(m_varianceSize, m_varianceSize, m_varianceSize, TextureFormat.ARGB32, true); m_variance.wrapMode = TextureWrapMode.Clamp; m_variance.filterMode = FilterMode.Bilinear; } protected void CreateBuffer(ref RenderTexture[] tex, RenderTextureFormat format) { tex = new RenderTexture[2]; for (int i = 0; i < 2; i++) { tex[i] = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); tex[i].filterMode = FilterMode.Point; tex[i].wrapMode = TextureWrapMode.Clamp; tex[i].Create(); } } protected void CreateMap(ref RenderTexture map, RenderTextureFormat format, int ansio, bool useMipMaps) { map = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); map.filterMode = FilterMode.Trilinear; map.wrapMode = TextureWrapMode.Repeat; map.anisoLevel = ansio; // map.useMipMap = true; map.useMipMap = useMipMaps; map.Create(); } float sqr(float x) { return x * x; } float omega(float k) { return Mathf.Sqrt(9.81f * k * (1.0f + sqr(k / WAVE_KM))); } // Eq 24 float Spectrum(float kx, float ky, bool omnispectrum) { //I know this is a big chunk of ugly math but dont worry to much about what it all means //It recreates a statistcally representative model of a wave spectrum in the frequency domain. float U10 = m_windSpeed; // phase speed float k = Mathf.Sqrt(kx * kx + ky * ky); float c = omega(k) / k; // spectral peak float kp = 9.81f * sqr(m_omega / U10); // after Eq 3 float cp = omega(kp) / kp; // friction velocity float z0 = 3.7e-5f * sqr(U10) / 9.81f * Mathf.Pow(U10 / cp, 0.9f); // Eq 66 float u_star = 0.41f * U10 / Mathf.Log(10.0f / z0); // Eq 60 float Lpm = Mathf.Exp(-5.0f / 4.0f * sqr(kp / k)); // after Eq 3 float gamma = (m_omega < 1.0f) ? 1.7f : 1.7f + 6.0f * Mathf.Log(m_omega); // after Eq 3 // log10 or log? float sigma = 0.08f * (1.0f + 4.0f / Mathf.Pow(m_omega, 3.0f)); // after Eq 3 float Gamma = Mathf.Exp(-1.0f / (2.0f * sqr(sigma)) * sqr(Mathf.Sqrt(k / kp) - 1.0f)); float Jp = Mathf.Pow(gamma, Gamma); // Eq 3 float Fp = Lpm * Jp * Mathf.Exp(-m_omega / Mathf.Sqrt(10.0f) * (Mathf.Sqrt(k / kp) - 1.0f)); // Eq 32 float alphap = 0.006f * Mathf.Sqrt(m_omega); // Eq 34 float Bl = 0.5f * alphap * cp / c * Fp; // Eq 31 float alpham = 0.01f * (u_star < WAVE_CM ? 1.0f + Mathf.Log(u_star / WAVE_CM) : 1.0f + 3.0f * Mathf.Log(u_star / WAVE_CM)); // Eq 44 float Fm = Mathf.Exp(-0.25f * sqr(k / WAVE_KM - 1.0f)); // Eq 41 float Bh = 0.5f * alpham * WAVE_CM / c * Fm * Lpm; // Eq 40 (fixed) Bh *= Lpm; // bug fix??? if (omnispectrum) return AMP * (Bl + Bh) / (k * sqr(k)); // Eq 30 float a0 = Mathf.Log(2.0f) / 4.0f; float ap = 4.0f; float am = 0.13f * u_star / WAVE_CM; // Eq 59 float Delta = (float) System.Math.Tanh(a0 + ap * Mathf.Pow(c / cp, 2.5f) + am * Mathf.Pow(WAVE_CM / c, 2.5f)); // Eq 57 float phi = Mathf.Atan2(ky, kx); if (kx < 0.0f) return 0.0f; Bl *= 2.0f; Bh *= 2.0f; // remove waves perpendicular to wind dir float tweak = Mathf.Sqrt(Mathf.Max(kx / Mathf.Sqrt(kx * kx + ky * ky), 0.0f)); return AMP * (Bl + Bh) * (1.0f + Delta * Mathf.Cos(2.0f * phi)) / (2.0f * Mathf.PI * sqr(sqr(k))) * tweak; // Eq 67 } Vector2 GetSpectrumSample(float i, float j, float lengthScale, float kMin) { float dk = 2.0f * Mathf.PI / lengthScale; float kx = i * dk; float ky = j * dk; Vector2 result = new Vector2(0.0f, 0.0f); float rnd = UnityEngine.Random.value; if (Mathf.Abs(kx) >= kMin || Mathf.Abs(ky) >= kMin) { float S = Spectrum(kx, ky, false); float h = Mathf.Sqrt(S / 2.0f) * dk; float phi = rnd * 2.0f * Mathf.PI; result.x = h * Mathf.Cos(phi); result.y = h * Mathf.Sin(phi); } return result; } float GetSlopeVariance(float kx, float ky, Vector2 spectrumSample) { float kSquare = kx * kx + ky * ky; float real = spectrumSample.x; float img = spectrumSample.y; float hSquare = real * real + img * img; return kSquare * hSquare * 2.0f; } void GenerateWavesSpectrum() { // Slope variance due to all waves, by integrating over the full spectrum. // Used by the BRDF rendering model float theoreticSlopeVariance = 0.0f; float k = 5e-3f; while (k < 1e3f) { float nextK = k * 1.001f; theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k); k = nextK; } float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4]; float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4]; //#if CPUmode if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { m_spectrum01vector = new Vector4[m_fourierGridSize * m_fourierGridSize]; m_spectrum23vector = new Vector4[m_fourierGridSize * m_fourierGridSize]; } //#endif int idx; float i; float j; float totalSlopeVariance = 0.0f; Vector2 sample12XY; Vector2 sample12ZW; Vector2 sample34XY; Vector2 sample34ZW; UnityEngine.Random.seed = 0; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { idx = x + y * m_fourierGridSize; i = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float) x; j = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float) y; sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x); sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x); sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y); sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z); //#if CPUmode if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { m_spectrum01vector[idx].x = sample12XY.x; m_spectrum01vector[idx].y = sample12XY.y; m_spectrum01vector[idx].z = sample12ZW.x; m_spectrum01vector[idx].w = sample12ZW.y; m_spectrum23vector[idx].x = sample34XY.x; m_spectrum23vector[idx].y = sample34XY.y; m_spectrum23vector[idx].z = sample34ZW.x; m_spectrum23vector[idx].w = sample34ZW.y; } //#endif spectrum01[idx * 4 + 0] = sample12XY.x; spectrum01[idx * 4 + 1] = sample12XY.y; spectrum01[idx * 4 + 2] = sample12ZW.x; spectrum01[idx * 4 + 3] = sample12ZW.y; spectrum23[idx * 4 + 0] = sample34XY.x; spectrum23[idx * 4 + 1] = sample34XY.y; spectrum23[idx * 4 + 2] = sample34ZW.x; spectrum23[idx * 4 + 3] = sample34ZW.y; i *= 2.0f * Mathf.PI; j *= 2.0f * Mathf.PI; totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW); } } m_writeFloat.WriteIntoRenderTexture(m_spectrum01, 4, spectrum01); m_writeFloat.WriteIntoRenderTexture(m_spectrum23, 4, spectrum23); float slopeVarianceDelta = 0.5f * (theoreticSlopeVariance - totalSlopeVariance); m_varianceMax = new Vector2(float.NegativeInfinity, float.NegativeInfinity); Vector2[, , ] variance32bit = new Vector2[m_varianceSize, m_varianceSize, m_varianceSize]; Color[] variance8bit = new Color[m_varianceSize * m_varianceSize * m_varianceSize]; for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { variance32bit[x, y, z] = ComputeVariance(slopeVarianceDelta, spectrum01, spectrum23, x, y, z); if (variance32bit[x, y, z].x > m_varianceMax.x) m_varianceMax.x = variance32bit[x, y, z].x; if (variance32bit[x, y, z].y > m_varianceMax.y) m_varianceMax.y = variance32bit[x, y, z].y; } } } for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { idx = x + y * m_varianceSize + z * m_varianceSize * m_varianceSize; variance8bit[idx] = new Color(variance32bit[x, y, z].x / m_varianceMax.x, variance32bit[x, y, z].y / m_varianceMax.y, 0.0f, 1.0f); } } } m_variance.SetPixels(variance8bit); m_variance.Apply(); // m_maxSlopeVariance = 0.0f; // for (int v = 0; v < m_varianceSize * m_varianceSize * m_varianceSize; v++) { // m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, varianceData[v]); // } m_maxSlopeVariance = 0.0f; for(int v = 0; v < m_varianceSize*m_varianceSize*m_varianceSize; v++) { m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit[v].r*m_varianceMax.x); m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit[v].g*m_varianceMax.y); } } void CreateWTable() { //Some values need for the InitWaveSpectrum function can be precomputed Vector2 uv, st; float k1, k2, k3, k4, w1, w2, w3, w4; float[] table = new float[m_fourierGridSize * m_fourierGridSize * 4]; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { uv = new Vector2(x, y) / m_fsize; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; k1 = (st * m_inverseGridSizes.x).magnitude; k2 = (st * m_inverseGridSizes.y).magnitude; k3 = (st * m_inverseGridSizes.z).magnitude; k4 = (st * m_inverseGridSizes.w).magnitude; w1 = Mathf.Sqrt(9.81f * k1 * (1.0f + k1 * k1 / (WAVE_KM * WAVE_KM))); w2 = Mathf.Sqrt(9.81f * k2 * (1.0f + k2 * k2 / (WAVE_KM * WAVE_KM))); w3 = Mathf.Sqrt(9.81f * k3 * (1.0f + k3 * k3 / (WAVE_KM * WAVE_KM))); w4 = Mathf.Sqrt(9.81f * k4 * (1.0f + k4 * k4 / (WAVE_KM * WAVE_KM))); table[(x + y * m_fourierGridSize) * 4 + 0] = w1; table[(x + y * m_fourierGridSize) * 4 + 1] = w2; table[(x + y * m_fourierGridSize) * 4 + 2] = w3; table[(x + y * m_fourierGridSize) * 4 + 3] = w4; } } m_writeFloat.WriteIntoRenderTexture(m_WTable, 4, table); } /// /// Some of the values needed in the InitWaveSpectrum function can be precomputed. /// If the grid sizes change this function must called again. /// void CreateWTableForCPU() { Vector2 uv, st; float k1, k2, k3, k4, w1, w2, w3, w4; m_WTablevector = new Vector4[m_fourierGridSize * m_fourierGridSize]; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { uv = new Vector2(x, y) / m_fsize; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; k1 = (st * m_inverseGridSizes.x).magnitude; k2 = (st * m_inverseGridSizes.y).magnitude; k3 = (st * m_inverseGridSizes.z).magnitude; k4 = (st * m_inverseGridSizes.w).magnitude; w1 = Mathf.Sqrt(9.81f * k1 * (1.0f + k1 * k1 / (WAVE_KM * WAVE_KM))); w2 = Mathf.Sqrt(9.81f * k2 * (1.0f + k2 * k2 / (WAVE_KM * WAVE_KM))); w3 = Mathf.Sqrt(9.81f * k3 * (1.0f + k3 * k3 / (WAVE_KM * WAVE_KM))); w4 = Mathf.Sqrt(9.81f * k4 * (1.0f + k4 * k4 / (WAVE_KM * WAVE_KM))); m_WTablevector[x + y * m_fourierGridSize] = new Vector4(w1, w2, w3, w4); } } } Vector2 GetSpectrum(float t, float w, float s0x, float s0y, float s0cx, float s0cy) { float c = Mathf.Cos(w * t); float s = Mathf.Sin(w * t); return new Vector2((s0x + s0cx) * c - (s0y + s0cy) * s, (s0x - s0cx) * s + (s0y - s0cy) * c); } Vector2 COMPLEX(Vector2 z) { return new Vector2(-z.y, z.x); // returns i times z (complex number) } public virtual void onThreadsDone() { return; } void CommitResults(ref Vector4[,] data, ref Vector4[,] output) { for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { int i = x + y * m_fourierGridSize; output[m_bufferIdx,i] = data[m_bufferIdx, i]; } } } //main thread that launches the other threads void RunThreaded(object o) { Nullable time = o as Nullable; InitWaveSpectrumCPU(time.Value); ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded1), time); ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded2), time); ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded3), time); ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded4), time); ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded5), time); done0 = true; } void RunThreaded1(object o) { Nullable time = o as Nullable; m_bufferIdx = m_CPUfourier.PeformFFT(0, m_fourierBuffer0vector); done1 = true; } void RunThreaded2(object o) { Nullable time = o as Nullable; m_CPUfourier.PeformFFT(0, m_fourierBuffer1vector); done2 = true; } void RunThreaded3(object o) { Nullable time = o as Nullable; m_CPUfourier.PeformFFT(0, m_fourierBuffer2vector); done3 = true; } void RunThreaded4(object o) { Nullable time = o as Nullable; m_CPUfourier.PeformFFT(0, m_fourierBuffer3vector); done4 = true; } void RunThreaded5(object o) { Nullable time = o as Nullable; m_CPUfourier.PeformFFT(0, m_fourierBuffer4vector); done5 = true; } void ComputeButterflyLookupTable() { m_butterflyLookupTable = new float[m_fourierGridSize * m_passes * 4]; for (int i = 0; i < m_passes; i++) { int nBlocks = (int)Mathf.Pow(2, m_passes - 1 - i); int nHInputs = (int)Mathf.Pow(2, i); for (int j = 0; j < nBlocks; j++) { for (int k = 0; k < nHInputs; k++) { int i1, i2, j1, j2; if (i == 0) { i1 = j * nHInputs * 2 + k; i2 = j * nHInputs * 2 + nHInputs + k; j1 = BitReverse(i1); j2 = BitReverse(i2); } else { i1 = j * nHInputs * 2 + k; i2 = j * nHInputs * 2 + nHInputs + k; j1 = i1; j2 = i2; } float wr = Mathf.Cos(2.0f * Mathf.PI * (float)(k * nBlocks) / m_fsize); float wi = Mathf.Sin(2.0f * Mathf.PI * (float)(k * nBlocks) / m_fsize); int offset1 = 4 * (i1 + i * m_fourierGridSize); m_butterflyLookupTable[offset1 + 0] = j1; m_butterflyLookupTable[offset1 + 1] = j2; m_butterflyLookupTable[offset1 + 2] = wr; m_butterflyLookupTable[offset1 + 3] = wi; int offset2 = 4 * (i2 + i * m_fourierGridSize); m_butterflyLookupTable[offset2 + 0] = j1; m_butterflyLookupTable[offset2 + 1] = j2; m_butterflyLookupTable[offset2 + 2] = -wr; m_butterflyLookupTable[offset2 + 3] = -wi; } } } } int BitReverse(int i) { int j = i; int Sum = 0; int W = 1; int M = m_fourierGridSize / 2; while (M != 0) { j = ((i & M) > M - 1) ? 1 : 0; Sum += j * W; W *= 2; M /= 2; } return Sum; } void OnGUI(){ // GUI.DrawTexture(new Rect(0,0,512, 512), m_map0tex2DScaleMode.ScaleToFit, false); // GUI.DrawTexture(new Rect(0,0,512, 512), m_map0, ScaleMode.ScaleToFit, false); // GUI.DrawTexture(new Rect(512,0,512, 512), m_map0); } /// /// Get the two indices that need to be sampled for bilinear filtering. /// public void Index(double x, int sx, out int ix0, out int ix1) { ix0 = (int)x; ix1 = (int)x + (int)Math.Sign(x); // if(m_wrap) // { if(ix0 >= sx || ix0 <= -sx) ix0 = ix0 % sx; if(ix0 < 0) ix0 = sx - -ix0; if(ix1 >= sx || ix1 <= -sx) ix1 = ix1 % sx; if(ix1 < 0) ix1 = sx - -ix1; // } // else // { // if(ix0 < 0) ix0 = 0; // else if(ix0 >= sx) ix0 = sx-1; // // if(ix1 < 0) ix1 = 0; // else if(ix1 >= sx) ix1 = sx-1; // } // } public void GetUsingBilinearFiltering(float x, float y, float[] v, Vector4[,] m_data, int m_c) { //un-normalize cords x *= (float)m_fourierGridSize; y *= (float)m_fourierGridSize; x -= 0.5f; y -= 0.5f; int x0, x1; float fx = Math.Abs(x - (int)x); Index(x, m_fourierGridSize, out x0, out x1); int y0, y1; float fy = Math.Abs(y - (int)y); Index(y, m_fourierGridSize, out y0, out y1); // for(int c = 0; c < m_c; c++) //change this loop to work with Vector4 format // { // float v0 = m_data[(x0 + y0 * m_size) * m_c + c] * (1.0f-fx) + m_data[(x1 + y0 * m_size) * m_c + c] * fx; // float v1 = m_data[(x0 + y1 * m_size) * m_c + c] * (1.0f-fx) + m_data[(x1 + y1 * m_size) * m_c + c] * fx; // // v[c] = v0 * (1.0f-fy) + v1 * fy; // } float v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].x * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].x * fx; float v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].x * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].x * fx; v[0] = v0 * (1.0f-fy) + v1 * fy; v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].y * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].y * fx; v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].y * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].y * fx; v[1] = v0 * (1.0f-fy) + v1 * fy; v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].z * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].z * fx; v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].z * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].z * fx; v[2] = v0 * (1.0f-fy) + v1 * fy; v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].w * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].w * fx; v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].w * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].w * fx; v[3] = v0 * (1.0f-fy) + v1 * fy; } /// /// This will return the ocean height at any world pos. /// public float SampleHeight(Vector3 worldPos) { float ht = 0.0f; int HEIGHTS_CHANNELS = 4; float[] result = new float[HEIGHTS_CHANNELS]; Vector2 pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.x; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4); ht += result[0]; pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.y; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4); ht += result[1]; pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.z; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4); ht += result[2]; pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.w; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4); ht += result[3]; return ht; } /// /// This will return the ocean displacement at any world pos. /// public Vector2 SampleDisplacement(Vector3 worldPos) { Vector2 disp = Vector2.zero; int HEIGHTS_CHANNELS = 4; float[] result = new float[HEIGHTS_CHANNELS]; Vector2 pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.x; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer3vectorResults, 4); disp.x += result[0]* m_choppyness.x ; disp.y += result[1]* m_choppyness.x; pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.y; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer3vectorResults, 4); disp.x += result[2]* m_choppyness.y; disp.y += result[3]* m_choppyness.y; pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.z; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer4vectorResults, 4); disp.x += result[0]* m_choppyness.z; disp.y += result[1]* m_choppyness.z; pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.w; GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer4vectorResults, 4); disp.x += result[2]* m_choppyness.w; disp.y += result[3]* m_choppyness.w; return disp; } //Essentially a search method to find which point on the ocean is displaced sideways to end up at our part's position, so we can sample the correct height //Thanks to Scrawk (Justin Hawkins) for the tip //Original source: Water technology of uncharted p.126 https://www.gdcvault.com/play/1015309/Water-Technology-of public float findHeight(Vector3 worldPos, float precision) { int it = 0; Vector3 currentPosition = worldPos; Vector2 displacement = SampleDisplacement (currentPosition); Vector3 resultingPosition = currentPosition + new Vector3 (displacement.x, displacement.y, 0f); while ( ((resultingPosition - worldPos).magnitude > precision) && it<40 ) { Vector3 newPosition = currentPosition - (resultingPosition - worldPos); Vector3 newDisplacement = SampleDisplacement (newPosition); Vector3 newResultingPosition = newPosition + new Vector3 (newDisplacement.x, newDisplacement.y, 0f); currentPosition = newPosition; resultingPosition = newResultingPosition; it++; } return (SampleHeight (currentPosition)); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/OceanFFTgpu.cs ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. * * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. * Modified and ported to Unity by Justin Hawkins 2014 * * */ using UnityEngine; namespace Scatterer { /* * Extend the base class OceanNode to provide the data need * to create the waves using fourier transform which can then be applied * to the projected grid handled by the OceanNode. * All the fourier transforms are performed on the GPU */ public class OceanFFTgpu: OceanNode { WriteFloat m_writeFloat; public float WAVE_CM = 0.23f; // Eq 59 public float WAVE_KM = 370.0f; // Eq 59 [Persistent] public float AMP = 1.0f; Material m_initSpectrumMat, m_initDisplacementMat; public int mapsAniso = 2; [Persistent] public float m_windSpeed = 5.0f; //A higher wind speed gives greater swell to the waves [Persistent] public float m_omega = 0.84f; //A lower number means the waves last longer and will build up larger waves [Persistent] public float m_gravity = 9.81f; public Vector4 m_gridSizes = new Vector4(5488, 392, 28, 2); //Size in meters (i.e. in spatial domain) of each grid public Vector4 m_choppyness = new Vector4(2.3f, 2.1f, 1.3f, 0.9f); //strenght of sideways displacement for each grid public int m_fourierGridSize = 64; //This is the fourier transform size, must pow2 number. Recommend no higher or lower than 64, 128 or 256. private int m_varianceSize = 4; float m_fsize; float m_maxSlopeVariance; protected int m_idx = 0; protected Vector4 m_spectrumOffset; protected Vector4 m_inverseGridSizes; protected RenderTexture m_spectrum01, m_spectrum23; protected RenderTexture m_WTable; public bool rendertexturesCreated { get { return (m_WTable.IsCreated()); } } RenderTexture[] m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2; RenderTexture[] m_fourierBuffer3, m_fourierBuffer4; public RenderTexture m_map0, m_map1, m_map2, m_map3, m_map4; private ComputeShader m_varianceShader; RenderTexture m_varianceRenderTexture; Texture3D m_varianceTexture; Vector2 m_varianceMax; protected FourierGPU m_fourier; public override float GetMaxSlopeVariance() { return m_maxSlopeVariance; } [Persistent] public float maxWaveInteractionShipAltitude = 500.0f; // These are all oceanWhiteCaps settings but I add them here so they don't mess up serialization of gui public float m_foamMipMapBias = -2.0f; [Persistent] public float m_whiteCapStr = 0.1f; [Persistent] public float shoreFoam = 1.0f; [Persistent] public float m_farWhiteCapStr = 0.1f; private GPUWaveInteractionHandler waveInteractionHandler = null; public void Awake() { } public override void Init(ProlandManager manager) { base.Init(manager); if (m_gravity == 0f) { m_gravity = (float)(prolandManager.parentCelestialBody.GeeASL * 9.81d); } m_initSpectrumMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitSpectrum")]); m_initDisplacementMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitDisplacement")]); m_fourierGridSize = Scatterer.Instance.mainSettings.m_fourierGridSize; if (m_fourierGridSize > 256) { Utils.LogDebug("Proland::OceanFFT::Start - fourier grid size must not be greater than 256, changing to 256"); m_fourierGridSize = 256; } if (!Mathf.IsPowerOfTwo(m_fourierGridSize)) { Utils.LogDebug("Proland::OceanFFT::Start - fourier grid size must be pow2 number, changing to nearest pow2 number"); m_fourierGridSize = Mathf.NextPowerOfTwo(m_fourierGridSize); } m_fsize = (float) m_fourierGridSize; m_spectrumOffset = new Vector4(1.0f + 0.5f / m_fsize, 1.0f + 0.5f / m_fsize, 0, 0); float factor = 2.0f * Mathf.PI * m_fsize; m_inverseGridSizes = new Vector4(factor / m_gridSizes.x, factor / m_gridSizes.y, factor / m_gridSizes.z, factor / m_gridSizes.w); m_fourier = new FourierGPU(m_fourierGridSize); m_writeFloat = new WriteFloat(m_fourierGridSize, m_fourierGridSize); m_varianceSize = SystemInfo.supportsComputeShaders ? 16 : 4; //Create the data needed to make the waves each frame CreateRenderTextures(); GenerateWavesSpectrum(); CreateWTable(); m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum01_PROPERTY, m_spectrum01); m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum23_PROPERTY, m_spectrum23); m_initSpectrumMat.SetTexture (ShaderProperties._WTable_PROPERTY, m_WTable); m_initSpectrumMat.SetVector (ShaderProperties._Offset_PROPERTY, m_spectrumOffset); m_initSpectrumMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes); m_initDisplacementMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes); m_oceanMaterial.SetVector (ShaderProperties._Ocean_MapSize_PROPERTY, new Vector2(m_fsize, m_fsize)); m_oceanMaterial.SetVector (ShaderProperties._Ocean_Choppyness_PROPERTY, m_choppyness); m_oceanMaterial.SetVector (ShaderProperties._Ocean_GridSizes_PROPERTY, m_gridSizes); Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "FOAM_ON", "FOAM_OFF", false); if (SystemInfo.supportsAsyncGPUReadback && SystemInfo.supportsComputeShaders && Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { waveInteractionHandler = new GPUWaveInteractionHandler(maxWaveInteractionShipAltitude, prolandManager.parentCelestialBody.isHomeWorld); } } Vector2 GetSlopeVariances(Vector2 k, float A, float B, float C, float spectrumX, float spectrumY) { float w = 1.0f - Mathf.Exp(A * k.x * k.x + B * k.x * k.y + C * k.y * k.y); return new Vector2((k.x * k.x) * w, (k.y * k.y) * w) * (spectrumX * spectrumX + spectrumY * spectrumY) * 2.0f; } /// /// Iterate over the spectrum and find the variance. /// Use in the BRDF equations. /// Vector2 ComputeVariance(float slopeVarianceDelta, float[] inSpectrum01, float[] inSpectrum23, float idxX, float idxY, float idxZ) { const float SCALE = 10.0f; float A = Mathf.Pow(idxX / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE; float C = Mathf.Pow(idxZ / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE; float B = (2.0f * idxY / ((float) m_varianceSize - 1.0f) - 1.0f) * Mathf.Sqrt(A * C); A = -0.5f * A; B = -B; C = -0.5f * C; Vector2 slopeVariances = new Vector2(slopeVarianceDelta, slopeVarianceDelta); for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { int i = x >= m_fsize / 2.0f ? x - m_fourierGridSize : x; int j = y >= m_fsize / 2.0f ? y - m_fourierGridSize : y; Vector2 k = new Vector2(i, j) * 2.0f * Mathf.PI; slopeVariances += GetSlopeVariances(k / m_gridSizes.x, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 1]); slopeVariances += GetSlopeVariances(k / m_gridSizes.y, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 3]); slopeVariances += GetSlopeVariances(k / m_gridSizes.z, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 1]); slopeVariances += GetSlopeVariances(k / m_gridSizes.w, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 3]); } } return slopeVariances; } /* * Initializes the data to the shader that needs to * have the fourier transform applied to it this frame. */ protected virtual void InitWaveSpectrum(float t) { // init heights (0) and slopes (1,2) RenderTexture[] buffers012 = new RenderTexture[] { m_fourierBuffer0[1], m_fourierBuffer1[1], m_fourierBuffer2[1] }; m_initSpectrumMat.SetFloat (ShaderProperties._T_PROPERTY, t); RTUtility.MultiTargetBlit(buffers012, m_initSpectrumMat, 0); // Init displacement (3,4) RenderTexture[] buffers34 = new RenderTexture[] { m_fourierBuffer3[1], m_fourierBuffer4[1] }; m_initDisplacementMat.SetTexture (ShaderProperties._Buffer1_PROPERTY, m_fourierBuffer1[1]); m_initDisplacementMat.SetTexture (ShaderProperties._Buffer2_PROPERTY, m_fourierBuffer2[1]); // RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat); RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat, 0); } public override void UpdateNode() { if (!prolandManager.skyNode.inScaledSpace || (prolandManager.skyNode.simulateOceanInteraction && (waveInteractionHandler != null))) { //keep within low float exponents, otherwise we lose precision float t = (float)(Planetarium.GetUniversalTime() % 100000.0); InitWaveSpectrum(t); //Perform fourier transform and record what is the current index m_idx = m_fourier.PeformFFT(m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2); m_fourier.PeformFFT(m_fourierBuffer3, m_fourierBuffer4); //Copy the contents of the completed fourier transform to the map textures. //You could just use the buffer textures (m_fourierBuffer0,1,2,etc) to read from for the ocean shader //but they need to have mipmaps and unity updates the mipmaps //every time the texture is renderer into. This impacts performance during fourier transform stage as mipmaps would be updated every pass //and there is no way to disable and then enable mipmaps on render textures in Unity at time of writting. Graphics.Blit(m_fourierBuffer0[m_idx], m_map0); Graphics.Blit(m_fourierBuffer1[m_idx], m_map1); Graphics.Blit(m_fourierBuffer2[m_idx], m_map2); Graphics.Blit(m_fourierBuffer3[m_idx], m_map3); Graphics.Blit(m_fourierBuffer4[m_idx], m_map4); //m_oceanMaterial.SetFloat (ShaderProperties._Ocean_HeightOffset_PROPERTY, m_oceanLevel); m_oceanMaterial.SetFloat (ShaderProperties._Ocean_HeightOffset_PROPERTY, 0f); if (SystemInfo.supportsComputeShaders) { m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Variance_PROPERTY, m_varianceRenderTexture ); } else { m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Variance_PROPERTY, m_varianceTexture); } m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map0_PROPERTY, m_map0); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map1_PROPERTY, m_map1); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map2_PROPERTY, m_map2); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map3_PROPERTY, m_map3); m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map4_PROPERTY, m_map4); m_oceanMaterial.SetVector (ShaderProperties._VarianceMax_PROPERTY, SystemInfo.supportsComputeShaders? Vector2.one : m_varianceMax); // don't need to be done every frame if (waveInteractionHandler != null) { waveInteractionHandler.SetMaterialProperties(m_choppyness, m_gridSizes, m_map0, m_map3, m_map4); } } base.UpdateNode(); } public override void OnDestroy() { base.OnDestroy(); m_map0.Release(); m_map1.Release(); m_map2.Release(); m_map3.Release(); m_map4.Release(); m_spectrum01.Release(); m_spectrum23.Release(); m_WTable.Release(); for (int i = 0; i < 2; i++) { m_fourierBuffer0[i].Release(); m_fourierBuffer1[i].Release(); m_fourierBuffer2[i].Release(); m_fourierBuffer3[i].Release(); m_fourierBuffer4[i].Release(); } if (waveInteractionHandler != null) { waveInteractionHandler.Cleanup(); } } protected virtual void CreateRenderTextures() { RenderTextureFormat mapFormat = RenderTextureFormat.ARGBFloat; RenderTextureFormat fourierTransformformat = RenderTextureFormat.ARGBHalf; //These texture hold the actual data use in the ocean renderer CreateMap(ref m_map0, mapFormat, mapsAniso, true); CreateMap(ref m_map1, mapFormat, mapsAniso, true); CreateMap(ref m_map2, mapFormat, mapsAniso, true); CreateMap(ref m_map3, mapFormat, mapsAniso, true); CreateMap(ref m_map4, mapFormat, mapsAniso, true); //These textures are used to perform the fourier transform CreateBuffer(ref m_fourierBuffer0, fourierTransformformat); //heights CreateBuffer(ref m_fourierBuffer1, fourierTransformformat); // slopes X CreateBuffer(ref m_fourierBuffer2, fourierTransformformat); // slopes Y CreateBuffer(ref m_fourierBuffer3, fourierTransformformat); // displacement X CreateBuffer(ref m_fourierBuffer4, fourierTransformformat); // displacement Y //These textures hold the specturm the fourier transform is performed on m_spectrum01 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, fourierTransformformat); m_spectrum01.filterMode = FilterMode.Point; m_spectrum01.wrapMode = TextureWrapMode.Repeat; m_spectrum01.enableRandomWrite = false; m_spectrum01.Create(); m_spectrum23 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, fourierTransformformat); m_spectrum23.filterMode = FilterMode.Point; m_spectrum23.wrapMode = TextureWrapMode.Repeat; m_spectrum23.enableRandomWrite = false; m_spectrum23.Create(); m_WTable = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, fourierTransformformat); m_WTable.filterMode = FilterMode.Point; m_WTable.wrapMode = TextureWrapMode.Clamp; m_WTable.enableRandomWrite = false; m_WTable.Create(); if (SystemInfo.supportsComputeShaders) { m_varianceRenderTexture = new RenderTexture(m_varianceSize, m_varianceSize, 0, RenderTextureFormat.RHalf); m_varianceRenderTexture.volumeDepth = m_varianceSize; m_varianceRenderTexture.wrapMode = TextureWrapMode.Clamp; m_varianceRenderTexture.filterMode = FilterMode.Bilinear; m_varianceRenderTexture.dimension = UnityEngine.Rendering.TextureDimension.Tex3D; m_varianceRenderTexture.enableRandomWrite = true; m_varianceRenderTexture.useMipMap = true; m_varianceRenderTexture.Create(); } else { m_varianceTexture = new Texture3D (m_varianceSize, m_varianceSize, m_varianceSize, TextureFormat.ARGB32, true); m_varianceTexture.wrapMode = TextureWrapMode.Clamp; m_varianceTexture.filterMode = FilterMode.Bilinear; } } protected void CreateBuffer(ref RenderTexture[] tex, RenderTextureFormat format) { tex = new RenderTexture[2]; for (int i = 0; i < 2; i++) { tex[i] = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); tex[i].filterMode = FilterMode.Point; tex[i].wrapMode = TextureWrapMode.Clamp; tex[i].Create(); } } protected void CreateMap(ref RenderTexture map, RenderTextureFormat format, int ansio, bool useMipMaps) { map = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format); map.filterMode = FilterMode.Trilinear; map.wrapMode = TextureWrapMode.Repeat; map.anisoLevel = ansio; map.useMipMap = useMipMaps; map.Create(); } float sqr(float x) { return x * x; } float omega(float k) { return Mathf.Sqrt(m_gravity * k * (1.0f + sqr(k / WAVE_KM))); } // Eq 24 float Spectrum(float kx, float ky, bool omnispectrum) { //I know this is a big chunk of ugly math but dont worry to much about what it all means //It recreates a statistcally representative model of a wave spectrum in the frequency domain. //How to rotate the windDirection in the spectrum: https://github.com/Scrawk/Ceto/blob/07f8f45955a989983fe2330ea17eaf3f44c82031/Assets/Ceto/Scripts/Spectrum/CustomWaveSpectrumExample.cs#L248-L250 //But I prefere to rotate the Ux and Uy axis, that way can change the wind direction without regenerating spectrum float U10 = m_windSpeed; // phase speed float k = Mathf.Sqrt(kx * kx + ky * ky); float c = omega(k) / k; // spectral peak float kp = m_gravity * sqr(m_omega / U10); // after Eq 3 float cp = omega(kp) / kp; // friction velocity float z0 = 3.7e-5f * sqr(U10) / m_gravity * Mathf.Pow(U10 / cp, 0.9f); // Eq 66 float u_star = 0.41f * U10 / Mathf.Log(10.0f / z0); // Eq 60 float Lpm = Mathf.Exp(-5.0f / 4.0f * sqr(kp / k)); // after Eq 3 float gamma = (m_omega < 1.0f) ? 1.7f : 1.7f + 6.0f * Mathf.Log(m_omega); // after Eq 3 // log10 or log? float sigma = 0.08f * (1.0f + 4.0f / Mathf.Pow(m_omega, 3.0f)); // after Eq 3 float Gamma = Mathf.Exp(-1.0f / (2.0f * sqr(sigma)) * sqr(Mathf.Sqrt(k / kp) - 1.0f)); float Jp = Mathf.Pow(gamma, Gamma); // Eq 3 float Fp = Lpm * Jp * Mathf.Exp(-m_omega / Mathf.Sqrt(10.0f) * (Mathf.Sqrt(k / kp) - 1.0f)); // Eq 32 float alphap = 0.006f * Mathf.Sqrt(m_omega); // Eq 34 float Bl = 0.5f * alphap * cp / c * Fp; // Eq 31 float alpham = 0.01f * (u_star < WAVE_CM ? 1.0f + Mathf.Log(u_star / WAVE_CM) : 1.0f + 3.0f * Mathf.Log(u_star / WAVE_CM)); // Eq 44 float Fm = Mathf.Exp(-0.25f * sqr(k / WAVE_KM - 1.0f)); // Eq 41 float Bh = 0.5f * alpham * WAVE_CM / c * Fm * Lpm; // Eq 40 (fixed) Bh *= Lpm; // bug fix??? if (omnispectrum) return AMP * (Bl + Bh) / (k * sqr(k)); // Eq 30 float a0 = Mathf.Log(2.0f) / 4.0f; float ap = 4.0f; float am = 0.13f * u_star / WAVE_CM; // Eq 59 float Delta = (float) System.Math.Tanh(a0 + ap * Mathf.Pow(c / cp, 2.5f) + am * Mathf.Pow(WAVE_CM / c, 2.5f)); // Eq 57 float phi = Mathf.Atan2(ky, kx); if (kx < 0.0f) return 0.0f; Bl *= 2.0f; Bh *= 2.0f; // remove waves perpendicular to wind dir float tweak = Mathf.Sqrt(Mathf.Max(kx / Mathf.Sqrt(kx * kx + ky * ky), 0.0f)); return AMP * (Bl + Bh) * (1.0f + Delta * Mathf.Cos(2.0f * phi)) / (2.0f * Mathf.PI * sqr(sqr(k))) * tweak; // Eq 67 } Vector2 GetSpectrumSample(float i, float j, float lengthScale, float kMin) { float dk = 2.0f * Mathf.PI / lengthScale; float kx = i * dk; float ky = j * dk; Vector2 result = new Vector2(0.0f, 0.0f); float rnd = UnityEngine.Random.value; if (Mathf.Abs(kx) >= kMin || Mathf.Abs(ky) >= kMin) { float S = Spectrum(kx, ky, false); float h = Mathf.Sqrt(S / 2.0f) * dk; float phi = rnd * 2.0f * Mathf.PI; result.x = h * Mathf.Cos(phi); result.y = h * Mathf.Sin(phi); } return result; } float GetSlopeVariance(float kx, float ky, Vector2 spectrumSample) { float kSquare = kx * kx + ky * ky; float real = spectrumSample.x; float img = spectrumSample.y; float hSquare = real * real + img * img; return kSquare * hSquare * 2.0f; } void GenerateWavesSpectrum() { // Slope variance due to all waves, by integrating over the full spectrum. // Used by the BRDF rendering model float theoreticSlopeVariance = 0.0f; float k = 5e-3f; while (k < 1e3f) { float nextK = k * 1.001f; theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k); k = nextK; } float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4]; float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4]; int idx; float i; float j; float totalSlopeVariance = 0.0f; Vector2 sample12XY; Vector2 sample12ZW; Vector2 sample34XY; Vector2 sample34ZW; UnityEngine.Random.seed = 0; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { idx = x + y * m_fourierGridSize; i = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float) x; j = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float) y; sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x); sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x); sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y); sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z); spectrum01[idx * 4 + 0] = sample12XY.x; spectrum01[idx * 4 + 1] = sample12XY.y; spectrum01[idx * 4 + 2] = sample12ZW.x; spectrum01[idx * 4 + 3] = sample12ZW.y; spectrum23[idx * 4 + 0] = sample34XY.x; spectrum23[idx * 4 + 1] = sample34XY.y; spectrum23[idx * 4 + 2] = sample34ZW.x; spectrum23[idx * 4 + 3] = sample34ZW.y; i *= 2.0f * Mathf.PI; j *= 2.0f * Mathf.PI; totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW); } } //This can be replaced by a texture2D now and the whole thing with a set raw data + apply m_writeFloat.WriteIntoRenderTexture(m_spectrum01, 4, spectrum01); m_writeFloat.WriteIntoRenderTexture(m_spectrum23, 4, spectrum23); if (!SystemInfo.supportsComputeShaders) { // Compute variance for the BRDF, copied from the dx9 project float slopeVarianceDelta = 0.5f * (theoreticSlopeVariance - totalSlopeVariance); m_varianceMax = new Vector2 (float.NegativeInfinity, float.NegativeInfinity); Vector2[, , ] variance32bit = new Vector2[m_varianceSize, m_varianceSize, m_varianceSize]; Color[] variance8bit = new Color[m_varianceSize * m_varianceSize * m_varianceSize]; for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { variance32bit [x, y, z] = ComputeVariance (slopeVarianceDelta, spectrum01, spectrum23, x, y, z); if (variance32bit [x, y, z].x > m_varianceMax.x) m_varianceMax.x = variance32bit [x, y, z].x; if (variance32bit [x, y, z].y > m_varianceMax.y) m_varianceMax.y = variance32bit [x, y, z].y; } } } for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { idx = x + y * m_varianceSize + z * m_varianceSize * m_varianceSize; variance8bit [idx] = new Color (variance32bit [x, y, z].x / m_varianceMax.x, variance32bit [x, y, z].y / m_varianceMax.y, 0.0f, 1.0f); } } } m_varianceTexture.SetPixels (variance8bit); m_varianceTexture.Apply (); m_maxSlopeVariance = 0.0f; for (int v = 0; v < m_varianceSize*m_varianceSize*m_varianceSize; v++) { m_maxSlopeVariance = Mathf.Max (m_maxSlopeVariance, variance8bit [v].r * m_varianceMax.x); m_maxSlopeVariance = Mathf.Max (m_maxSlopeVariance, variance8bit [v].g * m_varianceMax.y); } } else { m_varianceShader = ShaderReplacer.Instance.LoadedComputeShaders["SlopeVariance"]; m_varianceShader.SetFloat("_SlopeVarianceDelta", 0.5f * (theoreticSlopeVariance - totalSlopeVariance)); m_varianceShader.SetFloat("_VarianceSize", (float)m_varianceSize); m_varianceShader.SetFloat("_Size", m_fsize); m_varianceShader.SetVector("_GridSizes", m_gridSizes); m_varianceShader.SetTexture(0, "_Spectrum01", m_spectrum01); m_varianceShader.SetTexture(0, "_Spectrum23", m_spectrum23); m_varianceShader.SetTexture(0, "des", m_varianceRenderTexture); m_varianceShader.Dispatch(0,m_varianceSize/4,m_varianceSize/4,m_varianceSize/4); //Find the maximum value for slope variance ComputeBuffer buffer = new ComputeBuffer(m_varianceSize*m_varianceSize*m_varianceSize, sizeof(float)); CBUtility.ReadFromRenderTexture(m_varianceRenderTexture, 1, buffer, ShaderReplacer.Instance.LoadedComputeShaders["ReadData"]); float[] varianceData = new float[m_varianceSize*m_varianceSize*m_varianceSize]; buffer.GetData(varianceData); m_maxSlopeVariance = 0.0f; for(int v = 0; v < m_varianceSize*m_varianceSize*m_varianceSize; v++) { m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, varianceData[v]); } buffer.Release(); } } void CreateWTable() { //Some values need for the InitWaveSpectrum function can be precomputed Vector2 uv, st; float k1, k2, k3, k4, w1, w2, w3, w4; float[] table = new float[m_fourierGridSize * m_fourierGridSize * 4]; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { uv = new Vector2(x, y) / m_fsize; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; k1 = (st * m_inverseGridSizes.x).magnitude; k2 = (st * m_inverseGridSizes.y).magnitude; k3 = (st * m_inverseGridSizes.z).magnitude; k4 = (st * m_inverseGridSizes.w).magnitude; w1 = Mathf.Sqrt(m_gravity * k1 * (1.0f + k1 * k1 / (WAVE_KM * WAVE_KM))); w2 = Mathf.Sqrt(m_gravity * k2 * (1.0f + k2 * k2 / (WAVE_KM * WAVE_KM))); w3 = Mathf.Sqrt(m_gravity * k3 * (1.0f + k3 * k3 / (WAVE_KM * WAVE_KM))); w4 = Mathf.Sqrt(m_gravity * k4 * (1.0f + k4 * k4 / (WAVE_KM * WAVE_KM))); table[(x + y * m_fourierGridSize) * 4 + 0] = w1; table[(x + y * m_fourierGridSize) * 4 + 1] = w2; table[(x + y * m_fourierGridSize) * 4 + 2] = w3; table[(x + y * m_fourierGridSize) * 4 + 3] = w4; } } m_writeFloat.WriteIntoRenderTexture(m_WTable, 4, table); } Vector2 GetSpectrum(float t, float w, float s0x, float s0y, float s0cx, float s0cy) { float c = Mathf.Cos(w * t); float s = Mathf.Sin(w * t); return new Vector2((s0x + s0cx) * c - (s0y + s0cy) * s, (s0x - s0cx) * s + (s0y - s0cy) * c); } Vector2 COMPLEX(Vector2 z) { return new Vector2(-z.y, z.x); // returns i times z (complex number) } int BitReverse(int i) { int j = i; int Sum = 0; int W = 1; int M = m_fourierGridSize / 2; while (M != 0) { j = ((i & M) > M - 1) ? 1 : 0; Sum += j * W; W *= 2; M /= 2; } return Sum; } //FixedUpdate is responsible for physics, apply part displacement here public void FixedUpdate() { if (waveInteractionHandler != null && prolandManager.GetSkyNode().simulateOceanInteraction) { waterHeightAtCameraPosition = waveInteractionHandler.UpdateInteractions(height, waterHeightAtCameraPosition, ux.ToVector3(), uy.ToVector3(), offsetVector3); } } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/OceanNode.cs ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. * * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. * Modified and ported to Unity by Justin Hawkins 2014 * * */ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using UnityEngine.Rendering; using KSP.IO; using UnityEngine.XR; namespace Scatterer { //TODO: refactor and clean up this class public abstract class OceanNode: MonoBehaviour { public UrlDir.UrlConfig configUrl; public ProlandManager prolandManager; public Material m_oceanMaterial; OceanRenderingHook oceanRenderingHook; [Persistent] public Vector3 m_oceanUpwellingColor = new Vector3 (0.0039f, 0.0156f, 0.047f); [Persistent] public Vector3 m_UnderwaterColor = new Vector3 (0.1f, 0.75f, 0.8f); //Size of each grid in the projected grid. (number of pixels on screen) public int m_resolution = 4; int m_screenWidth; int m_screenHeight; [Persistent] public float offScreenVertexStretch = 1.25f; [Persistent] public float alphaRadius = 3000f; [Persistent] public float transparencyDepth = 60f; [Persistent] public float darknessDepth = 1000f; [Persistent] public float refractionIndex = 1.33f; [Persistent] public float skyReflectionStrength = 1f; public bool isUnderwater = false; bool underwaterMode = false; bool oceanDraw = true; public int numGrids; Mesh[] m_screenGrids; GameObject[] waterGameObjects; public MeshRenderer[] waterMeshRenderers; MeshFilter[] waterMeshFilters; public GenericLocalAtmosphereContainer underwaterScattering; public Material underwaterMaterial; public Vector3 offsetVector3{ get { return offset.ToVector3(); } } public double height = 0; public Vector3d2 m_Offset = Vector3d2.Zero(); public Vector3d2 offset = Vector3d2.Zero(), ux=Vector3d2.Zero(), uy=Vector3d2.Zero(), uz=Vector3d2.Zero(), oo=Vector3d2.Zero(); OceanCameraUpdateHook oceanCameraProjectionMatModifier; UnderwaterDimmingHook underwaterDimmingHook; public float planetOpacity=1f; //planetOpacity to fade out the ocean when PQS is fading out //Concrete classes must provide a function that returns the //variance of the waves need for the BRDF rendering of waves public abstract float GetMaxSlopeVariance (); //caustics [Persistent] public string causticsTexturePath=""; [Persistent] public Vector2 causticsLayer1Scale; [Persistent] public Vector2 causticsLayer1Speed; [Persistent] public Vector2 causticsLayer2Scale; [Persistent] public Vector2 causticsLayer2Speed; [Persistent] public float causticsMultiply; [Persistent] public float causticsUnderwaterLightBoost; [Persistent] public float causticsMinBrightness; [Persistent] public float causticsBlurDepth; [Persistent] public float lightRaysStrength=1f; public CausticsShadowMaskModulate causticsShadowMaskModulator; public CausticsLightRaysRenderer causticsLightRaysRenderer; protected float waterHeightAtCameraPosition = 0f; public virtual void Init (ProlandManager manager) { m_resolution = Scatterer.Instance.mainSettings.oceanMeshResolution; m_screenWidth = Screen.width; m_screenHeight = Screen.height; if (XRSettings.loadedDeviceName != string.Empty) { m_screenWidth = Math.Max(m_screenWidth, XRSettings.eyeTextureWidth); m_screenHeight = Math.Max(m_screenHeight, XRSettings.eyeTextureHeight); } prolandManager = manager; loadFromConfigNode (); InitOceanMaterial (); //Worth moving to projected Grid Class? CreateProjectedGridMeshes (true); oceanCameraProjectionMatModifier = waterGameObjects[0].AddComponent(); oceanCameraProjectionMatModifier.oceanNode = this; oceanRenderingHook = waterGameObjects[0].AddComponent(); oceanRenderingHook.targetMaterial = m_oceanMaterial; oceanRenderingHook.targetRenderer = waterMeshRenderers [0]; oceanRenderingHook.celestialBodyName = prolandManager.parentCelestialBody.name; DisableEffectsChecker disableEffectsChecker = waterGameObjects[0].AddComponent(); disableEffectsChecker.manager = this.prolandManager; if (Scatterer.Instance.mainSettings.shadowsOnOcean || Scatterer.Instance.mainSettings.oceanLightRays) { ShadowMapRetrieveCommandBuffer retriever = prolandManager.mainSunLight.gameObject.GetComponent(); if (!retriever) prolandManager.mainSunLight.gameObject.AddComponent (typeof(ShadowMapRetrieveCommandBuffer)); } InitUnderwaterMaterial (); underwaterScattering = new ScreenSpaceScatteringContainer(underwaterMaterial,prolandManager.parentLocalTransform,(float)prolandManager.m_radius, prolandManager, false); //this shouldn't need quarter res as it isn't expensive underwaterScattering.SetInScaledSpace(false); underwaterScattering.SetActivated(false); underwaterScattering.UpdateContainer (); //dimming //TODO: maybe this can be changed, instead of complicated hooks on the Camera, add it to the light, like causticsShadowMaskModulate? if ((Scatterer.Instance.mainSettings.underwaterLightDimming || Scatterer.Instance.mainSettings.oceanCaustics) && (HighLogic.LoadedScene != GameScenes.MAINMENU)) { underwaterDimmingHook = (UnderwaterDimmingHook) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(UnderwaterDimmingHook)); underwaterDimmingHook.oceanNode = this; } if (Scatterer.Instance.mainSettings.oceanCaustics && (HighLogic.LoadedScene == GameScenes.FLIGHT)) { //why doesn't this work with IVA camera? do they have a separate light? causticsShadowMaskModulator = (CausticsShadowMaskModulate) prolandManager.mainSunLight.gameObject.AddComponent (typeof(CausticsShadowMaskModulate)); if(!causticsShadowMaskModulator.Init(causticsTexturePath, causticsLayer1Scale, causticsLayer1Speed, causticsLayer2Scale, causticsLayer2Speed, causticsMultiply, causticsMinBrightness, (float)manager.GetRadius(), causticsBlurDepth, prolandManager.mainSunLight)) { UnityEngine.Object.DestroyImmediate (causticsShadowMaskModulator); causticsShadowMaskModulator = null; } if (Scatterer.Instance.mainSettings.oceanLightRays) { causticsLightRaysRenderer = (CausticsLightRaysRenderer) waterGameObjects[0].AddComponent(); if (!causticsLightRaysRenderer.Init(causticsTexturePath, causticsLayer1Scale, causticsLayer1Speed, causticsLayer2Scale, causticsLayer2Speed, causticsMultiply, causticsMinBrightness, (float)manager.GetRadius(), causticsBlurDepth, this, lightRaysStrength)) { UnityEngine.Object.DestroyImmediate (causticsLightRaysRenderer); causticsLightRaysRenderer = null; } } } } public virtual void UpdateNode () { oceanDraw = !MapView.MapIsEnabled && !prolandManager.skyNode.inScaledSpace; foreach (MeshRenderer _mr in waterMeshRenderers) { _mr.enabled = oceanDraw; } isUnderwater = height < waterHeightAtCameraPosition; underwaterScattering.SetActivated(isUnderwater); if (underwaterMode ^ isUnderwater) { toggleUnderwaterMode(); } if (causticsShadowMaskModulator) { causticsShadowMaskModulator.isEnabled = oceanDraw && (prolandManager.GetSkyNode().altitude < 6000f); causticsShadowMaskModulator.UpdateCaustics (); } } public void updateNonCameraSpecificUniforms (Material oceanMaterial) { prolandManager.GetSkyNode ().SetOceanUniforms (oceanMaterial); if (underwaterMode) { prolandManager.GetSkyNode ().UpdatePostProcessMaterialUniforms (underwaterMaterial); } planetOpacity = 1f - prolandManager.parentCelestialBody.pqsController.surfaceMaterial.GetFloat (ShaderProperties._PlanetOpacity_PROPERTY); m_oceanMaterial.SetFloat (ShaderProperties._PlanetOpacity_PROPERTY, planetOpacity); m_oceanMaterial.SetInt (ShaderProperties._ZwriteVariable_PROPERTY, 1); } public void OnPreCull() { if (!MapView.MapIsEnabled && Scatterer.Instance.nearCamera && prolandManager.skyNode.simulateOceanInteraction) { updateNonCameraSpecificUniforms(m_oceanMaterial); } } void CreateProjectedGridMeshes (bool use32BitIndexMesh) { //Create the projected grid. The resolution is the size in pixels //of each square in the grid. If not using 32-bit index meshes, the verts of //the mesh will exceed the max verts for a mesh in Unity. In this case //split the mesh up into smaller meshes. m_resolution = Mathf.Max (1, m_resolution); //The number of squares in the grid on the x and y axis int NX = m_screenWidth / m_resolution; int NY = m_screenHeight / m_resolution; numGrids = 1; const int MAX_VERTS = 65000; //The number of meshes need to make a grid of this resolution, if not using 32-bit index meshes if (!use32BitIndexMesh && (NX * NY > MAX_VERTS)) { numGrids += (NX * NY) / MAX_VERTS; } m_screenGrids = new Mesh[numGrids]; waterGameObjects = new GameObject[numGrids]; waterMeshRenderers = new MeshRenderer[numGrids]; waterMeshFilters = new MeshFilter[numGrids]; //Make the meshes. The end product will be a grid of verts that cover //the screen on the x and y axis with the z depth at 0. This grid is then //projected as the ocean by the shader for (int i = 0; i < numGrids; i++) { NY = m_screenHeight / numGrids / m_resolution; if (use32BitIndexMesh) m_screenGrids [i] = MeshFactory.MakePlane32BitIndexFormat (NX, NY, MeshFactory.PLANE.XY, false, true, (float)i / (float)numGrids, 1.0f / (float)numGrids); else m_screenGrids [i] = MeshFactory.MakePlane (NX, NY, MeshFactory.PLANE.XY, false, true, (float)i / (float)numGrids, 1.0f / (float)numGrids); m_screenGrids [i].bounds = new Bounds (Vector3.zero, new Vector3 (1e8f, 1e8f, 1e8f)); waterGameObjects [i] = new GameObject (); waterGameObjects [i].transform.position = prolandManager.parentCelestialBody.transform.position; waterGameObjects [i].transform.parent = prolandManager.parentCelestialBody.transform; //might be redundant waterMeshFilters [i] = waterGameObjects [i].AddComponent (); waterMeshFilters [i].mesh.Clear (); waterMeshFilters [i].mesh = m_screenGrids [i]; waterGameObjects [i].layer = 15; waterMeshRenderers [i] = waterGameObjects [i].AddComponent (); if (Scatterer.Instance.mainSettings.oceanPixelLights) { m_oceanMaterial.SetPass (1); //Disable the main pass so we can render it with our commandbuffer. Pixel light passes render after scattering in depth buffer mode, and before scattering in projector mode waterMeshRenderers [i].sharedMaterial = m_oceanMaterial; waterMeshRenderers [i].material = m_oceanMaterial; } else { waterMeshRenderers [i].material = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/invisible")]); } waterMeshRenderers [i].receiveShadows = Scatterer.Instance.mainSettings.shadowsOnOcean && (QualitySettings.shadows != ShadowQuality.Disable); waterMeshRenderers [i].shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; waterMeshRenderers [i].enabled = true; } } void InitOceanMaterial () { m_oceanMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/OceanWhiteCaps")]); Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "SKY_REFLECTIONS_ON", "SKY_REFLECTIONS_OFF", Scatterer.Instance.mainSettings.oceanSkyReflections); Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "PLANETSHINE_ON", "PLANETSHINE_OFF", (prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine); if (Scatterer.Instance.mainSettings.shadowsOnOcean && (QualitySettings.shadows != ShadowQuality.Disable)) { Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "OCEAN_SHADOWS_HARD", "OCEAN_SHADOWS_SOFT", (QualitySettings.shadows == ShadowQuality.HardOnly)); m_oceanMaterial.DisableKeyword ("OCEAN_SHADOWS_OFF"); } else { m_oceanMaterial.EnableKeyword ("OCEAN_SHADOWS_OFF"); m_oceanMaterial.DisableKeyword ("OCEAN_SHADOWS_HARD"); m_oceanMaterial.DisableKeyword ("OCEAN_SHADOWS_SOFT"); } m_oceanMaterial.EnableKeyword("DEPTH_BUFFER_MODE_ON"); m_oceanMaterial.DisableKeyword("PROJECTOR_MODE"); m_oceanMaterial.DisableKeyword("PROJECTOR_MODE_GODRAYS"); Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "DEPTH_BUFFER_MODE_ON", "DEPTH_BUFFER_MODE_OFF", true); m_oceanMaterial.SetOverrideTag ("IgnoreProjector", "True"); if (!Scatterer.Instance.unifiedCameraMode && DepthToDistanceCommandBuffer.RenderTexture != null) m_oceanMaterial.SetTexture(ShaderProperties._customDepthTexture_PROPERTY, DepthToDistanceCommandBuffer.RenderTexture); m_oceanMaterial.renderQueue=2502; m_oceanMaterial.SetVector (ShaderProperties._Ocean_Color_PROPERTY, m_oceanUpwellingColor); m_oceanMaterial.SetVector ("_Underwater_Color", m_UnderwaterColor); m_oceanMaterial.SetVector (ShaderProperties._Ocean_ScreenGridSize_PROPERTY, new Vector2 ((float)m_resolution / (float)m_screenWidth, (float)m_resolution / (float)m_screenHeight)); //oceanMaterial.SetFloat (ShaderProperties._Ocean_Radius_PROPERTY, (float)(radius+m_oceanLevel)); m_oceanMaterial.SetFloat (ShaderProperties._Ocean_Radius_PROPERTY, (float)(prolandManager.GetRadius())); m_oceanMaterial.SetFloat (ShaderProperties.alphaRadius_PROPERTY, alphaRadius); m_oceanMaterial.SetFloat ("skyReflectionStrength", skyReflectionStrength); m_oceanMaterial.SetFloat ("refractionIndex", refractionIndex); //these don't need to be updated every frame m_oceanMaterial.SetFloat ("transparencyDepth", transparencyDepth); m_oceanMaterial.SetFloat ("darknessDepth", darknessDepth); float camerasOverlap = 0f; if (!Scatterer.Instance.unifiedCameraMode) camerasOverlap = Scatterer.Instance.nearCamera.farClipPlane - Scatterer.Instance.farCamera.nearClipPlane; m_oceanMaterial.SetFloat("_ScattererCameraOverlap",camerasOverlap); m_oceanMaterial.SetFloat ("offScreenVertexStretch", offScreenVertexStretch); } void InitUnderwaterMaterial () { underwaterMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/UnderwaterScatterDepthBuffer")]); underwaterMaterial.renderQueue = 2502; //draw over fairings which is 2450 and over ocean which is 2501 underwaterMaterial.SetFloat ("transparencyDepth", transparencyDepth); underwaterMaterial.SetFloat ("darknessDepth", darknessDepth); underwaterMaterial.SetVector ("_Underwater_Color", m_UnderwaterColor); underwaterMaterial.SetFloat ("Rg",(float)prolandManager.m_radius); Utils.EnableOrDisableShaderKeywords (underwaterMaterial, "DITHERING_ON", "DITHERING_OFF", Scatterer.Instance.mainSettings.useDithering); } void toggleUnderwaterMode() { if (underwaterMode) //switch to over water { underwaterScattering.SetActivated(false); underwaterScattering.UpdateContainer (); m_oceanMaterial.EnableKeyword("UNDERWATER_OFF"); m_oceanMaterial.DisableKeyword("UNDERWATER_ON"); prolandManager.GetSkyNode().SetUnderwater(false); } else //switch to underwater { underwaterScattering.SetActivated(true); underwaterScattering.UpdateContainer (); m_oceanMaterial.EnableKeyword("UNDERWATER_ON"); m_oceanMaterial.DisableKeyword("UNDERWATER_OFF"); prolandManager.GetSkyNode().SetUnderwater(true); } underwaterMode = !underwaterMode; } public virtual void OnDestroy () { if (oceanCameraProjectionMatModifier) { Component.Destroy (oceanCameraProjectionMatModifier); UnityEngine.Object.Destroy (oceanCameraProjectionMatModifier); } for (int i = 0; i < numGrids; i++) { DestroyImmediate(waterGameObjects[i]); Component.DestroyImmediate(waterMeshFilters[i]); Component.DestroyImmediate(waterMeshRenderers[i]); UnityEngine.Object.DestroyImmediate(m_screenGrids [i]); } UnityEngine.Object.DestroyImmediate(m_oceanMaterial); UnityEngine.Object.DestroyImmediate(underwaterMaterial); if (underwaterDimmingHook) Component.DestroyImmediate(underwaterDimmingHook); if (underwaterScattering!=null) { underwaterScattering.Cleanup(); } if (causticsShadowMaskModulator) { UnityEngine.Object.DestroyImmediate (causticsShadowMaskModulator); } if (causticsLightRaysRenderer) { UnityEngine.Object.DestroyImmediate(causticsLightRaysRenderer); } if (oceanRenderingHook) { Component.DestroyImmediate(oceanRenderingHook); } } public void applyUnderwaterDimming () //called OnPostRender of scaledSpace Camera by hook, needs to be done before farCamera onPreCull where the color is set { if (!MapView.MapIsEnabled && isUnderwater) { float finalDim = 1f; if (Scatterer.Instance.mainSettings.underwaterLightDimming) { float underwaterDim = Mathf.Abs(Vector3.Distance (Scatterer.Instance.nearCamera.transform.position, prolandManager.parentLocalTransform.position)-(float)prolandManager.m_radius); underwaterDim = Mathf.Lerp(1.0f,0.0f,underwaterDim / darknessDepth); finalDim*=underwaterDim; } if (causticsShadowMaskModulator) { finalDim*=causticsUnderwaterLightBoost; //replace by caustics multiplier } Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByAttenuation(prolandManager.mainSunLight, finalDim); } } public void saveToConfigNode () { ConfigNode[] configNodeArray; bool found = false; configNodeArray = configUrl.config.GetNodes("Ocean"); foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name") && _cn.GetValue("name") == prolandManager.parentCelestialBody.name) { ConfigNode cnTemp = ConfigNode.CreateConfigFromObject (this); _cn.ClearData(); ConfigNode.Merge (_cn, cnTemp); _cn.name="Ocean"; Utils.LogDebug("saving "+prolandManager.parentCelestialBody.name+ " ocean config to: "+configUrl.parent.url); configUrl.parent.SaveConfigs (); found=true; break; } } if (!found) { Utils.LogDebug("couldn't find config file to save to"); } } public void loadFromConfigNode () { ConfigNode cnToLoad = new ConfigNode(); ConfigNode[] configNodeArray; bool found = false; foreach (UrlDir.UrlConfig _url in Scatterer.Instance.planetsConfigsReader.oceanConfigs) { configNodeArray = _url.config.GetNodes("Ocean"); foreach(ConfigNode _cn in configNodeArray) { if (_cn.HasValue("name") && _cn.GetValue("name") == prolandManager.parentCelestialBody.name) { cnToLoad = _cn; configUrl = _url; found = true; break; } } } if (found) { Utils.LogDebug("Ocean config found for: "+prolandManager.parentCelestialBody.name); ConfigNode.LoadObjectFromConfig (this, cnToLoad); } else { Utils.LogDebug("Ocean config not found for: "+prolandManager.parentCelestialBody.name); Utils.LogDebug("Removing ocean for "+prolandManager.parentCelestialBody.name +" from planets list"); (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Find(_cb => _cb.celestialBodyName == prolandManager.parentCelestialBody.name)).hasOcean = false; UnityEngine.Component.DestroyImmediate (this); } } public void setWaterMeshrenderersEnabled (bool enabled) { for (int i=0; i < numGrids; i++) { waterMeshRenderers[i].enabled=enabled && oceanDraw; } } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/OceanRenderingHook.cs ================================================ using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; namespace Scatterer { public class OceanRenderingHook : MonoBehaviour { public bool isEnabled = false; public OceanRenderingHook () { } public MeshRenderer targetRenderer; public Material targetMaterial; public string celestialBodyName; //Dictionary to check if we added the OceanCommandBuffer to the camera private Dictionary cameraToOceanCommandBuffer = new Dictionary(); void OnWillRenderObject() { Camera cam = Camera.current; if (!cam || !targetRenderer || !targetMaterial) return; // Render ocean MeshRenderer for this frame // If projector mode render directly to screen // If depth buffer mode render to separate buffer so we can have the ocean's color and depth to be used by the scattering shader if (cameraToOceanCommandBuffer.ContainsKey (cam)) { if (cameraToOceanCommandBuffer[cam] != null) { cameraToOceanCommandBuffer[cam].EnableForThisFrame(); // Enable screen copying for this frame if (Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions && (cam == Scatterer.Instance.farCamera || cam == Scatterer.Instance.nearCamera)) ScreenCopyCommandBuffer.EnableScreenCopyForFrame(cam); } } else { //we add null to the cameras we don't want to render on so we don't do a string compare every time if ((cam.name == "TRReflectionCamera") || (cam.name=="Reflection Probes Camera") || (cam.name == "DepthCamera") || (cam.name == "NearCamera")) { cameraToOceanCommandBuffer[cam] = null; } else { OceanCommandBuffer oceanCommandBuffer = (OceanCommandBuffer) cam.gameObject.AddComponent(typeof(OceanCommandBuffer)); oceanCommandBuffer.targetRenderer = targetRenderer; oceanCommandBuffer.targetMaterial = targetMaterial; oceanCommandBuffer.celestialBodyName = celestialBodyName; oceanCommandBuffer.Initialize(); oceanCommandBuffer.EnableForThisFrame(); cameraToOceanCommandBuffer[cam] = oceanCommandBuffer; } } } public void OnDestroy () { foreach (OceanCommandBuffer oceanCommandBuffer in cameraToOceanCommandBuffer.Values) { if (oceanCommandBuffer) Component.DestroyImmediate(oceanCommandBuffer); } } } public class OceanCommandBuffer : MonoBehaviour { bool renderingEnabled = false; bool hdrEnabled = false; public MeshRenderer targetRenderer; public Material targetMaterial; public string celestialBodyName; private Camera targetCamera; private CommandBuffer rendererCommandBuffer; private int oceanRenderTextureNameID, depthCopyRenderTextureNameID; private Material copyCameraDepthMaterial; bool oceanScreenShotModeEnabled = false; public void Initialize() { targetCamera = GetComponent(); copyCameraDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders["Scatterer/CopyCameraDepth"]); rendererCommandBuffer = new CommandBuffer(); rendererCommandBuffer.name = "Ocean MeshRenderer CommandBuffer"; oceanRenderTextureNameID = Shader.PropertyToID(nameof(oceanRenderTextureNameID)); depthCopyRenderTextureNameID = Shader.PropertyToID(nameof(depthCopyRenderTextureNameID)); RecreateCommandBuffer(); } private void RecreateCommandBuffer() { rendererCommandBuffer.Clear(); // review: not sure if these automatically generate mips. // might need to use the overload that takes RenderTextureDescriptor to disable them rendererCommandBuffer.GetTemporaryRT( depthCopyRenderTextureNameID, -1, -1, // width, height: use camera dimensions 0, // depth buffer bits FilterMode.Point, RenderTextureFormat.RFloat); rendererCommandBuffer.GetTemporaryRT( oceanRenderTextureNameID, -1, -1, // width, height: use camera dimensions 0, // depth buffer bits FilterMode.Point, hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32); // Init depth render texture rendererCommandBuffer.Blit(null, depthCopyRenderTextureNameID, copyCameraDepthMaterial, 3); // Draw ocean renderer, output as normal to the screen, and ocean depth to the depth texture RenderTargetIdentifier[] oceanRenderTargets = { new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget), new RenderTargetIdentifier(depthCopyRenderTextureNameID) }; rendererCommandBuffer.SetRenderTarget(oceanRenderTargets, BuiltinRenderTextureType.CameraTarget); rendererCommandBuffer.DrawRenderer(targetRenderer, targetMaterial, 0, 0); //this doesn't work with pixel lights so render only the main pass here and render pixel lights the regular way //they will render on top of depth buffer scattering but that's not a noticeable issue, especially since ocean lights are soft additive // expose the new depth buffer rendererCommandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); rendererCommandBuffer.SetGlobalTexture("ScattererDepthCopy", depthCopyRenderTextureNameID); // enable cloud shadows rendererCommandBuffer.SetGlobalFloat(ShaderProperties.render_ocean_cloud_shadow_PROPERTY, 1f); // draw cloud shadows if (Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName)) { foreach (var clouds2d in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName]) { if (clouds2d.CloudShadowMaterial != null) { rendererCommandBuffer.Blit(null, BuiltinRenderTextureType.CameraTarget, clouds2d.CloudShadowMaterial); } } } // disable it for regular cloud shadows rendererCommandBuffer.SetGlobalFloat(ShaderProperties.render_ocean_cloud_shadow_PROPERTY, 0f); // recopy the screen and expose it as input for the scattering rendererCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, new RenderTargetIdentifier(oceanRenderTextureNameID)); // then set the textures for the scattering shader rendererCommandBuffer.SetGlobalTexture("ScattererScreenCopy", oceanRenderTextureNameID); } public void EnableForThisFrame() { if (!renderingEnabled) { if (hdrEnabled != targetCamera.allowHDR) { RecreateCommandBuffer(); } targetCamera.AddCommandBuffer(CameraEvent.AfterImageEffectsOpaque, rendererCommandBuffer); //ocean renders on AfterImageEffectsOpaque, local scattering (with it's depth downscale) can render and copy to screen on afterForwardAlpha renderingEnabled = true; } } void OnPostRender() { if (renderingEnabled && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left) { targetCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffectsOpaque, rendererCommandBuffer); renderingEnabled = false; } } public void OnDestroy () { if (targetCamera && rendererCommandBuffer != null) { targetCamera.RemoveCommandBuffer (CameraEvent.AfterImageEffectsOpaque, rendererCommandBuffer); rendererCommandBuffer.Release(); rendererCommandBuffer = null; renderingEnabled = false; } } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/OceanWhiteCaps.cs ================================================ using UnityEngine; using System.Collections; namespace Scatterer { /* * Extend the OceanFFT node to also generate ocean white caps. */ public class OceanWhiteCaps: OceanFFTgpu { [Persistent] protected string name; Material m_initJacobiansMat; Material m_whiteCapsPrecomputeMat; RenderTexture[] m_fourierBuffer5, m_fourierBuffer6, m_fourierBuffer7; int foamAniso = 9; RenderTexture m_foam0, m_foam1; public override void Init(ProlandManager manager) { base.Init(manager); m_initJacobiansMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitJacobians")]); m_whiteCapsPrecomputeMat = new Material(ShaderReplacer.Instance.LoadedShaders[("Proland/Ocean/WhiteCapsPrecompute0")]); m_initJacobiansMat.SetTexture(ShaderProperties._Spectrum01_PROPERTY, m_spectrum01); m_initJacobiansMat.SetTexture(ShaderProperties._Spectrum23_PROPERTY, m_spectrum23); m_initJacobiansMat.SetTexture(ShaderProperties._WTable_PROPERTY, m_WTable); m_initJacobiansMat.SetVector (ShaderProperties._Offset_PROPERTY, m_spectrumOffset); m_initJacobiansMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes); m_oceanMaterial.SetFloat (ShaderProperties._Ocean_WhiteCapStr_PROPERTY, m_whiteCapStr); m_oceanMaterial.SetFloat (ShaderProperties.farWhiteCapStr_PROPERTY, m_farWhiteCapStr); m_oceanMaterial.SetTexture(ShaderProperties._Ocean_Foam0_PROPERTY, m_foam0); m_oceanMaterial.SetTexture(ShaderProperties._Ocean_Foam1_PROPERTY, m_foam1); m_oceanMaterial.SetFloat (ShaderProperties.shoreFoam_PROPERTY, shoreFoam); Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "FOAM_ON", "FOAM_OFF", true); } protected override void CreateRenderTextures() { RenderTextureFormat format = RenderTextureFormat.ARGBHalf; CreateMap(ref m_foam0, format, foamAniso, true); CreateMap(ref m_foam1, format, foamAniso, true); m_foam1.mipMapBias = m_foamMipMapBias; //These textures are used to perform the fourier transform CreateBuffer(ref m_fourierBuffer5, format); // Jacobians XX CreateBuffer(ref m_fourierBuffer6, format); // Jacobians YY CreateBuffer(ref m_fourierBuffer7, format); // Jacobians XY //Make sure the base textures are also created base.CreateRenderTextures(); } public override void OnDestroy() { base.OnDestroy(); m_foam0.Release(); m_foam1.Release(); for (int i = 0; i < 2; i++) { m_fourierBuffer5[i].Release(); m_fourierBuffer6[i].Release(); m_fourierBuffer7[i].Release(); } } protected override void InitWaveSpectrum(float t) { base.InitWaveSpectrum(t); // Init jacobians (5,6,7) RenderTexture[] buffers567 = new RenderTexture[]{m_fourierBuffer5[1], m_fourierBuffer6[1], m_fourierBuffer7[1]}; m_initJacobiansMat.SetFloat (ShaderProperties._T_PROPERTY, t); RTUtility.MultiTargetBlit(buffers567, m_initJacobiansMat, 0); } public override void UpdateNode() { base.UpdateNode(); if (!MapView.MapIsEnabled && prolandManager.skyNode.simulateOceanInteraction) { m_fourier.PeformFFT(m_fourierBuffer5, m_fourierBuffer6, m_fourierBuffer7); //fixed block, two passes, fixes mipmapping issue resulting in black ocean m_whiteCapsPrecomputeMat.SetTexture(ShaderProperties._Map5_PROPERTY, m_fourierBuffer5[m_idx]); m_whiteCapsPrecomputeMat.SetTexture(ShaderProperties._Map6_PROPERTY, m_fourierBuffer6[m_idx]); m_whiteCapsPrecomputeMat.SetTexture(ShaderProperties._Map7_PROPERTY, m_fourierBuffer7[m_idx]); m_whiteCapsPrecomputeMat.SetVector (ShaderProperties._Choppyness_PROPERTY, m_choppyness); //RenderTexture[] buffers = new RenderTexture[] {m_foam0, m_foam1}; //RTUtility.MultiTargetBlit(buffers, m_whiteCapsPrecomputeMat, 0); //causes mipmapping issue resulting in black ocean Graphics.Blit (null, m_foam0, m_whiteCapsPrecomputeMat, 0); Graphics.Blit (null, m_foam1, m_whiteCapsPrecomputeMat, 1); } } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/UnderwaterDimmingHook.cs ================================================ using UnityEngine; namespace Scatterer { public class UnderwaterDimmingHook : MonoBehaviour { public OceanNode oceanNode; public void OnPostRender() { oceanNode.applyUnderwaterDimming (); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Utils/CBUtility.cs ================================================ using UnityEngine; using UnityEngine.Rendering; using System; using System.IO; namespace Scatterer { static public class CBUtility { public static ComputeBuffer CreateArgBuffer(int vertexCountPerInstance, int instanceCount, int startVertex, int startInstance) { ComputeBuffer buffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments); int[] args = new int[] { vertexCountPerInstance, instanceCount, startVertex, startInstance }; buffer.SetData(args); return buffer; } public static int GetVertexCountPerInstance(ComputeBuffer buffer) { int[] args = new int[] { 0, 0, 0, 0 }; buffer.GetData(args); return args[0]; } private static string[,] readNames2D = new string[,] { {"read2DC1", "_Tex2D", "_Buffer2DC1"}, {"read2DC2", "_Tex2D", "_Buffer2DC2"}, {"read2DC3", "_Tex2D", "_Buffer2DC3"}, {"read2DC4", "_Tex2D", "_Buffer2DC4"} }; private static string[,] readNames3D = new string[,] { {"read3DC1", "_Tex3D", "_Buffer3DC1"}, {"read3DC2", "_Tex3D", "_Buffer3DC2"}, {"read3DC3", "_Tex3D", "_Buffer3DC3"}, {"read3DC4", "_Tex3D", "_Buffer3DC4"} }; public static void ReadFromRenderTexture(RenderTexture tex, int channels, ComputeBuffer buffer, ComputeShader readData) { if (tex == null) throw new ArgumentException("RenderTexture is null"); if (buffer == null) throw new ArgumentException("Buffer is null"); if (readData == null) throw new ArgumentException("Computer shader is null"); if (channels < 1 || channels > 4) throw new ArgumentException("Channels must be 1, 2, 3, or 4"); if (!tex.IsCreated()) throw new ArgumentException("Tex has not been created (Call Create() on tex)"); int kernel = -1; int depth = 1; if(tex.dimension == TextureDimension.Tex3D) { depth = tex.volumeDepth; kernel = readData.FindKernel(readNames3D[channels - 1, 0]); readData.SetTexture(kernel, readNames3D[channels - 1, 1], tex); readData.SetBuffer(kernel, readNames3D[channels - 1, 2], buffer); } else { kernel = readData.FindKernel(readNames2D[channels - 1, 0]); readData.SetTexture(kernel, readNames2D[channels - 1, 1], tex); readData.SetBuffer(kernel, readNames2D[channels - 1, 2], buffer); } if (kernel == -1) throw new ArgumentException("Could not find kernel " + readNames2D[channels - 1, 0]); int width = tex.width; int height = tex.height; readData.SetInt("_Width", width); readData.SetInt("_Height", height); readData.SetInt("_Depth", depth); //run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need //some extra threadBlocks. This will result in some unneeded threads running int padX = (width % 8 == 0) ? 0 : 1; int padY = (height % 8 == 0) ? 0 : 1; int padZ = (depth % 8 == 0) ? 0 : 1; readData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ)); } public static void ReadSingleFromRenderTexture(RenderTexture tex, float x, float y, float z, ComputeBuffer buffer, ComputeShader readData, bool useBilinear) { if (tex == null) throw new ArgumentException("RenderTexture is null"); if (buffer == null) throw new ArgumentException("Buffer is null"); if (readData == null) throw new ArgumentException("Computer shader is null"); if (!tex.IsCreated()) throw new ArgumentException("Tex has not been created (Call Create() on tex)"); int kernel = -1; int depth = 1; if (tex.dimension == TextureDimension.Tex3D) { if(useBilinear) kernel = readData.FindKernel("readSingleBilinear3D"); else kernel = readData.FindKernel("readSingle3D"); depth = tex.volumeDepth; readData.SetTexture(kernel, "_Tex3D", tex); readData.SetBuffer(kernel, "_BufferSingle3D", buffer); } else { if (useBilinear) kernel = readData.FindKernel("readSingleBilinear2D"); else kernel = readData.FindKernel("readSingle2D"); readData.SetTexture(kernel, "_Tex2D", tex); readData.SetBuffer(kernel, "_BufferSingle2D", buffer); } if (kernel == -1) throw new ArgumentException("Could not find kernel readSingle for " + tex.dimension); int width = tex.width; int height = tex.height; //used for point sampling readData.SetInt("_IdxX", (int)x); readData.SetInt("_IdxY", (int)y); readData.SetInt("_IdxZ", (int)z); //used for bilinear sampling readData.SetVector("_UV", new Vector4(x / (float)(width - 1), y / (float)(height - 1), z / (float)(depth - 1), 0.0f)); readData.Dispatch(kernel, 1, 1, 1); } public static void WriteIntoRenderTexture(RenderTexture tex, int channels, ComputeBuffer buffer, ComputeShader writeData) { if (tex == null) throw new ArgumentException("RenderTexture is null"); if (buffer == null) throw new ArgumentException("Buffer is null"); if (writeData == null) throw new ArgumentException("Computer shader is null"); if (channels < 1 || channels > 4) throw new ArgumentException("Channels must be 1, 2, 3, or 4"); if (!tex.enableRandomWrite) throw new ArgumentException("You must enable random write on render texture"); if (!tex.IsCreated()) throw new ArgumentException("Tex has not been created (Call Create() on tex)"); int kernel = -1; int depth = 1; string D = "2D"; string C = "C" + channels.ToString(); if (tex.dimension == TextureDimension.Tex3D) { depth = tex.volumeDepth; D = "3D"; } kernel = writeData.FindKernel("write" + D + C); if (kernel == -1) throw new ArgumentException("Could not find kernel " + "write" + D + C); int width = tex.width; int height = tex.height; //set the compute shader uniforms writeData.SetTexture(kernel, "_Des" + D + C, tex); writeData.SetInt("_Width", width); writeData.SetInt("_Height", height); writeData.SetInt("_Depth", depth); writeData.SetBuffer(kernel, "_Buffer" + D + C, buffer); //run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need //some extra threadBlocks. This will result in some unneeded threads running int padX = (width % 8 == 0) ? 0 : 1; int padY = (height % 8 == 0) ? 0 : 1; int padZ = (depth % 8 == 0) ? 0 : 1; writeData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ)); } public static void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, ComputeBuffer buffer, ComputeShader writeData) { if (tex == null) throw new ArgumentException("RenderTexture is null"); if (buffer == null) throw new ArgumentException("buffer is null"); if (writeData == null) throw new ArgumentException("Computer shader is null"); if (channels < 1 || channels > 4) throw new ArgumentException("Channels must be 1, 2, 3, or 4"); if (!tex.enableRandomWrite) throw new ArgumentException("You must enable random write on render texture"); if (!tex.IsCreated()) throw new ArgumentException("Tex has not been created (Call Create() on tex)"); int kernel = -1; int depth = 1; string D = "2D"; string C = "C" + channels.ToString(); if (tex.dimension == TextureDimension.Tex3D) { depth = tex.volumeDepth; D = "3D"; } kernel = writeData.FindKernel("write" + D + C); if (kernel == -1) throw new ArgumentException("Could not find kernel " + "write" + D + C); int width = tex.width; int height = tex.height; int size = width * height * depth * channels; float[] map = new float[size]; LoadRawFile(path, map, size); buffer.SetData(map); //set the compute shader uniforms writeData.SetTexture(kernel, "_Des" + D + C, tex); writeData.SetInt("_Width", width); writeData.SetInt("_Height", height); writeData.SetInt("_Depth", depth); writeData.SetBuffer(kernel, "_Buffer" + D + C, buffer); //run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need //some extra threadBlocks. This will result in some unneeded threads running int padX = (width % 8 == 0) ? 0 : 1; int padY = (height % 8 == 0) ? 0 : 1; int padZ = (depth % 8 == 0) ? 0 : 1; writeData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ)); } private static void LoadRawFile(string path, float[] map, int size) { FileInfo fi = new FileInfo(path); if (fi == null) throw new ArgumentException("Raw file not found (" + path + ")"); FileStream fs = fi.OpenRead(); byte[] data = new byte[fi.Length]; fs.Read(data, 0, (int)fi.Length); fs.Close(); //divide by 4 as there are 4 bytes in a 32 bit float if (size > fi.Length / 4) throw new ArgumentException("Raw file is not the required size (" + path + ")"); for (int x = 0, i = 0; x < size; x++, i += 4) { //Convert 4 bytes to 1 32 bit float map[x] = System.BitConverter.ToSingle(data, i); }; } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Utils/FakeOceanPQS.cs ================================================ using System; using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Scatterer { public class FakeOceanPQS : PQSMod { bool coroutineStarted = false; Material originalOceanMaterial; IEnumerator StopSphereCoroutine() { while (true) { for (int i=0; i<10; i++) yield return new WaitForFixedUpdate (); sphere.StopAllCoroutines (); sphere.DeactivateSphere(); } } public override void OnSphereStarted() { if (!coroutineStarted) { StartCoroutine (StopSphereCoroutine ()); coroutineStarted = true; } } public void Apply(PQS pqs) { if (pqs != null) { this.sphere = pqs; this.transform.parent = pqs.transform; this.requirements = PQS.ModiferRequirements.Default; this.modEnabled = true; this.order = 0; originalOceanMaterial = pqs.surfaceMaterial; Material invisibleOceanMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/invisible")]); invisibleOceanMaterial.SetOverrideTag ("IgnoreProjector", "True"); invisibleOceanMaterial.SetOverrideTag ("ForceNoShadowCasting", "True"); pqs.surfaceMaterial = invisibleOceanMaterial; sphere.StopAllCoroutines (); sphere.DeactivateSphere(); } } public void Remove() { this.StopAllCoroutines (); sphere.surfaceMaterial = originalOceanMaterial; sphere.StartUpSphere (); gameObject.DestroyGameObject (); } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Utils/OceanUtils.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public static class OceanUtils { public static bool oceanRemoved = false; public static void removeStockOceansIfNotDone() { if (!oceanRemoved) { removeStockOceans(); oceanRemoved = true; } } private static void removeStockOceans() { foreach (ScattererCelestialBody sctBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies) { if (sctBody.hasOcean) { bool removed = false; var celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.celestialBodyName); if (celBody == null) { celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.transformName); } if (celBody != null) { PQS pqs = celBody.pqsController; if ((pqs != null) && (pqs.ChildSpheres != null) && (pqs.ChildSpheres.Count () != 0)) { PQS ocean = pqs.ChildSpheres [0]; if (ocean != null) { GameObject go = new GameObject ("Scatterer stock ocean disabler "+sctBody.celestialBodyName); FakeOceanPQS fakeOcean = go.AddComponent (); fakeOcean.Apply (ocean); removed = true; } } } if (!removed) { Utils.LogDebug ("Couldn't remove stock ocean for " + sctBody.celestialBodyName); } } } Utils.LogDebug ("Removed stock oceans"); } //We can disable scatterer oceans and re-enable stock oceans without restarting the game //but once started the stock ocean "pollutes" the scene with gameObjects that remain and lower performance so it isn't recommended but the option is there public static void restoreOceansIfNeeded() { if (oceanRemoved) { FakeOceanPQS[] fakes = (FakeOceanPQS[])FakeOceanPQS.FindObjectsOfType (typeof(FakeOceanPQS)); foreach (FakeOceanPQS fake in fakes) { fake.Remove (); Component.Destroy(fake); } oceanRemoved = false; Utils.LogDebug ("Stock oceans restored"); } } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Utils/RTUtility.cs ================================================ using UnityEngine; using System.Collections; namespace Scatterer { static public class RTUtility { static public void MultiTargetBlit(RenderTexture[] des, Material mat, int pass) { RenderBuffer[] rb = new RenderBuffer[des.Length]; for(int i = 0; i < des.Length; i++) rb[i] = des[i].colorBuffer; Graphics.SetRenderTarget(rb, des[0].depthBuffer); GL.PushMatrix(); GL.LoadOrtho(); mat.SetPass(pass); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f); GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f); GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f); GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f); GL.End(); GL.PopMatrix(); } static public void MultiTargetBlit(RenderBuffer[] des_rb, RenderBuffer des_db, Material mat, int pass) { Graphics.SetRenderTarget(des_rb, des_db); GL.PushMatrix(); GL.LoadOrtho(); mat.SetPass(pass); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f); GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f); GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f); GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f); GL.End(); GL.PopMatrix(); } static public void Swap(RenderTexture[] texs) { RenderTexture temp = texs[0]; texs[0] = texs[1]; texs[1] = temp; } static public void ClearColor(RenderTexture[] texs) { for(int i = 0; i < texs.Length; i++) { Graphics.SetRenderTarget(texs[i]); GL.Clear(false,true, Color.clear); } } } } ================================================ FILE: scatterer/Effects/Proland/Ocean/Utils/WriteFloat.cs ================================================ using UnityEngine; using System; using System.Collections; using System.IO; namespace Scatterer { //This class is now obsolete and can be replaced with a single blit /// /// This class is designed to take 32 bit floating point data and get it into a 2D render texture. /// As there is no way in Unity to load floating point data straight into a render texture (with out dx11) the data for each /// channel must be encoded into a ARGB32 format texture and then decoded via a shader into the render texture. /// /// At the moment there are some conditions that must be meet for this to work /// /// 1 - The data must be 32 bit floating point but the render texture format can be float or half. /// /// 2 - The encode/decode step only works on data in the range 0 - 0.9999 but the function will find the highest number and normalize the /// the data if its over 1 and then un-normalize it in the shader. This way you can have numbers greater than 1. /// The function will also find the lowest number and if its below 0 it will add this value to all the data so the lowest number is 0. /// This way you can have numbers lower than 0. This only works when copying data into a render texture. /// When trying to get it out of a render texture you will need to make sure the data is in the range 0 - 0.9999 /// as there is not easy way to iterate over the texture and find the min and max values. /// /// 3 - When trying encode/decode values it does not seem to work on values equal to 1 so Ive stated the max range as 0.9999. /// /// 4 - Ive added the ability to load a raw file and copy the data into a render texture. /// You can load 32 bit or 16 bit data. 16 bit data can be big endian or little endian /// public class WriteFloat { const float MAX_VALUE = 0.999999f; /// /// The material which will write the encoded /// data into the render texture. /// Material m_writeToFloat; /// /// The textures to hold the encoded data. /// To increase performance Ive made it so these /// textures are created once and reused. /// This does mean that the data must match the texture size. /// You can call the resize function to recreate the /// textures at a new size if needed. /// Texture2D m_mapR, m_mapG, m_mapB, m_mapA; /// /// The current size of the maps. /// int m_width, m_height; /// /// Create a new object that can write data into a render texture of dimensions w and h. /// public WriteFloat(int w, int h) { Shader shader = ShaderReplacer.Instance.LoadedShaders[("EncodeFloat/WriteToFloat")]; if(shader == null) { throw new InvalidOperationException("Could not find shader EncodeFloat/WriteToFloat. Did you change the shaders name?"); } m_writeToFloat = new Material(shader); m_width = w; m_height = h; m_mapR = new Texture2D(w, h, TextureFormat.ARGB32, false, true); m_mapR.filterMode = FilterMode.Point; m_mapR.wrapMode = TextureWrapMode.Clamp; m_mapG = new Texture2D(w, h, TextureFormat.ARGB32, false, true); m_mapG.filterMode = FilterMode.Point; m_mapG.wrapMode = TextureWrapMode.Clamp; m_mapB = new Texture2D(w, h, TextureFormat.ARGB32, false, true); m_mapB.filterMode = FilterMode.Point; m_mapB.wrapMode = TextureWrapMode.Clamp; m_mapA = new Texture2D(w, h, TextureFormat.ARGB32, false, true); m_mapA.filterMode = FilterMode.Point; m_mapA.wrapMode = TextureWrapMode.Clamp; } /// /// Resize to new dimensions. /// public void Resize(int w, int h) { m_width = w; m_height = h; m_mapR.Resize(w, h, TextureFormat.ARGB32, false); m_mapG.Resize(w, h, TextureFormat.ARGB32, false); m_mapB.Resize(w, h, TextureFormat.ARGB32, false); m_mapA.Resize(w, h, TextureFormat.ARGB32, false); } /// /// This will write the values in data array into tex /// /// The texture to write into /// The number of channels in texture /// The data to write into texture. Size must width * height * channels. public void WriteIntoRenderTexture(RenderTexture tex, int channels, float[] data) { if(channels < 1 || channels > 4) { Utils.LogDebug("Channels must be 1, 2, 3, or 4"); return; } int w = tex.width; int h = tex.height; if(w != m_width || h != m_height) { Utils.LogDebug("Render texture not the correct dimensions"); return; } int size = w*h*channels; Color[] map = new Color[size]; float max = 1.0f; float min = 0.0f; LoadData(data, map, size, ref min, ref max); Write(w, h, channels, min, max, tex, map); } /// /// Load 32 bit float data from raw file and write into render texture /// width the option of writting the loaded data into the fdata array if it is not null. /// /// The texture to write into /// The number of channels in texture /// The data to write into texture. Size must width * height * channels. /// If this is not the data in the file will be written into this. // public void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, float[] fdata = null) public void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, float[] fdata) { if(channels < 1 || channels > 4) { Utils.LogDebug("EncodeFloat::WriteIntoRenderTexture - Channels must be 1, 2, 3, or 4"); return; } int w = tex.width; int h = tex.height; if(w != m_width || h != m_height) { Utils.LogDebug("Render texture not the correct dimensions"); return; } int size = w*h*channels; Color[] map = new Color[size]; if(fdata == null) fdata = new float[size]; float max = 1.0f; float min = 0.0f; if(!LoadRawFile(path, map, size, ref min, ref max, fdata)) { Utils.LogDebug("EncodeFloat::WriteIntoRenderTexture - Error loading raw file " + path); return; } Write(w, h, channels, min, max, tex, map); } /// /// Load 16 bit float data from raw file and write into render texture /// width the option of writting the loaded data in to the fdata array if it is not null. /// /// The texture to write into /// The number of channels in texture /// The data to write into texture. Size must width * height * channels. /// If this is not the data in the file will be written into this. // public void WriteIntoRenderTexture16bit(RenderTexture tex, int channels, string path, bool bigEndian, float[] fdata = null) public void WriteIntoRenderTexture16bit(RenderTexture tex, int channels, string path, bool bigEndian, float[] fdata) { if(channels < 1 || channels > 4) { Utils.LogDebug("Channels must be 1, 2, 3, or 4"); return; } int w = tex.width; int h = tex.height; if(w != m_width || h != m_height) { Utils.LogDebug("Render texture not the correct dimensions"); return; } int size = w*h*channels; Color[] map = new Color[size]; if(fdata == null) fdata = new float[size]; float max = 1.0f; float min = 0.0f; if(!LoadRawFile16(path, map, size, ref min, ref max, fdata, bigEndian)) { Utils.LogDebug("EncodeFloat::WriteIntoRenderTexture16bit - Error loading raw file " + path); return; } Write(w, h, channels, min, max, tex, map); } /// /// Write the encoded float in map into texture. /// void Write(int w, int h, int c, float min, float max, RenderTexture tex, Color[] map) { for(int x = 0; x < w; x++) { for(int y = 0; y < h; y++) { if(c > 0) m_mapR.SetPixel(x, y, map[(x+y*w)*c+0]); else m_mapR.SetPixel(x, y, Color.clear); if(c > 1) m_mapG.SetPixel(x, y, map[(x+y*w)*c+1]); else m_mapG.SetPixel(x, y, Color.clear); if(c > 2) m_mapB.SetPixel(x, y, map[(x+y*w)*c+2]); else m_mapB.SetPixel(x, y, Color.clear); if(c > 3) m_mapA.SetPixel(x, y, map[(x+y*w)*c+3]); else m_mapA.SetPixel(x, y, Color.clear); } } m_mapR.Apply(); m_mapG.Apply(); m_mapB.Apply(); m_mapA.Apply(); m_writeToFloat.SetFloat("_Max", max); m_writeToFloat.SetFloat("_Min", min); m_writeToFloat.SetTexture("_TexR", m_mapR); m_writeToFloat.SetTexture("_TexG", m_mapG); m_writeToFloat.SetTexture("_TexB", m_mapB); m_writeToFloat.SetTexture("_TexA", m_mapA); Graphics.Blit(null, tex, m_writeToFloat); } /// /// Encode a float into 4 bytes as normilized floats. /// float[] EncodeFloatRGBA(float val) { float[] kEncodeMul = new float[]{ 1.0f, 255.0f, 65025.0f, 160581375.0f }; float kEncodeBit = 1.0f / 255.0f; for( int i = 0; i < kEncodeMul.Length; ++i ) { kEncodeMul[i] *= val; // Frac kEncodeMul[i] = ( float )( kEncodeMul[i] - System.Math.Truncate( kEncodeMul[i] ) ); } // enc -= enc.yzww * kEncodeBit; float[] yzww = new float[] { kEncodeMul[1], kEncodeMul[2], kEncodeMul[3], kEncodeMul[3] }; for( int i = 0; i < kEncodeMul.Length; ++i ) { kEncodeMul[i] -= yzww[i] * kEncodeBit; } return kEncodeMul; } /// /// Find the range of the data and then pak it into the map. /// void LoadData(float[] data, Color[] map, int size, ref float min, ref float max) { for(int x = 0 ; x < size; x++) { //Find the min and max range of data if(data[x] > max) max = data[x]; if(data[x] < min) min = data[x]; }; min = Mathf.Abs(min); max += min; PackData(map, size, min, max, data); } /// /// Load the data from a 32 bit file, find the range of the data and then pak it into the map. /// bool LoadRawFile(string path, Color[] map, int size, ref float min, ref float max, float[] fdata) { FileInfo fi = new FileInfo(path); if(fi == null) { Utils.LogDebug("Raw file not found"); return false; } FileStream fs = fi.OpenRead(); byte[] data = new byte[fi.Length]; fs.Read(data, 0, (int)fi.Length); fs.Close(); //divide by 4 as there are 4 bytes in a 32 bit float if(size > fi.Length/4) { Utils.LogDebug("Raw file is not the required size"); return false; } int i = 0; for(int x = 0 ; x < size; x++) { //Convert 4 bytes to 1 32 bit float fdata[x] = System.BitConverter.ToSingle(data, i); //Find the min and max range of data if(fdata[x] > max) max = fdata[x]; if(fdata[x] < min) min = fdata[x]; i += 4; // theres 4 bytes in 32 bits so increment i by 4 }; min = Mathf.Abs(min); max += min; PackData(map, size, min, max, fdata); return true; } /// /// Load the data from a 16 bit file, find the range of the data and then pak it into the map. /// bool LoadRawFile16(string path, Color[] map, int size, ref float min, ref float max, float[] fdata, bool bigendian) { FileInfo fi = new FileInfo(path); if(fi == null) { Utils.LogDebug("Raw file not found"); return false; } FileStream fs = fi.OpenRead(); byte[] data = new byte[fi.Length]; fs.Read(data, 0, (int)fi.Length); fs.Close(); //divide by 2 as there are 2 bytes in a 16 bit float if(size > fi.Length/2) { Utils.LogDebug("Raw file is not the required size"); return false; } int i = 0; for(int x = 0 ; x < size; x++) { //Extract 16 bit data and normalize. fdata[x] = (bigendian) ? (data[i++]*256.0f + data[i++]) : (data[i++] + data[i++]*256.0f); fdata[x] /= 65535.0f; //Find the min and max range of data if(fdata[x] > max) max = fdata[x]; if(fdata[x] < min) min = fdata[x]; }; min = Mathf.Abs(min); max += min; PackData(map, size, min, max, fdata); return true; } /// /// Encode data into the map. /// void PackData(Color[] map, int size, float min, float max, float[] data) { for(int x = 0 ; x < size; x++) { float normalizedData = (data[x] + min) / max; //does not work on value of one if(normalizedData >= 1.0f) normalizedData = MAX_VALUE; float[] farray = EncodeFloatRGBA(normalizedData); map[x] = new Color(farray[0], farray[1], farray[2], farray[3]); }; } public void OnDestroy () { UnityEngine.Object.Destroy(m_mapA); UnityEngine.Object.Destroy(m_mapR); UnityEngine.Object.Destroy(m_mapG); UnityEngine.Object.Destroy(m_mapB); UnityEngine.Object.Destroy (m_writeToFloat); } } } ================================================ FILE: scatterer/Effects/Proland/ProlandManager.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { /* * A manager to organise what order update functions are called * Manages all effects taken from Proland (ie Precomputed Scattering and Ocean, maybe one day forests...) * The class structures from original Proland are kept, with some added Utilities related to scatterer and KSP * Provides a location for common settings and allows the nodes to access each other */ public class ProlandManager: MonoBehaviour { public bool hasOcean = false; public bool usesCloudIntegration = true; public bool cloudIntegrationUsesScattererSunColors = false; public bool flatScaledSpaceModel = false; public double m_radius = 600000.0; public float mainMenuScaleFactor = 1f; OceanFFTgpu oceanNode; public SkyNode skyNode; public Color sunColor; public CelestialBody parentCelestialBody; public Transform parentScaledTransform; public Transform parentLocalTransform; public bool sunsUseIntensityCurves; public CelestialBody sunCelestialBody; public List eclipseCasters=new List {}; public List planetshineSources=new List {}; public List secondarySuns=new List {}; public Light mainSunLight, mainScaledSunLight; public ScattererCelestialBody scattererCelestialBody; public Matrix4x4 planetShineSourcesMatrix=Matrix4x4.zero; public Matrix4x4 planetShineRGBMatrix=Matrix4x4.zero; //Contains the colors set in the scatterer config public Matrix4x4 planetShineOriginalRGBMatrix=Matrix4x4.zero; //Contains the original colors of the directional lights, if available public void Init(ScattererCelestialBody scattererBody) { scattererCelestialBody = scattererBody; parentCelestialBody = scattererBody.celestialBody; sunColor=scattererBody.sunColor; flatScaledSpaceModel = scattererBody.flatScaledSpaceModel; usesCloudIntegration = scattererBody.usesCloudIntegration; cloudIntegrationUsesScattererSunColors = scattererBody.cloudIntegrationUsesScattererSunColors; hasOcean = scattererBody.hasOcean; sunsUseIntensityCurves = scattererBody.sunsUseIntensityCurves; sunCelestialBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == scattererBody.mainSunCelestialBody); mainSunLight = findLight (scattererBody.mainSunCelestialBody); mainScaledSunLight = findScaledLight (scattererBody.mainSunCelestialBody); if (!mainSunLight) { Utils.LogError ("No light found for " + scattererBody.mainSunCelestialBody + " for body " + parentCelestialBody.name + ". Defaulting to main sunlight, godrays, lightrays and caustics may look wrong, check your Kopernicus configuration."); mainSunLight = Scatterer.Instance.sunLight; } else { if (Scatterer.Instance.mainSettings.terrainShadows) Scatterer.Instance.SetShadowsForLight (mainSunLight); else Scatterer.Instance.DisableCustomShadowResForLight (mainSunLight); } if (HighLogic.LoadedScene == GameScenes.MAINMENU) { parentScaledTransform = Utils.GetMainMenuObject(scattererBody.celestialBody).transform; parentLocalTransform = Utils.GetMainMenuObject(scattererBody.celestialBody).transform; } else { parentScaledTransform = scattererBody.transform; parentLocalTransform = scattererBody.celestialBody.transform; } FindEclipseCasters (scattererBody); FindPlanetShineSources (scattererBody); if (HighLogic.LoadedScene == GameScenes.MAINMENU) { GameObject _go = Utils.GetMainMenuObject(scattererBody.celestialBody); if (_go) { MeshRenderer _mr = _go.GetComponent (); if (_mr) { var sctBodyTransform = ScaledSpace.Instance.transform.FindChild (parentCelestialBody.name); mainMenuScaleFactor = (_go.transform.localScale.x / sctBodyTransform.localScale.x); m_radius = mainMenuScaleFactor * parentCelestialBody.Radius; } } } else { m_radius = parentCelestialBody.Radius; } InitSecondarySuns (); InitSkyAndOceanNodes (); } //TODO: move to utils Light findLight (string sunCelestialBody) { Light light = Scatterer.Instance.lights.SingleOrDefault (_light => (_light != null) && (_light.gameObject != null) && (_light.gameObject.name == sunCelestialBody)); if (!light && (sunCelestialBody == "Sun")) light = Scatterer.Instance.sunLight; return light; } Light findScaledLight (string sunCelestialBody) { Light light = Scatterer.Instance.lights.SingleOrDefault (_light => (_light != null) && (_light.gameObject != null) && (_light.gameObject.name == ("Scaledspace SunLight "+sunCelestialBody))); if (!light && (sunCelestialBody == "Sun")) light = Scatterer.Instance.scaledSpaceSunLight; return light; } void FindEclipseCasters (ScattererCelestialBody scattererBody) { if (Scatterer.Instance.mainSettings.useEclipses) { for (int k = 0; k < scattererBody.eclipseCasters.Count; k++) { var cc = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == scattererBody.eclipseCasters [k]); if (cc == null) Utils.LogDebug ("Eclipse caster " + scattererBody.eclipseCasters [k] + " not found for " + scattererBody.celestialBodyName); else { eclipseCasters.Add (cc); Utils.LogDebug ("Added eclipse caster " + scattererBody.eclipseCasters [k] + " for " + scattererBody.celestialBodyName); } } } } void FindPlanetShineSources (ScattererCelestialBody scattererBody) { if (Scatterer.Instance.mainSettings.usePlanetShine) { for (int k = 0; k < scattererBody.planetshineSources.Count; k++) { var cc = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == scattererBody.planetshineSources [k].bodyName); if (cc == null) Utils.LogDebug ("planetshine source " + scattererBody.planetshineSources [k].bodyName + " not found for " + scattererBody.celestialBodyName); else { AtmoPlanetShineSource src = scattererBody.planetshineSources [k]; src.body = cc; scattererBody.planetshineSources [k].body = cc; planetshineSources.Add (src); Utils.LogDebug ("Added planetshine source" + scattererBody.planetshineSources [k].bodyName + " for " + scattererBody.celestialBodyName); } } } } void InitSkyAndOceanNodes () { skyNode = (SkyNode)Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(SkyNode)); skyNode.prolandManager = this; skyNode.SetCelestialBodyName (parentCelestialBody.name); skyNode.SetParentScaledTransform (parentScaledTransform); skyNode.SetParentLocalTransform (parentLocalTransform); skyNode.usesCloudIntegration = usesCloudIntegration; skyNode.mainMenuScaleFactor = mainMenuScaleFactor; if (skyNode.LoadFromConfigNode ()) { skyNode.Init (); if (hasOcean && Scatterer.Instance.mainSettings.useOceanShaders && (HighLogic.LoadedScene != GameScenes.MAINMENU)) { if (Scatterer.Instance.mainSettings.oceanFoam) oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanWhiteCaps)); else oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanFFTgpu)); oceanNode.Init (this); } } } public void Update() { if (secondarySuns.Count > 0) { UpdateSecondarySuns(); } skyNode.UpdateNode(); if (oceanNode) { oceanNode.UpdateNode(); } } void FindSecondarySuns (ScattererCelestialBody scattererBody) { foreach (SecondarySunConfig sunConfig in scattererBody.secondarySuns) { SecondarySun secondarySun = SecondarySun.FindSecondarySun (sunConfig); if (secondarySun != null) { secondarySun.sunLight = findLight (sunConfig.celestialBodyName); secondarySun.scaledSunLight = findScaledLight (sunConfig.celestialBodyName); secondarySuns.Add (secondarySun); } } } void InitSecondarySuns () { FindSecondarySuns (scattererCelestialBody); planetShineRGBMatrix = Matrix4x4.zero; for (int i = 0; i < Math.Min (4, secondarySuns.Count); i++) { planetShineRGBMatrix.SetRow (i, new Vector4 (secondarySuns[i].config.sunColor.r, secondarySuns[i].config.sunColor.g, secondarySuns[i].config.sunColor.b, 1.0f)); if (secondarySuns[i].scaledSunLight != null) planetShineOriginalRGBMatrix.SetRow (i, new Vector4 (secondarySuns[i].scaledSunLight.color.r, secondarySuns[i].scaledSunLight.color.g, secondarySuns[i].scaledSunLight.color.b, 1.0f)); else planetShineOriginalRGBMatrix.SetRow(i, planetShineRGBMatrix.GetRow(i)); } } void UpdateSecondarySuns () { planetShineSourcesMatrix = Matrix4x4.zero; for (int i = 0; i < Math.Min (4, secondarySuns.Count); i++) { Vector3 sourcePosRelPlanet = Vector3.Scale (secondarySuns[i].celestialBody.position - parentCelestialBody.GetTransform ().position, new Vector3d (ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor)); //has to be this that is borked planetShineSourcesMatrix.SetRow (i, new Vector4 (sourcePosRelPlanet.x, sourcePosRelPlanet.y, sourcePosRelPlanet.z, 1.0f)); if (secondarySuns[i].scaledSunLight != null) { if (sunsUseIntensityCurves) { planetShineRGBMatrix[i,3] = secondarySuns[i].scaledSunLight.intensity; } if (!cloudIntegrationUsesScattererSunColors) { planetShineOriginalRGBMatrix.SetRow (i, new Vector4 (secondarySuns[i].scaledSunLight.color.r, secondarySuns[i].scaledSunLight.color.g, secondarySuns[i].scaledSunLight.color.b, secondarySuns[i].scaledSunLight.intensity)); } } } } public void OnDestroy() { if (skyNode) { skyNode.OnDestroy(); // no idea why this doesn't fire by itself sometimes Component.Destroy(skyNode); } if (oceanNode) { oceanNode.OnDestroy(); Component.Destroy(oceanNode); } } //TODO: change this so that it takes the new configNode and that's all? May not be possible depending on if it needs to recreate lightraysRenderer and stuff //Therefor add an option to init from configNode? yep public void reBuildOcean() { if (oceanNode) { Component.DestroyImmediate(oceanNode); if (Scatterer.Instance.mainSettings.oceanFoam) oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanWhiteCaps)); else oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanFFTgpu)); oceanNode.Init(this); Utils.LogDebug("Rebuilt Ocean"); } if (skyNode) skyNode.InitOceanMaterialUniforms(); } public Vector3 getDirectionToMainSun() { if (HighLogic.LoadedScene == GameScenes.MAINMENU) { return (Scatterer.Instance.mainMenuLight.gameObject.transform.forward*(-1)); } else return (sunCelestialBody.GetTransform().position - parentCelestialBody.GetTransform().position).normalized; } public Vector3 getDirectionToCelestialBody(CelestialBody target) { return (target.GetTransform().position - parentCelestialBody.GetTransform().position); } public double GetRadius() { return m_radius; } public OceanFFTgpu GetOceanNode() { return oceanNode; } public SkyNode GetSkyNode() { return skyNode; } public Color getIntensityModulatedSunColor() { return (sunsUseIntensityCurves ? sunColor * mainScaledSunLight.intensity : sunColor); } } } ================================================ FILE: scatterer/Effects/ScattererCelestialBodiesManager.cs ================================================ // Manages loading,unloading and updating for all the Scatterer-enabled celestial bodies // Will spawn/delete/update a ProlandManager for each body if within range using System; using System.Linq; using UnityEngine; namespace Scatterer { public class ScattererCelestialBodiesManager { public bool underwater = false; bool pqsEnabledOnScattererPlanet = false; public bool isPQSEnabledOnScattererPlanet{get{return pqsEnabledOnScattererPlanet;}} bool customOceanEnabledOnScattererPlanet = false; public bool isCustomOceanEnabledOnScattererPlanet{get{return customOceanEnabledOnScattererPlanet;}} public ScattererCelestialBodiesManager () { } public void Init() { findCelestialBodies (); } public void Update() { UpdateProlandManagers (); } void UpdateProlandManagers () { pqsEnabledOnScattererPlanet = false; underwater = false; customOceanEnabledOnScattererPlanet = false; foreach (ScattererCelestialBody scattererCelestialBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies) { float minDistance; //smallest distance to either the camera or ship if (scattererCelestialBody.isFound) { minDistance = Vector3.Distance (Scatterer.Instance.scaledSpaceCamera.transform.position, scattererCelestialBody.transform.position) * ScaledSpace.ScaleFactor; minDistance = FlightGlobals.ActiveVessel ? Mathf.Min(minDistance, Vector3.Distance (FlightGlobals.ActiveVessel.transform.position, ScaledSpace.ScaledToLocalSpace (scattererCelestialBody.transform.position))) : minDistance; if (scattererCelestialBody.active) { if (minDistance > scattererCelestialBody.unloadDistance) { unloadEffectsForBody(scattererCelestialBody); break; } else { updateBody (scattererCelestialBody, ref pqsEnabledOnScattererPlanet, ref underwater, ref customOceanEnabledOnScattererPlanet); } } else { if (minDistance < scattererCelestialBody.loadDistance && scattererCelestialBody.transform && scattererCelestialBody.celestialBody) { loadEffectsForBody (scattererCelestialBody); break; } } } } } void findCelestialBodies() { foreach (ScattererCelestialBody sctBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies) { Utils.LogDebug("Finding ScattererCelestialBody name: "+sctBody.celestialBodyName+". TransformName: "+sctBody.transformName); var celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.celestialBodyName); if (celBody == null) { Utils.LogDebug("ScattererCelestialBody not found by name, trying transformName"); celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.transformName); } if (celBody == null) { Utils.LogError("ScattererCelestialBody "+sctBody.celestialBodyName+" not found by name, or transformName. Effects for this body won't be available."); continue; } else { Utils.LogDebug ("Found ScattererCelestialBody: " + sctBody.celestialBodyName + ", actual ingame name: " + celBody.GetName ()); } sctBody.celestialBody = celBody; var sctBodyTransform = ScaledSpace.Instance.transform.FindChild (sctBody.transformName); if (!sctBodyTransform) { sctBodyTransform = ScaledSpace.Instance.transform.FindChild (sctBody.celestialBodyName); } else { sctBody.transform = sctBodyTransform; sctBody.isFound = true; } sctBody.active = false; } } void loadEffectsForBody (ScattererCelestialBody scattererCelestialBody) { try { if (HighLogic.LoadedScene == GameScenes.TRACKSTATION || HighLogic.LoadedScene == GameScenes.MAINMENU) scattererCelestialBody.hasOcean = false; scattererCelestialBody.prolandManager = new ProlandManager (); scattererCelestialBody.prolandManager.Init (scattererCelestialBody); scattererCelestialBody.active = true; if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Contains (scattererCelestialBody)) { Scatterer.Instance.guiHandler.LoadPlanet(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.IndexOf (scattererCelestialBody)); } else { throw new Exception ("Planet already removed from planets list"); } Utils.LogDebug ("Effects loaded for " + scattererCelestialBody.celestialBodyName); } catch (Exception exception) { if (HighLogic.LoadedScene != GameScenes.MAINMENU || !exception.Message.Contains("No correct main menu object found for ")) Utils.LogError ("Effects couldn't be loaded for " + scattererCelestialBody.celestialBodyName + ", " + exception.ToString ()); try { scattererCelestialBody.prolandManager.OnDestroy (); } catch (Exception exception2) { Utils.LogDebug ("manager couldn't be removed for " + scattererCelestialBody.celestialBodyName + " because of exception: " + exception2.ToString ()); } Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Remove (scattererCelestialBody); if (HighLogic.LoadedScene != GameScenes.MAINMENU) { Utils.LogDebug ("" + scattererCelestialBody.celestialBodyName + " removed from active planets."); } return; } } ScattererCelestialBody updateBody (ScattererCelestialBody scattererCelestialBody, ref bool inPqsEnabledOnScattererPlanet, ref bool inUnderwater, ref bool inCustomOceanEnabledOnScattererPlanet) { scattererCelestialBody.prolandManager.Update (); inPqsEnabledOnScattererPlanet = inPqsEnabledOnScattererPlanet || !scattererCelestialBody.prolandManager.skyNode.inScaledSpace; if (inPqsEnabledOnScattererPlanet && scattererCelestialBody.prolandManager.GetOceanNode()) { inCustomOceanEnabledOnScattererPlanet = true; inUnderwater = scattererCelestialBody.prolandManager.GetOceanNode ().isUnderwater; } return scattererCelestialBody; } void unloadEffectsForBody(ScattererCelestialBody scattererCelestialBody) { scattererCelestialBody.prolandManager.OnDestroy (); UnityEngine.Object.DestroyImmediate (scattererCelestialBody.prolandManager); scattererCelestialBody.prolandManager = null; scattererCelestialBody.active = false; Utils.LogDebug ("Effects unloaded for " + scattererCelestialBody.celestialBodyName); } public void Cleanup() { foreach (ScattererCelestialBody scattererCelestialBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies) { if (scattererCelestialBody.active) { scattererCelestialBody.prolandManager.OnDestroy (); UnityEngine.Object.DestroyImmediate (scattererCelestialBody.prolandManager); scattererCelestialBody.prolandManager = null; scattererCelestialBody.active = false; Utils.LogDebug ("Effects unloaded for " + scattererCelestialBody.celestialBodyName); } } } } } ================================================ FILE: scatterer/Effects/SunFlare/SunFlare.cs ================================================ //rendering steps //scaledSpaceCamera.OnPrecull -> skynodes update the extinction texture one after one //camerahook on the relevant scaledSpace or farCamera -> clear the extinction texture before the next frame //while taking care of keeping it around until the rendering has finished (either nearCamera or scaledCamera) using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using KSP.IO; namespace Scatterer { public class SunFlare : MonoBehaviour { public ConfigNode configNodeToLoad; public Material sunglareMaterial; public CelestialBody source; public string sourceName; public Transform sourceScaledTransform; static Dictionary texturesDictionary = new Dictionary (); public RenderTexture extinctionTexture; int waitBeforeReloadCnt = 0; SunflareCameraHook nearCameraHook, scaledCameraHook; RaycastHit hit; bool hitStatus=false; bool flareRendering=false; public bool FlareRendering { get { return flareRendering; } } float sunGlareScale=1; float sunGlareFade=1; float ghostFade=1; Mesh screenMesh; GameObject sunflareGameObject; public int syntaxVersion = 1; SunflareSettingsV1 settingsV1; SunflareSettingsV2 settingsV2; public void start() { LoadSettings (); sunglareMaterial = new Material (ShaderReplacer.Instance.LoadedShaders["Scatterer/sunFlare"]); sunglareMaterial.SetOverrideTag ("IGNOREPROJECTOR", "True"); sunglareMaterial.SetOverrideTag ("IgnoreProjector", "True"); Utils.EnableOrDisableShaderKeywords (sunglareMaterial, "SCATTERER_MERGED_DEPTH_ON", "SCATTERER_MERGED_DEPTH_OFF", !Scatterer.Instance.unifiedCameraMode); if (!Scatterer.Instance.unifiedCameraMode) { if (HighLogic.LoadedScene != GameScenes.TRACKSTATION && DepthToDistanceCommandBuffer.RenderTexture != null) { sunglareMaterial.SetTexture ("_customDepthTexture", DepthToDistanceCommandBuffer.RenderTexture); } else sunglareMaterial.SetTexture ("_customDepthTexture", Texture2D.whiteTexture); //keep this in mind for when doing multiple points check and ditching raycast } sunglareMaterial.renderQueue = 3100; screenMesh = MeshFactory.MakePlane (2, 2, MeshFactory.PLANE.XY, false, false); screenMesh.bounds = new Bounds (Vector4.zero, new Vector3 (Mathf.Infinity, Mathf.Infinity, Mathf.Infinity)); sunflareGameObject = new GameObject (); MeshFilter sunflareGameObjectMeshFilter; if (sunflareGameObject.GetComponent ()) sunflareGameObjectMeshFilter = sunflareGameObject.GetComponent (); else sunflareGameObjectMeshFilter = sunflareGameObject.AddComponent(); sunflareGameObjectMeshFilter.mesh.Clear (); sunflareGameObjectMeshFilter.mesh = screenMesh; MeshRenderer sunflareGameObjectMeshRenderer; if (sunflareGameObject.GetComponent ()) sunflareGameObjectMeshRenderer = sunflareGameObject.GetComponent (); else sunflareGameObjectMeshRenderer = sunflareGameObject.AddComponent(); sunflareGameObjectMeshRenderer.sharedMaterial = sunglareMaterial; sunflareGameObjectMeshRenderer.material = sunglareMaterial; sunflareGameObjectMeshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; sunflareGameObjectMeshRenderer.receiveShadows = false; sunflareGameObjectMeshRenderer.enabled = true; sunflareGameObject.layer = 10; //start in scaledspace scaledCameraHook = (SunflareCameraHook) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(SunflareCameraHook)); scaledCameraHook.flare = this; scaledCameraHook.useDbufferOnCamera = 0f; if (!(HighLogic.LoadedScene == GameScenes.TRACKSTATION)) { nearCameraHook = (SunflareCameraHook)Scatterer.Instance.nearCamera.gameObject.AddComponent (typeof(SunflareCameraHook)); nearCameraHook.flare = this; nearCameraHook.useDbufferOnCamera = 1f; } ApplySunflareConfig (); sunglareMaterial.SetFloat (ShaderProperties.aspectRatio_PROPERTY, Scatterer.Instance.scaledSpaceCamera.aspect); Shader.SetGlobalTexture(ShaderProperties.scattererReconstructedCloud_PROPERTY, Texture2D.whiteTexture); // Temporary way to pass volumetric cloud extinction, if raymarched volumetrics are loaded they override this Utils.LogDebug ("Added custom sun flare for "+sourceName); } public void updateProperties() { var sunViewPortPos = Scatterer.Instance.scaledSpaceCamera.WorldToViewportPoint (sourceScaledTransform.position); hitStatus=false; if (sunViewPortPos.z > 0) { if (syntaxVersion == 1) { float dist = (float) (Scatterer.Instance.scaledSpaceCamera.transform.position - sourceScaledTransform.position) .magnitude; sunGlareScale = dist / 2266660f * Scatterer.Instance.scaledSpaceCamera.fieldOfView / 60f; //if dist > 1.25*sunglareFadeDistance -->1 //if dist < 0.25*sunglareFadeDistance -->0 //else values smoothstepped in between sunGlareFade = Mathf.SmoothStep (0, 1, (dist / settingsV1.sunGlareFadeDistance) - 0.25f); //if dist < 0.5 * ghostFadeDistance -->1 //if dist > 1.5 * ghostFadeDistance -->0 //else values smoothstepped in between ghostFade = Mathf.SmoothStep (0, 1, (dist - 0.5f * settingsV1.ghostFadeDistance) / (settingsV1.ghostFadeDistance)); ghostFade = 1 - ghostFade; sunglareMaterial.SetFloat (ShaderProperties.sunGlareScale_PROPERTY, sunGlareScale); sunglareMaterial.SetFloat (ShaderProperties.sunGlareFade_PROPERTY, sunGlareFade); sunglareMaterial.SetFloat (ShaderProperties.ghost1Fade_PROPERTY, ghostFade); sunglareMaterial.SetFloat (ShaderProperties.ghost2Fade_PROPERTY, ghostFade); sunglareMaterial.SetFloat (ShaderProperties.ghost3Fade_PROPERTY, ghostFade); } else if (syntaxVersion == 2) { float dist = (float) (Scatterer.Instance.scaledSpaceCamera.transform.position - sourceScaledTransform.position).magnitude / ((float) source.Radius / ScaledSpace.ScaleFactor); //distance measured in stellar radius if (settingsV2.flares.Count > 0) { float intensity = settingsV2.flares[0].intensityCurve.Curve.Evaluate(dist); float scale = settingsV2.flares[0].scaleCurve.Curve.Evaluate(dist); sunglareMaterial.SetVector ("flareSettings", new Vector3(intensity, settingsV2.flares[0].displayAspectRatio,1f/scale)); } if (settingsV2.flares.Count > 1) { float intensity = settingsV2.flares[1].intensityCurve.Evaluate(dist); float scale = settingsV2.flares[1].scaleCurve.Evaluate(dist); sunglareMaterial.SetVector ("spikesSettings", new Vector3(intensity, settingsV2.flares[1].displayAspectRatio,1f/scale)); } //ghostFade is now per ghost if (settingsV2.ghosts.Count > 0) { ghostFade = settingsV2.ghosts[0].intensityCurve.Evaluate(dist); sunglareMaterial.SetFloat (ShaderProperties.ghost1Fade_PROPERTY, ghostFade); } if (settingsV2.ghosts.Count > 1) { ghostFade = settingsV2.ghosts[1].intensityCurve.Evaluate(dist); sunglareMaterial.SetFloat (ShaderProperties.ghost2Fade_PROPERTY, ghostFade); } if (settingsV2.ghosts.Count > 2) { ghostFade = settingsV2.ghosts[2].intensityCurve.Evaluate(dist); sunglareMaterial.SetFloat (ShaderProperties.ghost3Fade_PROPERTY, ghostFade); } } if (!MapView.MapIsEnabled && !(HighLogic.LoadedScene == GameScenes.TRACKSTATION)) { hitStatus = Physics.Raycast (Scatterer.Instance.nearCamera.transform.position, (source.transform.position - Scatterer.Instance.nearCamera.transform.position).normalized, out hit, Mathf.Infinity, (int)((1 << 15) + (1 << 0))); if (!hitStatus) { hitStatus = Physics.Raycast (Scatterer.Instance.scaledSpaceCamera.transform.position, (sourceScaledTransform.position - Scatterer.Instance.scaledSpaceCamera.transform.position) .normalized, out hit, Mathf.Infinity, (int)((1 << 10))); } sunglareMaterial.SetVector(ShaderProperties.sunWorldPosition_PROPERTY, (Vector3)ScaledSpace.ScaledToLocalSpace(new Vector3d(sourceScaledTransform.position.x, sourceScaledTransform.position.y, sourceScaledTransform.position.z))); } else { hitStatus = Physics.Raycast (Scatterer.Instance.scaledSpaceCamera.transform.position, (sourceScaledTransform.position - Scatterer.Instance.transform.position).normalized, out hit, Mathf.Infinity, (int)((1 << 10))); sunglareMaterial.SetVector(ShaderProperties.sunWorldPosition_PROPERTY, sourceScaledTransform.position); } if(hitStatus) { //if sun visible, draw sunflare if(hit.transform == sourceScaledTransform) hitStatus=false; } if (HighLogic.LoadedScene != GameScenes.TRACKSTATION && DepthToDistanceCommandBuffer.RenderTexture != null) sunglareMaterial.SetTexture (ShaderProperties._customDepthTexture_PROPERTY, DepthToDistanceCommandBuffer.RenderTexture); } flareRendering = !hitStatus && (sunViewPortPos.z > 0) && !Scatterer.Instance.scattererCelestialBodiesManager.underwater; sunglareMaterial.SetFloat(ShaderProperties.renderSunFlare_PROPERTY, flareRendering ? 1.0f : 0.0f); } public void Update() { //if rendertexture is lost, wait a bit before re-creating it if (!extinctionTexture.IsCreated()) { waitBeforeReloadCnt++; if (waitBeforeReloadCnt >= 2) { extinctionTexture.Create(); waitBeforeReloadCnt = 0; } } //enable or disable scaled or near script depending on trackstation or mapview if (!MapView.MapIsEnabled && HighLogic.LoadedScene != GameScenes.TRACKSTATION) { nearCameraHook.enabled = true; scaledCameraHook.enabled = false; sunflareGameObject.layer = 15; } else { if (nearCameraHook) nearCameraHook.enabled=false; scaledCameraHook.enabled=true; sunflareGameObject.layer = 10; } } public void ClearExtinction() { RenderTexture rt=RenderTexture.active; RenderTexture.active= extinctionTexture; GL.Clear(false,true,Color.white); //restore active rendertexture RenderTexture.active=rt; } public void OnDestroy() { if (nearCameraHook) { Component.Destroy (nearCameraHook); UnityEngine.Object.Destroy (nearCameraHook); } if (scaledCameraHook) { Component.Destroy (scaledCameraHook); UnityEngine.Object.Destroy (scaledCameraHook); } if (extinctionTexture) { extinctionTexture.Release(); UnityEngine.Object.Destroy (extinctionTexture); } } public void Configure(CelestialBody source, string sourceName, Transform sourceScaledTransform, ConfigNode configNodeToLoad) { this.source = source; this.sourceName = sourceName; this.sourceScaledTransform = sourceScaledTransform; this.configNodeToLoad = configNodeToLoad; } public void LoadSettings () { LoadSettingsFromConfigNode (configNodeToLoad); } void LoadSettingsFromConfigNode (ConfigNode node) { if (node.HasValue ("syntaxVersion")) { if (node.TryGetValue ("syntaxVersion", ref syntaxVersion) && ((syntaxVersion == 1) || (syntaxVersion == 2))) { Utils.LogDebug ("Sunflare syntax version: " + syntaxVersion.ToString ()); } else { Utils.LogDebug ("Invalid sunflare syntax version found: " + node.GetValue ("syntaxVersion") + ", defaulting to version 1 for retro-compatibility"); syntaxVersion = 1; } } else { Utils.LogDebug ("No sunflare syntax version found, defaulting to version 1 for retro-compatibility"); syntaxVersion = 1; } if (syntaxVersion == 1) { settingsV1 = new SunflareSettingsV1 (); ConfigNode.LoadObjectFromConfig (settingsV1, node); } else { settingsV2 = new SunflareSettingsV2 (); settingsV2.Load(node); } } public void ApplyFromUI(ConfigNode node) { LoadSettingsFromConfigNode (node); configNodeToLoad = node; ApplySunflareConfig (); } void ApplySunflareConfig () { if (syntaxVersion == 1) { ApplySyntaxV1FlareConfig (); } else if (syntaxVersion == 2) { ApplySyntaxV2FlareConfig (); } extinctionTexture = new RenderTexture (4, 4, 0, RenderTextureFormat.ARGB32); extinctionTexture.antiAliasing = 1; extinctionTexture.filterMode = FilterMode.Point; extinctionTexture.Create (); sunglareMaterial.SetTexture ("extinctionTexture", extinctionTexture); } void ApplySyntaxV1FlareConfig () { LoadAndSetTexture ("sunFlare" , (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "sunFlare.png"))); LoadAndSetTexture ("sunSpikes", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "sunSpikes.png"))); LoadAndSetTexture ("sunGhost1", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "Ghost1.png"))); LoadAndSetTexture ("sunGhost2", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "Ghost2.png"))); LoadAndSetTexture ("sunGhost3", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "Ghost3.png"))); //didn't want to serialize the matrices directly as the result is pretty unreadable //sorry about the mess, syntax v2 is cleaner Matrix4x4 ghost1Settings1 = Matrix4x4.zero; for (int i = 0; i < settingsV1.ghost1SettingsList1.Count; i++) { ghost1Settings1.SetRow (i, settingsV1.ghost1SettingsList1 [i]); } Matrix4x4 ghost1Settings2 = Matrix4x4.zero; for (int i = 0; i < settingsV1.ghost1SettingsList2.Count; i++) { ghost1Settings2.SetRow (i, settingsV1.ghost1SettingsList2 [i]); } //ghost 2 Matrix4x4 ghost2Settings1 = Matrix4x4.zero; for (int i = 0; i < settingsV1.ghost2SettingsList1.Count; i++) { ghost2Settings1.SetRow (i, settingsV1.ghost2SettingsList1 [i]); } Matrix4x4 ghost2Settings2 = Matrix4x4.zero; for (int i = 0; i < settingsV1.ghost2SettingsList2.Count; i++) { ghost2Settings2.SetRow (i, settingsV1.ghost2SettingsList2 [i]); } //ghost 3 Matrix4x4 ghost3Settings1 = Matrix4x4.zero; for (int i = 0; i < settingsV1.ghost3SettingsList1.Count; i++) { ghost3Settings1.SetRow (i, settingsV1.ghost3SettingsList1 [i]); } Matrix4x4 ghost3Settings2 = Matrix4x4.zero; for (int i = 0; i < settingsV1.ghost3SettingsList2.Count; i++) { ghost3Settings2.SetRow (i, settingsV1.ghost3SettingsList2 [i]); } sunglareMaterial.SetVector ("flareSettings", settingsV1.flareSettings); sunglareMaterial.SetVector ("spikesSettings", settingsV1.spikesSettings); sunglareMaterial.SetMatrix ("ghost1Settings1", ghost1Settings1); sunglareMaterial.SetMatrix ("ghost1Settings2", ghost1Settings2); sunglareMaterial.SetMatrix ("ghost2Settings1", ghost2Settings1); sunglareMaterial.SetMatrix ("ghost2Settings2", ghost2Settings2); sunglareMaterial.SetMatrix ("ghost3Settings1", ghost3Settings1); sunglareMaterial.SetMatrix ("ghost3Settings2", ghost3Settings2); sunglareMaterial.SetVector ("flareColor", settingsV1.flareColor); } void ApplySyntaxV2FlareConfig () { sunglareMaterial.SetVector ("flareSettings", Vector3.zero); sunglareMaterial.SetVector ("spikesSettings", Vector3.zero); sunglareMaterial.SetMatrix ("ghost1Settings1", Matrix4x4.zero); sunglareMaterial.SetMatrix ("ghost1Settings2", Matrix4x4.zero); sunglareMaterial.SetMatrix ("ghost2Settings1", Matrix4x4.zero); sunglareMaterial.SetMatrix ("ghost2Settings2", Matrix4x4.zero); sunglareMaterial.SetMatrix ("ghost3Settings1", Matrix4x4.zero); sunglareMaterial.SetMatrix ("ghost3Settings2", Matrix4x4.zero); sunglareMaterial.SetFloat (ShaderProperties.sunGlareScale_PROPERTY, 1f); sunglareMaterial.SetFloat (ShaderProperties.sunGlareFade_PROPERTY, 1f); //For the 2 flares the scale and intensity have to be overriden from curve I think, or just leave intensity at 1 here and override fade from curve? //TODO: replace only the second 1f with the 1/value from the scaleCurve if (settingsV2.flares.Count > 0) { LoadAndSetTexture ("sunFlare", Utils.GameDataPath + settingsV2.flares[0].texture); sunglareMaterial.SetVector ("flareSettings", new Vector3(1f, settingsV2.flares[0].displayAspectRatio,1f)); } if (settingsV2.flares.Count > 1) { LoadAndSetTexture ("sunSpikes", Utils.GameDataPath + settingsV2.flares[1].texture); sunglareMaterial.SetVector ("spikesSettings", new Vector3(1f, settingsV2.flares[1].displayAspectRatio,1f)); } if (settingsV2.flares.Count > 2) { Utils.LogError ("More than 2 flares used on sunflare " + sourceName + ", only 2 are supported, additional flares will not be used"); } //All static settings are set for ghosts, all that's left to do is configure the fade from ghost intensity curves if (settingsV2.ghosts.Count > 0) { LoadAndSetTexture ("sunGhost1", Utils.GameDataPath + settingsV2.ghosts[0].texture); SetGhostParameters ("ghost1Settings1", "ghost1Settings2", settingsV2.ghosts[0]); } if (settingsV2.ghosts.Count > 1) { LoadAndSetTexture ("sunGhost2", Utils.GameDataPath + settingsV2.ghosts[1].texture); SetGhostParameters ("ghost2Settings1", "ghost2Settings2", settingsV2.ghosts[1]); } if (settingsV2.ghosts.Count > 2) { LoadAndSetTexture ("sunGhost3", Utils.GameDataPath + settingsV2.ghosts[2].texture); SetGhostParameters ("ghost3Settings1", "ghost3Settings2", settingsV2.ghosts[2]); } if (settingsV2.ghosts.Count > 3) { Utils.LogError ("More than 3 ghosts used on sunflare " + sourceName + ", only 3 are supported, additional ghosts will not be used"); } sunglareMaterial.SetVector ("flareColor", settingsV2.flareColor); } void SetGhostParameters (string shaderParam1, string shaderParam2, GhostSettings ghostSettings ) { Matrix4x4 ghostSettings1 = Matrix4x4.zero; for (int i = 0; (i < ghostSettings.instances.Count) && (i < 4); i++) { ghostSettings1.SetRow (i, new Vector4 (ghostSettings.instances [i].intensityMultiplier, ghostSettings.instances [i].displayAspectRatio, 1f / ghostSettings.instances [i].scale, ghostSettings.instances [i].sunToScreenCenterPosition)); } Matrix4x4 ghostSettings2 = Matrix4x4.zero; for (int i = 4; (i < ghostSettings.instances.Count) && (i < 8); i++) { ghostSettings2.SetRow (i-4, new Vector4 (ghostSettings.instances [i].intensityMultiplier, ghostSettings.instances [i].displayAspectRatio, 1f / ghostSettings.instances [i].scale, ghostSettings.instances [i].sunToScreenCenterPosition)); } sunglareMaterial.SetMatrix (shaderParam1, ghostSettings1); sunglareMaterial.SetMatrix (shaderParam2, ghostSettings2); } void LoadAndSetTexture (string textureName, string path) { Texture2D texture = null; if (texturesDictionary.ContainsKey (path)) { texture = texturesDictionary[path]; } else { if (Path.GetExtension(path) == ".dds") { texture = Utils.LoadDDSTexture(System.IO.File.ReadAllBytes (path),path); } else { texture = new Texture2D(1, 1); texture.LoadImage(System.IO.File.ReadAllBytes(path)); } texturesDictionary[path] = texture; } texture.wrapMode = TextureWrapMode.Clamp; sunglareMaterial.SetTexture (textureName, texture); } } } ================================================ FILE: scatterer/Effects/SunFlare/SunflareCameraHook.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using KSP.IO; namespace Scatterer { public class SunflareCameraHook : MonoBehaviour { public SunFlare flare; public float useDbufferOnCamera; public SunflareCameraHook () { } public void OnPreRender() { if(flare) { flare.updateProperties (); flare.sunglareMaterial.SetFloat(ShaderProperties.renderOnCurrentCamera_PROPERTY,1.0f); flare.sunglareMaterial.SetFloat(ShaderProperties.useDbufferOnCamera_PROPERTY,useDbufferOnCamera); } } public void OnPostRender() { if(flare) { flare.ClearExtinction (); flare.sunglareMaterial.SetFloat(ShaderProperties.renderOnCurrentCamera_PROPERTY,0.0f); flare.sunglareMaterial.SetFloat(ShaderProperties.useDbufferOnCamera_PROPERTY,useDbufferOnCamera); } } } } ================================================ FILE: scatterer/Effects/SunFlare/SunflareManager.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Scatterer { public class SunflareManager : MonoBehaviour { public Dictionary scattererSunFlares = new Dictionary(); public SunflareManager () { } public void Init() { StartCoroutine (InitCoroutine()); } IEnumerator InitCoroutine() { foreach (ConfigNode _sunflareConfigs in Scatterer.Instance.planetsConfigsReader.sunflareConfigs) { foreach (ConfigNode _cn in _sunflareConfigs.GetNodes()) { if (scattererSunFlares.ContainsKey(_cn.name)) continue; SunFlare customSunFlare = (SunFlare)Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(SunFlare)); try { customSunFlare.Configure(FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == _cn.name), _cn.name,Utils.GetScaledTransform (_cn.name), _cn); customSunFlare.start (); scattererSunFlares.Add (_cn.name, customSunFlare); } catch (Exception exception) { Utils.LogDebug ("Custom sunflare cannot be added to " + _cn.name + " " + exception.ToString ()); Component.Destroy (customSunFlare); UnityEngine.Object.Destroy (customSunFlare); continue; } yield return new WaitForFixedUpdate (); } } DisableStockSunflares (); } //TODO: decouple and let every sunflare update itself, based on the GameObject it is linked to? public void UpdateFlares() { foreach (SunFlare customSunFlare in scattererSunFlares.Values) { customSunFlare.Update(); } } public void OnDestroy() { if (this) StopAllCoroutines(); ReenableStockSunflares (); foreach (SunFlare customSunFlare in scattererSunFlares.Values) { Component.DestroyImmediate (customSunFlare); } } void DisableStockSunflares () { global::SunFlare[] stockFlares = (global::SunFlare[])global::SunFlare.FindObjectsOfType (typeof(global::SunFlare)); foreach (global::SunFlare _flare in stockFlares) { if (scattererSunFlares.ContainsKey (_flare.sun.name)) { Utils.LogDebug ("Disabling stock sunflare for " + _flare.sun.name); _flare.sunFlare.enabled = false; _flare.enabled = false; _flare.gameObject.SetActive (false); } } } void ReenableStockSunflares () { global::SunFlare[] stockFlares = (global::SunFlare[]) global::SunFlare.FindObjectsOfType(typeof( global::SunFlare)); foreach(global::SunFlare _flare in stockFlares) { if (scattererSunFlares.ContainsKey (_flare.sun.name)) { _flare.sunFlare.enabled=true; } } } } } ================================================ FILE: scatterer/Effects/SunFlare/SunflareSettingsV1.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; namespace Scatterer { public class SunflareSettingsV1 { [Persistent] public int syntaxVersion = 1; [Persistent] public string assetPath; [Persistent] public float sunGlareFadeDistance = 250000; [Persistent] public float ghostFadeDistance = 13500000; [Persistent] public Vector3 flareSettings = Vector3.zero; [Persistent] public Vector3 spikesSettings = Vector3.zero; [Persistent] public List ghost1SettingsList1=new List{}; [Persistent] public List ghost1SettingsList2=new List{}; [Persistent] public List ghost2SettingsList1=new List{}; [Persistent] public List ghost2SettingsList2=new List{}; [Persistent] public List ghost3SettingsList1=new List{}; [Persistent] public List ghost3SettingsList2=new List{}; [Persistent] public Vector3 flareColor = Vector3.one; public SunflareSettingsV1 () { } } } ================================================ FILE: scatterer/Effects/SunFlare/SunflareSettingsV2.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; namespace Scatterer { public class SunflareSettingsV2 { [Persistent] public int syntaxVersion = 2; [Persistent] public Vector3 flareColor = Vector3.one; [Persistent] public List flares = new List {}; [Persistent] public List ghosts = new List {}; public SunflareSettingsV2 () { } public void Load(ConfigNode node) { ConfigNode.LoadObjectFromConfig (this, node); if (node.HasNode ("flares") && node.GetNode("flares").HasNode("Item")) { ConfigNode[] flareNodes = node.GetNode("flares").GetNodes("Item"); for (int i = 0; i < flareNodes.Length; i++) { flares[i].Load(flareNodes[i]);} } if (node.HasNode ("ghosts") && node.GetNode("ghosts").HasNode("Item")) { ConfigNode[] ghostNodes = node.GetNode("ghosts").GetNodes("Item"); for (int i = 0; i< ghostNodes.Length; i++) {ghosts[i].Load(ghostNodes[i]);} } } } public class FlareSettings { [Persistent] public string texture; [Persistent] public float displayAspectRatio; [Persistent] public FloatCurve scaleCurve = new FloatCurve(new [] {new Keyframe(0, 1), new Keyframe(1, 1)}); [Persistent] public FloatCurve intensityCurve = new FloatCurve(new [] {new Keyframe(0, 1), new Keyframe(1, 1)}); public void Load(ConfigNode node) { if (node.HasNode ("scaleCurve")) scaleCurve.Load (node.GetNode ("scaleCurve")); if (node.HasNode ("intensityCurve")) intensityCurve.Load (node.GetNode ("intensityCurve")); } } public class GhostSettings { [Persistent] public string texture; [Persistent] public FloatCurve intensityCurve = new FloatCurve(new [] {new Keyframe(0, 1), new Keyframe(1, 1)}); [Persistent] public List instances = new List {}; public void Load(ConfigNode node) { if (node.HasNode ("intensityCurve")) intensityCurve.Load (node.GetNode ("intensityCurve")); } } //not sure this will serialize or reach the depth limit thing public class GhostInstanceSettings { [Persistent] public float intensityMultiplier; [Persistent] public float displayAspectRatio; [Persistent] public float scale; [Persistent] public float sunToScreenCenterPosition; } } ================================================ FILE: scatterer/Effects/SunlightModulator/SunlightModulator.cs ================================================ using UnityEngine; using System.Collections.Generic; namespace Scatterer { public class SunlightModulatorsManager { public void ModulateByAttenuation(Light light, float inAttenuation) { FindOrCreateModulator (light).ModulateByAttenuation (inAttenuation); } public void ModulateByColor(Light light, Color inColor) { FindOrCreateModulator (light).ModulateByColor (inColor); } public Color GetLastModulateColor(Light light) { return FindOrCreateModulator (light).lastModulateColor; } public Color GetOriginalLightColor(Light light) { return FindOrCreateModulator (light).getOriginalColor(); } private SunlightModulator FindOrCreateModulator(Light light) { if (modulatorsDictionary.ContainsKey (light)) { return modulatorsDictionary [light]; } else { modulatorsDictionary[light] = (SunlightModulator) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(SunlightModulator)); modulatorsDictionary[light].Init(light); return modulatorsDictionary[light]; } } private Dictionary modulatorsDictionary = new Dictionary (); public void Cleanup() { foreach (SunlightModulator modulator in modulatorsDictionary.Values) { Component.DestroyImmediate(modulator); } } } public class SunlightModulator : MonoBehaviour { Color originalColor = Color.white, modulateColor; public Color lastModulateColor; Light sunLight; bool applyModulation = false; bool originalColorStored = false; public SunlightModulatorPreRenderHook preRenderHook; public SunlightModulatorPostRenderHook postRenderHook; public void Init(Light light) { sunLight = light; preRenderHook = (SunlightModulatorPreRenderHook) Utils.getEarliestLocalCamera().gameObject.AddComponent(typeof(SunlightModulatorPreRenderHook)); preRenderHook.Init (this); postRenderHook = (SunlightModulatorPostRenderHook) Scatterer.Instance.nearCamera.gameObject.AddComponent(typeof(SunlightModulatorPostRenderHook)); //less than optimal, doesn't affect internalCamera postRenderHook.Init (this); } public void OnPreCull() //added to scaledSpaceCamera, called before any calls from skyNode or oceanNode { storeOriginalColor (); } private void storeOriginalColor() //may not be necessary every frame? { if (sunLight.color != Color.black) { originalColor = sunLight.color; originalColorStored = true; } } public Color getOriginalColor() { return originalColor; } public void ModulateByAttenuation(float inAttenuation) //called by skynode, ie scaledSpaceCamera onPreCull { modulateColor *= inAttenuation; applyModulation = true; } public void ModulateByColor(Color inColor) { modulateColor *= inColor; applyModulation = true; } public void applyColorModulation() //called by hook on farCamera onPreRender { if (applyModulation && originalColorStored) { sunLight.color = modulateColor * originalColor; lastModulateColor = sunLight.color; modulateColor = Color.white; } } public void restoreOriginalColor() //called by hook on nearCamera/IVAcamera onPostRender //may not be necessary every frame? { if (applyModulation && originalColorStored) { sunLight.color = originalColor; applyModulation = false; } } public void OnDestroy() { Component.Destroy (preRenderHook); Component.Destroy (postRenderHook); } } } ================================================ FILE: scatterer/Effects/SunlightModulator/SunlightModulatorPostRenderHook.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using KSP.IO; namespace Scatterer { public class SunlightModulatorPostRenderHook : MonoBehaviour { SunlightModulator targetModulator; public SunlightModulatorPostRenderHook () { } public void Init(SunlightModulator target) { targetModulator = target; } public void OnPostRender() { targetModulator.restoreOriginalColor (); } public void OnDestroy() { targetModulator.postRenderHook = null; } } } ================================================ FILE: scatterer/Effects/SunlightModulator/SunlightModulatorPreRenderHook.cs ================================================ using UnityEngine; using System.Collections; using System.IO; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using KSP.IO; namespace Scatterer { public class SunlightModulatorPreRenderHook : MonoBehaviour { SunlightModulator targetModulator; public SunlightModulatorPreRenderHook () { } public void Init(SunlightModulator target) { targetModulator = target; } public void OnPreCull() //needs to be onPreCull, onPreRender is too late { targetModulator.applyColorModulation (); } public void OnDestroy() { targetModulator.preRenderHook = null; } } } ================================================ FILE: scatterer/Effects/Tonemapping/HableCurve.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Scatterer { // From unity postprocessing /// /// A raw implementation of John Hable's artist-friendly tonemapping curve. /// See http://filmicworlds.com/blog/filmic-tonemapping-with-piecewise-power-curves/ /// public class HableCurve { class Segment { public float offsetX; public float offsetY; public float scaleX; public float scaleY; public float lnA; public float B; public float Eval(float x) { float x0 = (x - offsetX) * scaleX; float y0 = 0f; // log(0) is undefined but our function should evaluate to 0. There are better ways to handle this, // but it's doing it the slow way here for clarity. if (x0 > 0) y0 = Mathf.Exp(lnA + B * Mathf.Log(x0)); return y0 * scaleY + offsetY; } } struct DirectParams { internal float x0; internal float y0; internal float x1; internal float y1; internal float W; internal float overshootX; internal float overshootY; internal float gamma; } /// /// The curve's white point. /// public float whitePoint { get; private set; } /// /// The inverse of the curve's white point. /// public float inverseWhitePoint { get; private set; } internal float x0 { get; private set; } internal float x1 { get; private set; } internal float y0 { get; private set; } internal float y1 { get; private set; } // Toe, mid, shoulder readonly Segment[] m_Segments = new Segment[3]; /// /// Creates a new curve. /// public HableCurve() { for (int i = 0; i < 3; i++) m_Segments[i] = new Segment(); uniforms = new Uniforms(this); } /// /// Evaluates a given point on the curve. /// /// The point within the curve to evaluate (on the horizontal axis) /// The value of the curve, at the point specified public float Eval(float x) { float normX = x * inverseWhitePoint; int index = (normX < x0) ? 0 : ((normX < x1) ? 1 : 2); var segment = m_Segments[index]; float ret = segment.Eval(normX); return ret; } /// /// Returns the base-2 exponential function of , which is 2 /// raised to the power . /// /// Value of the exponent /// The base-2 exponential function of public static float Exp2(float x) { return Mathf.Exp(x * 0.69314718055994530941723212145818f); } /// /// Initializes the curve with given settings. /// /// Affects the transition between the toe and the mid section of /// the curve. A value of 0 means no toe, a value of 1 means a very hard transition /// Affects how much of the dynamic range is in the toe. With a /// small value, the toe will be very short and quickly transition into the linear section, /// and with a longer value having a longer toe /// Affects the transition between the mid section and the /// shoulder of the curve. A value of 0 means no shoulder, a value of 1 means a very hard /// transition /// Affects how many F-stops (EV) to add to the dynamic range /// of the curve /// Affects how much overshoot to add to the shoulder /// Applies a gamma function to the curve public void Init(float toeStrength, float toeLength, float shoulderStrength, float shoulderLength, float shoulderAngle, float gamma) { var dstParams = new DirectParams(); // This is not actually the display gamma. It's just a UI space to avoid having to // enter small numbers for the input. const float kPerceptualGamma = 2.2f; // Constraints { toeLength = Mathf.Pow(Mathf.Clamp01(toeLength), kPerceptualGamma); toeStrength = Mathf.Clamp01(toeStrength); shoulderAngle = Mathf.Clamp01(shoulderAngle); shoulderStrength = Mathf.Clamp(shoulderStrength, 1e-5f, 1f - 1e-5f); shoulderLength = Mathf.Max(0f, shoulderLength); gamma = Mathf.Max(1e-5f, gamma); } // Apply base params { // Toe goes from 0 to 0.5 float x0 = toeLength * 0.5f; float y0 = (1f - toeStrength) * x0; // Lerp from 0 to x0 float remainingY = 1f - y0; float initialW = x0 + remainingY; float y1_offset = (1f - shoulderStrength) * remainingY; float x1 = x0 + y1_offset; float y1 = y0 + y1_offset; // Filmic shoulder strength is in F stops float extraW = Exp2(shoulderLength) - 1f; float W = initialW + extraW; dstParams.x0 = x0; dstParams.y0 = y0; dstParams.x1 = x1; dstParams.y1 = y1; dstParams.W = W; // Bake the linear to gamma space conversion dstParams.gamma = gamma; } dstParams.overshootX = (dstParams.W * 2f) * shoulderAngle * shoulderLength; dstParams.overshootY = 0.5f * shoulderAngle * shoulderLength; InitSegments(dstParams); } public void SetMaterialParams(Material mat) { /* mat.SetVector("_CustomToneCurve", uniforms.curve); mat.SetVector("_y0y1", uniforms.y0y1); mat.SetVector("_ToeSegmentA", uniforms.toeSegmentA); mat.SetVector("_ToeSegmentB", uniforms.toeSegmentB); mat.SetVector("_MidSegmentA", uniforms.midSegmentA); mat.SetVector("_MidSegmentB", uniforms.midSegmentB); mat.SetVector("_ShoSegmentA", uniforms.shoSegmentA); mat.SetVector("_ShoSegmentB", uniforms.shoSegmentB); */ Shader.SetGlobalVector("_CustomToneCurve", uniforms.curve); Shader.SetGlobalVector("_y0y1", uniforms.y0y1); Shader.SetGlobalVector("_ToeSegmentA", uniforms.toeSegmentA); Shader.SetGlobalVector("_ToeSegmentB", uniforms.toeSegmentB); Shader.SetGlobalVector("_MidSegmentA", uniforms.midSegmentA); Shader.SetGlobalVector("_MidSegmentB", uniforms.midSegmentB); Shader.SetGlobalVector("_ShoSegmentA", uniforms.shoSegmentA); Shader.SetGlobalVector("_ShoSegmentB", uniforms.shoSegmentB); } void InitSegments(DirectParams srcParams) { var paramsCopy = srcParams; whitePoint = srcParams.W; inverseWhitePoint = 1f / srcParams.W; // normalize params to 1.0 range paramsCopy.W = 1f; paramsCopy.x0 /= srcParams.W; paramsCopy.x1 /= srcParams.W; paramsCopy.overshootX = srcParams.overshootX / srcParams.W; float toeM = 0f; float shoulderM = 0f; { float m, b; AsSlopeIntercept(out m, out b, paramsCopy.x0, paramsCopy.x1, paramsCopy.y0, paramsCopy.y1); float g = srcParams.gamma; // Base function of linear section plus gamma is // y = (mx+b)^g // // which we can rewrite as // y = exp(g*ln(m) + g*ln(x+b/m)) // // and our evaluation function is (skipping the if parts): /* float x0 = (x - offsetX) * scaleX; y0 = exp(m_lnA + m_B*log(x0)); return y0*scaleY + m_offsetY; */ var midSegment = m_Segments[1]; midSegment.offsetX = -(b / m); midSegment.offsetY = 0f; midSegment.scaleX = 1f; midSegment.scaleY = 1f; midSegment.lnA = g * Mathf.Log(m); midSegment.B = g; toeM = EvalDerivativeLinearGamma(m, b, g, paramsCopy.x0); shoulderM = EvalDerivativeLinearGamma(m, b, g, paramsCopy.x1); // apply gamma to endpoints paramsCopy.y0 = Mathf.Max(1e-5f, Mathf.Pow(paramsCopy.y0, paramsCopy.gamma)); paramsCopy.y1 = Mathf.Max(1e-5f, Mathf.Pow(paramsCopy.y1, paramsCopy.gamma)); paramsCopy.overshootY = Mathf.Pow(1f + paramsCopy.overshootY, paramsCopy.gamma) - 1f; } this.x0 = paramsCopy.x0; this.x1 = paramsCopy.x1; this.y0 = paramsCopy.y0; this.y1 = paramsCopy.y1; // Toe section { var toeSegment = m_Segments[0]; toeSegment.offsetX = 0; toeSegment.offsetY = 0f; toeSegment.scaleX = 1f; toeSegment.scaleY = 1f; float lnA, B; SolveAB(out lnA, out B, paramsCopy.x0, paramsCopy.y0, toeM); toeSegment.lnA = lnA; toeSegment.B = B; } // Shoulder section { // Use the simple version that is usually too flat var shoulderSegment = m_Segments[2]; float x0 = (1f + paramsCopy.overshootX) - paramsCopy.x1; float y0 = (1f + paramsCopy.overshootY) - paramsCopy.y1; float lnA, B; SolveAB(out lnA, out B, x0, y0, shoulderM); shoulderSegment.offsetX = (1f + paramsCopy.overshootX); shoulderSegment.offsetY = (1f + paramsCopy.overshootY); shoulderSegment.scaleX = -1f; shoulderSegment.scaleY = -1f; shoulderSegment.lnA = lnA; shoulderSegment.B = B; } // Normalize so that we hit 1.0 at our white point. We wouldn't have do this if we // skipped the overshoot part. { // Evaluate shoulder at the end of the curve float scale = m_Segments[2].Eval(1f); float invScale = 1f / scale; m_Segments[0].offsetY *= invScale; m_Segments[0].scaleY *= invScale; m_Segments[1].offsetY *= invScale; m_Segments[1].scaleY *= invScale; m_Segments[2].offsetY *= invScale; m_Segments[2].scaleY *= invScale; } } // Find a function of the form: // f(x) = e^(lnA + Bln(x)) // where // f(0) = 0; not really a constraint // f(x0) = y0 // f'(x0) = m void SolveAB(out float lnA, out float B, float x0, float y0, float m) { B = (m * x0) / y0; lnA = Mathf.Log(y0) - B * Mathf.Log(x0); } // Convert to y=mx+b void AsSlopeIntercept(out float m, out float b, float x0, float x1, float y0, float y1) { float dy = (y1 - y0); float dx = (x1 - x0); if (dx == 0) m = 1f; else m = dy / dx; b = y0 - x0 * m; } // f(x) = (mx+b)^g // f'(x) = gm(mx+b)^(g-1) float EvalDerivativeLinearGamma(float m, float b, float g, float x) { float ret = g * m * Mathf.Pow(m * x + b, g - 1f); return ret; } /// /// Utility class to retrieve curve values for shader evaluation. /// public class Uniforms { HableCurve parent; internal Uniforms(HableCurve parent) { this.parent = parent; } /// /// A pre-built holding: (inverseWhitePoint, x0, x1, 0). /// public Vector4 curve { get { return new Vector4(parent.inverseWhitePoint, parent.x0, parent.x1, 0f); } } public Vector2 y0y1 { get { return new Vector2(parent.y0, parent.y1); } } /// /// A pre-built holding: (toe.offsetX, toe.offsetY, toe.scaleX, toe.scaleY). /// public Vector4 toeSegmentA { get { var toe = parent.m_Segments[0]; return new Vector4(toe.offsetX, toe.offsetY, toe.scaleX, toe.scaleY); } } /// /// A pre-built holding: (toe.lnA, toe.B, 0, 0). /// public Vector4 toeSegmentB { get { var toe = parent.m_Segments[0]; return new Vector4(toe.lnA, toe.B, 0f, 0f); } } /// /// A pre-built holding: (mid.offsetX, mid.offsetY, mid.scaleX, mid.scaleY). /// public Vector4 midSegmentA { get { var mid = parent.m_Segments[1]; return new Vector4(mid.offsetX, mid.offsetY, mid.scaleX, mid.scaleY); } } /// /// A pre-built holding: (mid.lnA, mid.B, 0, 0). /// public Vector4 midSegmentB { get { var mid = parent.m_Segments[1]; return new Vector4(mid.lnA, mid.B, 0f, 0f); } } /// /// A pre-built holding: (toe.offsetX, toe.offsetY, toe.scaleX, toe.scaleY). /// public Vector4 shoSegmentA { get { var sho = parent.m_Segments[2]; return new Vector4(sho.offsetX, sho.offsetY, sho.scaleX, sho.scaleY); } } /// /// A pre-built holding: (sho.lnA, sho.B, 0, 0). /// public Vector4 shoSegmentB { get { var sho = parent.m_Segments[2]; return new Vector4(sho.lnA, sho.B, 0f, 0f); } } } /// /// The builtin instance for this curve. /// public readonly Uniforms uniforms; } } ================================================ FILE: scatterer/GUI/AtmoGUI.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class AtmoGUI { float Rg = 600000.0f; float atmosphereStartRadiusScale = 1f; float HR = 3.2f; float HM = 0.48f; Vector3 m_betaR = new Vector3(0.029f, 0.0675f, 0.1655f); Vector3 BETA_MSca = new Vector3(0.02f,0.02f,0.02f); Vector3 ozoneAbsorption = new Vector3(0.0000003426f, 0.0000008298f, 0.000000036f); float ozoneHeight = 25f; float ozoneFalloff = 15f; bool useOzone = false; float m_mieG = 0.85f; float AVERAGE_GROUND_REFLECTANCE = 0.1f; float rescale = 1f, thickenRayleigh = 1f, thickenMie = 1f, thickenOzone = 1f; bool multipleScattering = true; bool fastPreviewMode = false; SkyNode targetSkyNode; int selPlanet; public AtmoGUI () { } public void drawAtmoGUI(int selectedPlanet) { GUILayout.BeginHorizontal(); GUILayout.Label("Atmosphere start radius "); GUILayout.TextField((Rg * atmosphereStartRadiusScale).ToString()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Scale start radius"); atmosphereStartRadiusScale=(float)(float.Parse(GUILayout.TextField(atmosphereStartRadiusScale.ToString()))); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Atmo height (auto)"); GUILayout.TextField((AtmoPreprocessor.CalculateRt (Rg*atmosphereStartRadiusScale, HR, HM, m_betaR, BETA_MSca, useOzone, ozoneHeight, ozoneFalloff)-Rg*atmosphereStartRadiusScale).ToString()); GUILayout.EndHorizontal(); GUIvector3NoButton ("Rayleigh Scattering - Beta_R:", ref m_betaR); GUILayout.BeginHorizontal(); GUILayout.Label("Thicken"); thickenRayleigh=(float)(float.Parse(GUILayout.TextField(thickenRayleigh.ToString("00.000")))); if (GUILayout.Button ("Go")) { m_betaR*=thickenRayleigh; generate(); } GUILayout.EndHorizontal(); GUIvector3NoButton ("Mie Scattering - Beta_MSca:", ref BETA_MSca); GUILayout.BeginHorizontal(); GUILayout.Label("Thicken"); thickenMie=(float)(float.Parse(GUILayout.TextField(thickenMie.ToString("00.000")))); if (GUILayout.Button ("Go")) { BETA_MSca*=thickenMie; generate(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Mie G (Mie phase function asymmetry)"); m_mieG = (float)(float.Parse(GUILayout.TextField(m_mieG.ToString()))); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Rayleigh density scale height"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("HR (in KM)"); HR=(float)(float.Parse(GUILayout.TextField(HR.ToString()))); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Mie density scale height"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("HM (in KM)"); HM=(float)(float.Parse(GUILayout.TextField(HM.ToString()))); GUILayout.EndHorizontal(); GUIvector3NoButton("Ozone absorption:", ref ozoneAbsorption); GUILayout.BeginHorizontal(); GUILayout.Label("Thicken"); thickenOzone = (float)(float.Parse(GUILayout.TextField(thickenOzone.ToString("00.000")))); if (GUILayout.Button("Go")) { ozoneAbsorption *= thickenOzone; generate(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Ozone layer altitude (km)"); ozoneHeight = (float)(float.Parse(GUILayout.TextField(ozoneHeight.ToString()))); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Ozone layer falloff/extents (km)"); ozoneFalloff = (float)(float.Parse(GUILayout.TextField(ozoneFalloff.ToString()))); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Use Ozone: " + useOzone.ToString() + " "); if (GUILayout.Button("Toggle")) useOzone = !useOzone; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Auto rescale"); rescale=(float)(float.Parse(GUILayout.TextField(rescale.ToString("00.000")))); if (GUILayout.Button ("Go")) { HR*=rescale; HM*=rescale; m_betaR/=rescale; BETA_MSca/=rescale; ozoneHeight *= rescale; ozoneFalloff *= rescale; ozoneAbsorption /= rescale; generate(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Average ground reflectance"); AVERAGE_GROUND_REFLECTANCE=(float)(float.Parse(GUILayout.TextField(AVERAGE_GROUND_REFLECTANCE.ToString()))); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Multiple scattering: "+multipleScattering.ToString()+" "); if (GUILayout.Button ("Toggle")) multipleScattering = !multipleScattering; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Fast preview mode: "+fastPreviewMode.ToString()); if (GUILayout.Button ("Toggle")) fastPreviewMode = !fastPreviewMode; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button ("Generate")) { generate(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button ("Delete atmo cache")) { AtmoPreprocessor.DeleteCache(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal (); if (!targetSkyNode.isConfigModuleManagerPatch) { if (GUILayout.Button ("Save atmo")) { targetSkyNode.SaveToConfigNode (); } } if (GUILayout.Button ("Load atmo")) { targetSkyNode.LoadFromConfigNode (); loadSettingsForPlanet(selPlanet); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label (".cfg file used:"); GUIStyle guiStyle = new GUIStyle(GUI.skin.textArea); if (targetSkyNode.isConfigModuleManagerPatch) guiStyle.normal.textColor = Color.red; GUILayout.TextField (targetSkyNode.isConfigModuleManagerPatch ? "ModuleManager patch detected, saving disabled" : targetSkyNode.configUrl.parent.url, guiStyle); GUILayout.EndHorizontal (); } void generate() { Utils.LogDebug ("Generating atmosphere from UI for planet: " + targetSkyNode.prolandManager.scattererCelestialBody.celestialBodyName + "" + "With settings:" + "Rg " + (Rg*atmosphereStartRadiusScale).ToString () + " HR " + HR.ToString () + " HM " + HM.ToString () + " m_betaR " + m_betaR.ToString () + " BETA_MSca " + BETA_MSca.ToString () + " m_mieG " + m_mieG.ToString () + " ozoneAbsorption " + ozoneAbsorption.ToString() + " ozoneHeight " + ozoneHeight.ToString() + " ozoneFalloff " + ozoneFalloff.ToString() + " useOzone " + useOzone.ToString() + " AVERAGE_GROUND_REFLECTANCE " + AVERAGE_GROUND_REFLECTANCE.ToString () + " multipleScattering " + multipleScattering.ToString () + " fastPreviewMode " + fastPreviewMode.ToString ()); targetSkyNode.ApplyAtmoFromUI (m_betaR, BETA_MSca, m_mieG, HR, HM, AVERAGE_GROUND_REFLECTANCE, multipleScattering, fastPreviewMode, atmosphereStartRadiusScale, useOzone, ozoneAbsorption, ozoneHeight, ozoneFalloff); } public void loadSettingsForPlanet(int selectedPlanet) { if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active) { targetSkyNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetSkyNode(); selPlanet = selectedPlanet; Rg = targetSkyNode.Rg; atmosphereStartRadiusScale = targetSkyNode.atmosphereStartRadiusScale; HR = targetSkyNode.HR; HM = targetSkyNode.HM; m_betaR = targetSkyNode.m_betaR; BETA_MSca = targetSkyNode.BETA_MSca; m_mieG = targetSkyNode.m_mieG; AVERAGE_GROUND_REFLECTANCE = targetSkyNode.averageGroundReflectance; multipleScattering = targetSkyNode.multipleScattering; ozoneAbsorption = targetSkyNode.ozoneAbsorption; ozoneHeight = targetSkyNode.ozoneHeight; ozoneFalloff = targetSkyNode.ozoneFalloff; useOzone = targetSkyNode.useOzone; fastPreviewMode = false; rescale=1f; thickenRayleigh=1f; thickenMie=1f; } } public void GUIvector3NoButton (string label, ref Vector3 target) { GUILayout.BeginHorizontal (); GUILayout.Label (label); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("R"); target.x = float.Parse(GUILayout.TextField(target.x.ToString())); GUILayout.Label ("G"); target.y = float.Parse(GUILayout.TextField(target.y.ToString())); GUILayout.Label ("B"); target.z = float.Parse (GUILayout.TextField (target.z.ToString())); GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ConfigPointGUI.cs ================================================ using System; using UnityEngine; namespace Scatterer { public class ConfigPointGUI { public int selectedConfigPoint = 0; private Vector2 _scroll; Vector3 sunColor=Vector3.one; float rimBlend = 20f; float rimpower = 600f; float cloudColorMultiplier=1f; float cloudScatteringMultiplier=1f; float cloudSkyIrradianceMultiplier = 1f; float volumetricsColorMultiplier=1f; float godrayStrength = 1.0f; // float godrayCloudAlphaThreshold = 0.1f; float extinctionThickness = 1f; float skyExtinctionTint = 1f; float noonSunlightExtinctionStrength = 1f; float specR = 0f, specG = 0f, specB = 0f, shininess = 0f, flattenScaledSpaceMesh = 0f; //ConfigPoint variables float pointAltitude = 0f; float newCfgPtAlt = 0f; int configPointsCnt; float postProcessingalpha = 78f; float postProcessDepth = 200f; float extinctionTint=100f; float postProcessExposure = 18f; //sky properties float exposure = 25f; float alphaGlobal = 100f; public ConfigPointGUI () { } public void DrawConfigPointGUI (int selectedPlanet) { configPointsCnt = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Count; ConfigPoint _cur = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints [selectedConfigPoint]; //if (!MapView.MapIsEnabled) { GUILayout.BeginHorizontal (); GUILayout.Label ("New point altitude:"); newCfgPtAlt = Convert.ToSingle (GUILayout.TextField (newCfgPtAlt.ToString ())); if (GUILayout.Button ("Add")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Insert (selectedConfigPoint + 1, new ConfigPoint (newCfgPtAlt, alphaGlobal / 100, exposure / 100, postProcessingalpha / 100, postProcessDepth / 10000, postProcessExposure / 100, skyExtinctionTint / 100, extinctionTint / 100, extinctionThickness)); selectedConfigPoint += 1; configPointsCnt = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Count; loadConfigPoint (selectedConfigPoint, selectedPlanet); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Config point:"); if (GUILayout.Button ("<")) { if (selectedConfigPoint > 0) { selectedConfigPoint -= 1; loadConfigPoint (selectedConfigPoint, selectedPlanet); } } GUILayout.TextField ((selectedConfigPoint).ToString ()); if (GUILayout.Button (">")) { if (selectedConfigPoint < configPointsCnt - 1) { selectedConfigPoint += 1; loadConfigPoint (selectedConfigPoint, selectedPlanet); } } //GUILayout.Label (String.Format("Total:{0}", configPointsCnt)); if (GUILayout.Button ("Delete")) { if (configPointsCnt <= 1) Debug.LogError ("Can't delete config point, one or no points remaining"); else { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.RemoveAt (selectedConfigPoint); if (selectedConfigPoint >= configPointsCnt - 1) { selectedConfigPoint = configPointsCnt - 2; } configPointsCnt = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Count; loadConfigPoint (selectedConfigPoint, selectedPlanet); } } GUILayout.EndHorizontal (); GUIfloat ("Point altitude", ref pointAltitude, ref _cur.altitude); _scroll = GUILayout.BeginScrollView (_scroll, false, true, GUILayout.Width (400), GUILayout.Height (Scatterer.Instance.pluginData.scrollSectionHeight)); GUILayout.Label ("(settings with a * are global and not cfgPoint dependent)"); GUILayout.Label ("Sky"); GUIfloat ("Sky Exposure", ref exposure, ref _cur.skyExposure); GUIfloat ("Sky Alpha", ref alphaGlobal, ref _cur.skyAlpha); GUIfloat ("Sky Extinction Tint", ref skyExtinctionTint, ref _cur.skyExtinctionTint); GUILayout.Label ("Scattering and Extinction"); GUIfloat ("Scattering Exposure (scaled+local)", ref postProcessExposure, ref _cur.scatteringExposure); GUIfloat ("Extinction Tint (scaled+local)", ref extinctionTint, ref _cur.extinctionTint); GUIfloat ("Extinction Thickness (scaled+local)", ref extinctionThickness, ref _cur.extinctionThickness); GUIfloat ("Noon Sunlight Extinction strength*", ref noonSunlightExtinctionStrength, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies[selectedPlanet].prolandManager.skyNode.noonSunlightExtinctionStrength); GUILayout.Label ("Post Processing"); GUIfloat ("Post Processing Alpha", ref postProcessingalpha, ref _cur.postProcessAlpha); GUIfloat ("Post Processing Depth", ref postProcessDepth, ref _cur.postProcessDepth); GUILayout.Label ("Godrays"); GUILayout.BeginHorizontal (); GUILayout.Label ("Legacy Godrays strength*"); godrayStrength = Mathf.Min(float.Parse (GUILayout.TextField (godrayStrength.ToString ("0.000"))),1.0f); if (GUILayout.Button ("Set")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.godrayStrength = godrayStrength; } GUILayout.EndHorizontal (); } if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.usesCloudIntegration) { GUILayout.Label ("EVE integration"); GUIfloat ("2d Cloud Color Multiplier*", ref cloudColorMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.cloudColorMultiplier); GUIfloat ("2d Cloud Scattering Multiplier*", ref cloudScatteringMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.cloudScatteringMultiplier); GUIfloat ("2d Cloud Sky irradiance Multiplier*", ref cloudSkyIrradianceMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.cloudSkyIrradianceMultiplier); GUIfloat ("Particle Volumetrics Color Multiplier*", ref volumetricsColorMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.volumetricsColorMultiplier); GUILayout.BeginHorizontal (); GUILayout.Label ("Preserve 2d cloud colors*"); GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.EVEIntegration_preserveCloudColors.ToString ()); if (GUILayout.Button ("Toggle")) Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TogglePreserveCloudColors (); GUILayout.EndHorizontal (); // GUIfloat ("Godray alpha threshold* (alpha value above which a cloud casts a godray)", ref godrayCloudAlphaThreshold, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.godrayCloudAlphaThreshold); // GUIfloat("Volumetrics Scattering Multiplier", ref volumetricsScatteringMultiplier, ref Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.volumetricsScatteringMultiplier); // GUIfloat("Volumetrics Sky irradiance Multiplier", ref volumetricsSkyIrradianceMultiplier, ref Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.volumetricsSkyIrradianceMultiplier); } GUILayout.Label ("ScaledSpace model"); GUILayout.BeginHorizontal (); GUILayout.Label ("RimBlend*"); rimBlend = Convert.ToSingle (GUILayout.TextField (rimBlend.ToString ())); GUILayout.Label ("RimPower*"); rimpower = Convert.ToSingle (GUILayout.TextField (rimpower.ToString ())); if (GUILayout.Button ("Set")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.rimBlend = rimBlend; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.rimpower = rimpower; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakStockAtmosphere (); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Spec*: R"); specR = (float)(Convert.ToDouble (GUILayout.TextField (specR.ToString ()))); GUILayout.Label ("G"); specG = (float)(Convert.ToDouble (GUILayout.TextField (specG.ToString ()))); GUILayout.Label ("B"); specB = (float)(Convert.ToDouble (GUILayout.TextField (specB.ToString ()))); GUILayout.Label ("shine*"); shininess = (float)(Convert.ToDouble (GUILayout.TextField (shininess.ToString ()))); if (GUILayout.Button ("Set")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.specR = specR; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.specG = specG; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.specB = specB; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.shininess = shininess; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.flattenScaledSpaceMesh = flattenScaledSpaceMesh; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakStockAtmosphere (); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Flatten scaled mesh"); flattenScaledSpaceMesh = (float)(Convert.ToDouble (GUILayout.TextField (flattenScaledSpaceMesh.ToString ("0.000")))); if (GUILayout.Button ("Set")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.flattenScaledSpaceMesh = flattenScaledSpaceMesh; Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakScaledMesh(); Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.scaledScatteringContainer.ApplyNewMesh(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.parentScaledTransform.GetComponent ().sharedMesh); } GUILayout.EndHorizontal (); Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.adjustScaledTexture = GUILayout.Toggle (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.adjustScaledTexture, "Adjust scaled texture"); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.adjustScaledTexture) { GUILayout.BeginHorizontal (); GUILayout.Label ("Land (brightness/contrast/saturation)"); GUILayout.EndHorizontal (); var node = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode; GUILayout.BeginHorizontal (); node.scaledLandBrightnessAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledLandBrightnessAdjust.ToString ("0.00")))); node.scaledLandContrastAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledLandContrastAdjust.ToString ("0.00")))); node.scaledLandSaturationAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledLandSaturationAdjust.ToString ("0.00")))); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Ocean (brightness/contrast/saturation)"); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); node.scaledOceanBrightnessAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledOceanBrightnessAdjust.ToString ("0.00")))); node.scaledOceanContrastAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledOceanContrastAdjust.ToString ("0.00")))); node.scaledOceanSaturationAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledOceanSaturationAdjust.ToString ("0.00")))); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); if (GUILayout.Button ("Set")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakStockScaledTexture(); } GUILayout.EndHorizontal (); } GUILayout.Label ("Misc"); GUIColorNoButton("Sunlight color "+ Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.mainSunLight.name+ " (Not saved automatically, save manually to PlanetsList)", ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.sunColor); int index = 0; foreach (SecondarySun secondarySun in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.secondarySuns) { Vector4 colorVect = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.planetShineRGBMatrix.GetRow(index); Color col = new Color(colorVect.x, colorVect.y, colorVect.z); GUIColorNoButton("Secondary sunlight color "+secondarySun.config.celestialBodyName, ref col); colorVect = new Vector4(col.r, col.g, col.b, colorVect.w); Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.planetShineRGBMatrix.SetRow(index, colorVect); index++; } GUILayout.EndScrollView (); GUILayout.BeginHorizontal (); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint == 0) GUILayout.Label ("Current state:Lowest configPoint, cfgPoint 0"); else if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint >= configPointsCnt) GUILayout.Label (String.Format ("Current state:Highest configPoint, cfgPoint{0}", Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint - 1)); else GUILayout.Label (String.Format ("Current state:{0}% cfgPoint{1} + {2}% cfgPoint{3} ", (int)(100 * (1 - Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.percentage)), Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint - 1, (int)(100 * Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.percentage), Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint)); GUILayout.EndHorizontal (); // GUILayout.BeginHorizontal (); // if (GUILayout.Button ("toggle sky")) // { // Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.skyEnabled = !Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.skyEnabled; // if (Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.skyEnabled) // Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.tweakStockAtmosphere(); // else // Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.RestoreStockAtmosphere(); // } // GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); if (!Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch) { if (GUILayout.Button ("Save atmo")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.SaveToConfigNode (); } } if (GUILayout.Button ("Load atmo")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.LoadFromConfigNode (); getSettingsFromSkynode (selectedPlanet); loadConfigPoint (selectedConfigPoint, selectedPlanet); //Restore sun color, hacky I know Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.sunColor = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.scattererCelestialBody.sunColor; } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label (".cfg file used:"); GUIStyle guiStyle = new GUIStyle(GUI.skin.textArea); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch) guiStyle.normal.textColor = Color.red; GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch ? "ModuleManager patch detected, saving disabled" : Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configUrl.parent.url, guiStyle); GUILayout.EndHorizontal (); } public void loadSettingsForPlanet(int selectedPlanet) { selectedConfigPoint = 0; if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active) { loadConfigPoint (selectedConfigPoint, selectedPlanet); getSettingsFromSkynode (selectedPlanet); } } public void getSettingsFromSkynode (int selectedPlanet) { SkyNode skyNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode; ConfigPoint selected = skyNode.configPoints [selectedConfigPoint]; postProcessingalpha = selected.postProcessAlpha; postProcessDepth = selected.postProcessDepth; extinctionTint = selected.extinctionTint; postProcessExposure = selected.scatteringExposure; exposure = selected.skyExposure; alphaGlobal = selected.skyAlpha; configPointsCnt = skyNode.configPoints.Count; specR = skyNode.specR; specG = skyNode.specG; specB = skyNode.specB; shininess = skyNode.shininess; flattenScaledSpaceMesh = skyNode.flattenScaledSpaceMesh; rimBlend = skyNode.rimBlend; rimpower = skyNode.rimpower; skyExtinctionTint = selected.skyExtinctionTint; extinctionThickness = selected.extinctionThickness; cloudColorMultiplier = skyNode.cloudColorMultiplier; cloudScatteringMultiplier = skyNode.cloudScatteringMultiplier; cloudSkyIrradianceMultiplier = skyNode.cloudSkyIrradianceMultiplier; volumetricsColorMultiplier = skyNode.volumetricsColorMultiplier; // volumetricsScatteringMultiplier = skyNode.volumetricsScatteringMultiplier; // volumetricsSkyIrradianceMultiplier = skyNode.volumetricsSkyIrradianceMultiplier; godrayStrength = skyNode.godrayStrength; // godrayCloudAlphaThreshold = skyNode.godrayCloudAlphaThreshold; } public void loadConfigPoint (int point, int selectedPlanet) { ConfigPoint _cur = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints [point]; postProcessDepth = _cur.postProcessDepth; extinctionTint = _cur.extinctionTint; postProcessExposure = _cur.scatteringExposure; postProcessingalpha = _cur.postProcessAlpha; alphaGlobal = _cur.skyAlpha; exposure = _cur.skyExposure; skyExtinctionTint = _cur.skyExtinctionTint; extinctionThickness = _cur.extinctionThickness; pointAltitude = _cur.altitude; } public void GUIfloat (string label, ref float local, ref float target) { GUILayout.BeginHorizontal (); GUILayout.Label (label); local = float.Parse (GUILayout.TextField (local.ToString ())); if (GUILayout.Button ("Set")) { target = local; } GUILayout.EndHorizontal (); } public void GUIColorNoButton (string label, ref Color target) { GUILayout.BeginHorizontal (); GUILayout.Label (label); target.r = float.Parse (GUILayout.TextField (target.r.ToString ())); target.g = float.Parse (GUILayout.TextField (target.g.ToString ())); target.b = float.Parse (GUILayout.TextField (target.b.ToString ())); GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/GUIhandler.cs ================================================ using System; using UnityEngine; namespace Scatterer { public class GUIhandler: MonoBehaviour { public Rect windowRect = new Rect (0, 0, 400, 50); public int windowId; public bool visible = false; public bool mainOptions=false; public bool sunflareOptions=false; public int selectedPlanet = 0; bool wireFrame = false; enum PlanetSettingsTabs { Atmo, Ocean, ConfigPoints, } PlanetSettingsTabs selectedPlanetSettingsTab = PlanetSettingsTabs.Atmo; MainOptionsGUI mainOptionsGUI = new MainOptionsGUI(); ConfigPointGUI configPointGUI = new ConfigPointGUI (); AtmoGUI atmoGUI = new AtmoGUI (); OceanGUI oceanGUI = new OceanGUI (); SunflareGUI sunflareGUI = new SunflareGUI (); public GUIhandler () { } public void Init() { windowId = UnityEngine.Random.Range(int.MinValue, int.MaxValue); mainOptions = (HighLogic.LoadedScene == GameScenes.SPACECENTER); windowRect.x=Scatterer.Instance.pluginData.inGameWindowLocation.x; windowRect.y=Scatterer.Instance.pluginData.inGameWindowLocation.y; //prevent window from going offscreen, only do this on start as otherwise it messes with lower resolutions windowRect.x = Mathf.Clamp(windowRect.x, 0, Screen.width - windowRect.width); windowRect.y = Mathf.Clamp(windowRect.y, 0, Screen.height - windowRect.height); } public void UpdateGUIvisible() { if ((Input.GetKey (Scatterer.Instance.pluginData.guiModifierKey1) || Input.GetKey (Scatterer.Instance.pluginData.guiModifierKey2)) && (Input.GetKeyDown (Scatterer.Instance.pluginData.guiKey1) || (Input.GetKeyDown (Scatterer.Instance.pluginData.guiKey2)))) { if (ToolbarButton.Instance.button!= null) { if (visible) ToolbarButton.Instance.button.SetFalse(false); else ToolbarButton.Instance.button.SetTrue(false); } visible = !visible; } } public void DrawGui() { if (visible) { windowRect = GUILayout.Window (windowId, windowRect, DrawScattererWindow,"Scatterer v"+Scatterer.Instance.versionNumber+": " + Scatterer.Instance.pluginData.guiModifierKey1String+"/"+Scatterer.Instance.pluginData.guiModifierKey2String +"+" +Scatterer.Instance.pluginData.guiKey1String +"/"+Scatterer.Instance.pluginData.guiKey2String+" toggle"); } } public void DrawScattererWindow (int windowId) { if (mainOptions) { mainOptionsGUI.DrawOptionsMenu (); } else if (Scatterer.Instance.isActive) { GUILayout.BeginHorizontal (); if (GUILayout.Button ("Planet settings")) { windowRect.width = 400; windowRect.height = 40; sunflareOptions = false; } if (Scatterer.Instance.mainSettings.fullLensFlareReplacement && Scatterer.Instance.sunflareManager && Scatterer.Instance.sunflareManager.scattererSunFlares != null) { if (GUILayout.Button ("Sunflare settings")) { windowRect.width = 400; windowRect.height = 40; sunflareGUI.InitSunflareGUI(); sunflareOptions = true; } } GUILayout.EndHorizontal (); if (sunflareOptions) { sunflareGUI.DrawSunflareGUI(); } else { DrawPlanetSelectionHeader (); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active) { GUILayout.BeginHorizontal (); if (GUILayout.Button("Atmosphere")) { windowRect.width = 300; windowRect.height = 40; selectedPlanetSettingsTab = PlanetSettingsTabs.Atmo; } if (GUILayout.Button("Ocean") && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies[selectedPlanet].hasOcean) { windowRect.width = 400; windowRect.height = 40; selectedPlanetSettingsTab = PlanetSettingsTabs.Ocean; } if (GUILayout.Button ("Config points")) { windowRect.width = 400; windowRect.height = 40; selectedPlanetSettingsTab = PlanetSettingsTabs.ConfigPoints; } GUILayout.EndHorizontal (); if (selectedPlanetSettingsTab == PlanetSettingsTabs.ConfigPoints) { configPointGUI.DrawConfigPointGUI(selectedPlanet); } else if (selectedPlanetSettingsTab == PlanetSettingsTabs.Atmo) { atmoGUI.drawAtmoGUI (selectedPlanet); } else { oceanGUI.drawOceanGUI (selectedPlanet); } } DrawSharedFooterGUI (); } } else { GUILayout.Label (String.Format ("Inactive in tracking station and VAB/SPH")); GUILayout.EndHorizontal (); } GUI.DragWindow(); } //move the getSettings, loadConfigPoint, selectedConfigPoint = 0; to method in ConfigPoint GUI void DrawPlanetSelectionHeader () { GUILayout.BeginHorizontal (); GUILayout.Label ("Planet:"); if (GUILayout.Button ("<")) { if (selectedPlanet > 0) { selectedPlanet -= 1; configPointGUI.loadSettingsForPlanet(selectedPlanet); atmoGUI.loadSettingsForPlanet(selectedPlanet); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].hasOcean) { oceanGUI.buildOceanGUI (selectedPlanet); } } } GUILayout.TextField ((Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].celestialBodyName).ToString ()); if (GUILayout.Button (">")) { if (selectedPlanet < Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Count - 1) { selectedPlanet += 1; configPointGUI.loadSettingsForPlanet(selectedPlanet); atmoGUI.loadSettingsForPlanet(selectedPlanet); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].hasOcean) { oceanGUI.buildOceanGUI (selectedPlanet); } } } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Loaded:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active.ToString () + ". Has ocean:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].hasOcean.ToString ()); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Load distance:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].loadDistance.ToString () + ". Unload distance:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].unloadDistance.ToString ()); GUILayout.EndHorizontal (); } void DrawSharedFooterGUI () { if (Scatterer.Instance.mainSettings.integrateWithEVEClouds) { GUILayout.BeginHorizontal(); if (GUILayout.Button("Map EVE clouds")) { Scatterer.Instance.eveReflectionHandler.MapEVEClouds(); foreach (ScattererCelestialBody _cel in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies) { if (_cel.active) { _cel.prolandManager.skyNode.InitEVEClouds(); } } } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (GUILayout.Button ("Toggle WireFrame")) { if (wireFrame) { if (HighLogic.LoadedScene != GameScenes.TRACKSTATION) { if (Scatterer.Instance.nearCamera.gameObject.GetComponent (typeof(Wireframe))) Component.Destroy (Scatterer.Instance.nearCamera.gameObject.GetComponent (typeof(Wireframe))); if (Scatterer.Instance.farCamera && Scatterer.Instance.farCamera.gameObject.GetComponent (typeof(Wireframe))) Component.Destroy (Scatterer.Instance.farCamera.gameObject.GetComponent (typeof(Wireframe))); } if (Scatterer.Instance.scaledSpaceCamera.gameObject.GetComponent (typeof(Wireframe))) Component.Destroy (Scatterer.Instance.scaledSpaceCamera.gameObject.GetComponent (typeof(Wireframe))); wireFrame = false; } else { if (HighLogic.LoadedScene != GameScenes.TRACKSTATION) { Scatterer.Instance.nearCamera.gameObject.AddComponent (typeof(Wireframe)); if (Scatterer.Instance.farCamera) Scatterer.Instance.farCamera.gameObject.AddComponent (typeof(Wireframe)); } Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(Wireframe)); wireFrame = true; } } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); if (GUILayout.Button ("Reload shader bundles")) { ShaderReplacer.Instance.LoadAssetBundle (); } GUILayout.EndHorizontal (); } public void LoadPlanet(int planetIndex) { selectedPlanetSettingsTab = PlanetSettingsTabs.Atmo; selectedPlanet = planetIndex; configPointGUI.loadSettingsForPlanet (selectedPlanet); atmoGUI.loadSettingsForPlanet(selectedPlanet); if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode()) { oceanGUI.buildOceanGUI (planetIndex); } } } } ================================================ FILE: scatterer/GUI/MainOptionsGUI.cs ================================================ using System; using System.Linq; using UnityEngine; namespace Scatterer { public class MainOptionsGUI { enum MainMenuTabs { QualityPresets, IndividualSettings } enum IndividualSettingsTabs { Scattering, Ocean, Sunflare, Lighting, Shadows, EVEintegration, Misc } MainMenuTabs selectedMainMenuTab = MainMenuTabs.QualityPresets; IndividualSettingsTabs selectedIndividualSettingsTab = IndividualSettingsTabs.Scattering; String[] qualityPresetsStrings; string currentPreset; int selQualityPresetInt = -1; public MainOptionsGUI () { } public void DrawOptionsMenu () { GUILayout.BeginHorizontal (); { GUILayout.Label ("Menu scroll section height"); Scatterer.Instance.pluginData.scrollSectionHeight = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.pluginData.scrollSectionHeight.ToString ()))); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); { GUILayout.Label (".cfg file used (display only):"); GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.baseConfigs [0].parent.url); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); { if (GUILayout.Button ("Quality Presets")) { InitPresets(); selectedMainMenuTab = MainMenuTabs.QualityPresets; } if (GUILayout.Button ("Customize Settings")) { selectedMainMenuTab = MainMenuTabs.IndividualSettings; } } GUILayout.EndHorizontal (); if (selectedMainMenuTab == MainMenuTabs.QualityPresets) { DrawQualityPresets(); } else { DrawIndividualSettings (); } } void DrawQualityPresets () { if (qualityPresetsStrings == null) { InitPresets(); } GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); { GUILayout.Label("Current preset:"); GUILayout.TextField(currentPreset); } GUILayout.EndHorizontal(); selQualityPresetInt = GUILayout.SelectionGrid(selQualityPresetInt, qualityPresetsStrings, 1); GUILayout.Label(""); if (GUILayout.Button("Apply preset")) { if (qualityPresetsStrings.Count() > 0) { Utils.LogInfo("Applying quality preset " + qualityPresetsStrings[selQualityPresetInt]); QualityPresetsLoader.LoadPresetIntoMainSettings(Scatterer.Instance.mainSettings, qualityPresetsStrings[selQualityPresetInt]); currentPreset = qualityPresetsStrings[selQualityPresetInt]; } } GUILayout.EndVertical(); } private void InitPresets() { if (qualityPresetsStrings == null) { qualityPresetsStrings = QualityPresetsLoader.GetPresetsList(); } currentPreset = QualityPresetsLoader.FindPresetOfCurrentSettings(Scatterer.Instance.mainSettings); int index = qualityPresetsStrings.IndexOf(currentPreset); selQualityPresetInt = index; } void DrawIndividualSettings () { GUILayout.BeginHorizontal (); { if (GUILayout.Button ("Scattering")) { selectedIndividualSettingsTab = IndividualSettingsTabs.Scattering; } if (GUILayout.Button ("Ocean")) { selectedIndividualSettingsTab = IndividualSettingsTabs.Ocean; } if (GUILayout.Button ("Sunflare")) { selectedIndividualSettingsTab = IndividualSettingsTabs.Sunflare; } if (GUILayout.Button ("Lighting")) { selectedIndividualSettingsTab = IndividualSettingsTabs.Lighting; } if (GUILayout.Button ("Shadows")) { selectedIndividualSettingsTab = IndividualSettingsTabs.Shadows; } if (GUILayout.Button ("EVE Clouds")) { selectedIndividualSettingsTab = IndividualSettingsTabs.EVEintegration; } if (GUILayout.Button ("Misc.")) { selectedIndividualSettingsTab = IndividualSettingsTabs.Misc; } } GUILayout.EndHorizontal (); if (selectedIndividualSettingsTab == IndividualSettingsTabs.Scattering) { Scatterer.Instance.mainSettings.useLegacyTerrainGodrays = GUILayout.Toggle(Scatterer.Instance.mainSettings.useLegacyTerrainGodrays, "Legacy terrain godrays (Requires long-distance shadows and shadowMapResolution override, Directx11 only)"); if (Scatterer.Instance.mainSettings.useLegacyTerrainGodrays) { //Godrays tesselation placeholder } //Scatterer.Instance.mainSettings.quarterResScattering = GUILayout.Toggle (Scatterer.Instance.mainSettings.quarterResScattering, "Render scattering in 1/4 resolution (speedup, incompatible and disabled with godrays)"); //Scatterer.Instance.mainSettings.mergeDepthPrePass = GUILayout.Toggle (Scatterer.Instance.mainSettings.mergeDepthPrePass, "Merge depth pre-pass into main depth for culling (experimental, may give small speedup but may cause z-fighting"); Scatterer.Instance.mainSettings.useTemporalAntiAliasing = GUILayout.Toggle(Scatterer.Instance.mainSettings.useTemporalAntiAliasing, "Temporal Antialiasing (TAA), can combine with SMAA"); if (Scatterer.Instance.mainSettings.useTemporalAntiAliasing) { GUILayout.BeginHorizontal (); { GUILayout.Label ("Stationary blending"); Scatterer.Instance.mainSettings.taaStationaryBlending = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaStationaryBlending.ToString("0.00"))),0f,0.99f); GUILayout.Label(" Motion blending"); Scatterer.Instance.mainSettings.taaMotionBlending = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaMotionBlending.ToString("0.00"))),0f,0.99f); GUILayout.Label(" Sample spread"); Scatterer.Instance.mainSettings.taaJitterSpread = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaJitterSpread.ToString("0.00"))),0.1f,1f); GUILayout.Label(" Sharpness"); Scatterer.Instance.mainSettings.taaSharpness = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaSharpness.ToString("0.00"))), 0f, 1f); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); GUILayout.Label("Disable TAA below framerate threshold (when SMAA is enabled)"); Scatterer.Instance.mainSettings.disableTaaBelowFrameRateThreshold = Convert.ToInt32(GUILayout.TextField(Scatterer.Instance.mainSettings.disableTaaBelowFrameRateThreshold.ToString())); GUILayout.EndHorizontal(); Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing = GUILayout.Toggle(Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing, "Subpixel Morphological Antialiasing (SMAA), can combine with TAA"); if (Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing) { GUILayout.BeginHorizontal (); { GUILayout.Label ("SMAA quality (1:normal,2:high)"); Scatterer.Instance.mainSettings.smaaQuality = (Int32) Mathf.Clamp( (float)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.smaaQuality.ToString ()))),1f,2f); } GUILayout.EndHorizontal (); } GUILayout.BeginHorizontal (); GUILayout.Label ("Tonemapper (0:disabled,1:bruneton,2:uncharted)"); Scatterer.Instance.mainSettings.scatteringTonemapper = (Int32) Mathf.Clamp( (float)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.scatteringTonemapper.ToString ()))),0f,2f); GUILayout.EndHorizontal (); /* if (Scatterer.Instance.mainSettings.scatteringTonemapper == 3) { GUILayout.BeginHorizontal(); { GUILayout.Label("Toe strength"); Scatterer.Instance.mainSettings.hableToeStrength =float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableToeStrength.ToString("0.00"))); GUILayout.Label("Toe length"); Scatterer.Instance.mainSettings.hableToeLength = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableToeLength.ToString("0.00"))); GUILayout.Label("Shoulder strength"); Scatterer.Instance.mainSettings.hableShoulderStrength = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableShoulderStrength.ToString("0.00"))); GUILayout.Label("Shoulder length"); Scatterer.Instance.mainSettings.hableShoulderLength = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableShoulderLength.ToString("0.00"))); GUILayout.Label("Shoulder angle"); Scatterer.Instance.mainSettings.hableShoulderAngle = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableShoulderAngle.ToString("0.00"))); GUILayout.Label("Gamma"); Scatterer.Instance.mainSettings.hableGamma = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableGamma.ToString("0.00"))); } GUILayout.EndHorizontal(); } */ GUILayout.BeginHorizontal(); Scatterer.Instance.mainSettings.useLowResolutionAtmosphere = GUILayout.Toggle(Scatterer.Instance.mainSettings.useLowResolutionAtmosphere, "Use low resolution atmosphere (for slower machines that get white atmos)"); GUILayout.EndHorizontal(); } else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Ocean) { Scatterer.Instance.mainSettings.useOceanShaders = GUILayout.Toggle (Scatterer.Instance.mainSettings.useOceanShaders, "Ocean shaders"); if (Scatterer.Instance.mainSettings.useOceanShaders) { GUILayout.BeginHorizontal (); { GUILayout.Label ("\t"); GUILayout.BeginVertical (); { GUILayout.BeginHorizontal (); GUILayout.Label ("Fourier grid size (64:fast,128:normal,256:HQ)"); Scatterer.Instance.mainSettings.m_fourierGridSize = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.m_fourierGridSize.ToString ()))); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Mesh resolution (pixels covered by a mesh quad, lower is better but slower)"); Scatterer.Instance.mainSettings.oceanMeshResolution = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.oceanMeshResolution.ToString ()))); GUILayout.EndHorizontal (); Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions, "Transparency and refractions"); Scatterer.Instance.mainSettings.oceanFoam = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanFoam, "Foam"); Scatterer.Instance.mainSettings.oceanSkyReflections = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanSkyReflections, "Sky reflections"); Scatterer.Instance.mainSettings.shadowsOnOcean = GUILayout.Toggle (Scatterer.Instance.mainSettings.shadowsOnOcean, "Surface receives shadows"); Scatterer.Instance.mainSettings.oceanPixelLights = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanPixelLights, "Secondary lights compatibility (huge performance hit when lights on)"); Scatterer.Instance.mainSettings.oceanCaustics = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCaustics, "Underwater caustics"); Scatterer.Instance.mainSettings.oceanLightRays = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanLightRays, "Underwater light rays"); GUI.contentColor = SystemInfo.supportsAsyncGPUReadback && SystemInfo.supportsComputeShaders ? Color.white : Color.gray; Scatterer.Instance.mainSettings.oceanCraftWaveInteractions = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions, "Waves interact with ships (Requires asyncGPU readback, Directx11 only)"); if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) { GUILayout.BeginHorizontal (); { GUILayout.Label ("\t"); GUILayout.BeginVertical (); { Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance, "Override water crash tolerance"); if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance) { GUILayout.BeginHorizontal (); GUILayout.Label ("Crash tolerance (default is 1.2)"); Scatterer.Instance.mainSettings.buoyancyCrashToleranceMultOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.buoyancyCrashToleranceMultOverride.ToString ("00.00"))); GUILayout.EndHorizontal (); } Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag, "Override water drag"); Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity, "Override max water recovery velocity"); if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity) { GUILayout.BeginHorizontal (); GUILayout.Label ("Maximum recovery velocity (default is 0.3)"); Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity.ToString ("00.00"))); GUILayout.EndHorizontal (); } } GUILayout.EndVertical (); } GUILayout.EndHorizontal (); } } GUILayout.EndVertical (); } GUILayout.EndHorizontal (); } } else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Lighting) { Scatterer.Instance.mainSettings.useEclipses = GUILayout.Toggle (Scatterer.Instance.mainSettings.useEclipses, "Eclipses (WIP, sky/orbit only for now)"); Scatterer.Instance.mainSettings.useRingShadows = GUILayout.Toggle (Scatterer.Instance.mainSettings.useRingShadows, "Kopernicus ring shadows (linear only, tiled rings not supported)"); Scatterer.Instance.mainSettings.disableAmbientLight = GUILayout.Toggle (Scatterer.Instance.mainSettings.disableAmbientLight, "Disable scaled space ambient light"); Scatterer.Instance.mainSettings.sunlightExtinction = GUILayout.Toggle (Scatterer.Instance.mainSettings.sunlightExtinction, "Sunlight extinction (direct sun light changes color with sunset/dusk)"); Scatterer.Instance.mainSettings.underwaterLightDimming = GUILayout.Toggle (Scatterer.Instance.mainSettings.underwaterLightDimming, "Dim light underwater"); } else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Shadows) { Scatterer.Instance.mainSettings.d3d11ShadowFix = GUILayout.Toggle (Scatterer.Instance.mainSettings.d3d11ShadowFix, "1.9+ Directx11 flickering shadows fix (recommended for 1.9, 1.10)"); Scatterer.Instance.mainSettings.terrainShadows = GUILayout.Toggle (Scatterer.Instance.mainSettings.terrainShadows, "Long-Distance Terrain shadows"); if (Scatterer.Instance.mainSettings.terrainShadows) { GUILayout.BeginHorizontal (); { GUILayout.Label (" "); GUILayout.BeginVertical (); { GUI.contentColor = Scatterer.Instance.unifiedCameraMode ? Color.white : Color.gray; GUILayout.Label ((Scatterer.Instance.unifiedCameraMode ? "[Active] " : "[Inactive] ") + "Unified camera mode (1.9+ Directx11):"); GUILayout.BeginHorizontal (); { GUILayout.Label ("\t"); GUILayout.BeginVertical (); { GUILayout.BeginHorizontal (); { GUILayout.Label ("Shadows Distance (in meters):"); Scatterer.Instance.mainSettings.unifiedCamShadowsDistance = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowsDistance.ToString ("0"))); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); { GUILayout.Label ("Shadowmap resolution (power of 2, zero for no override):"); Scatterer.Instance.mainSettings.unifiedCamShadowResolutionOverride = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowResolutionOverride.ToString ()))); } GUILayout.EndHorizontal (); GUIvector3NoButton ("Shadow cascade splits (zeroes for no override):", ref Scatterer.Instance.mainSettings.unifiedCamShadowCascadeSplitsOverride); GUILayout.BeginHorizontal (); { GUILayout.Label ("Shadow bias (0 for no override)"); Scatterer.Instance.mainSettings.unifiedCamShadowBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowBiasOverride.ToString ("0.000"))); GUILayout.Label ("Normal bias (0 for no override)"); Scatterer.Instance.mainSettings.unifiedCamShadowNormalBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowNormalBiasOverride.ToString ("0.000"))); } GUILayout.EndHorizontal (); } GUILayout.EndVertical (); } GUILayout.EndHorizontal (); GUI.contentColor = !Scatterer.Instance.unifiedCameraMode ? Color.white : Color.gray; GUILayout.Label ((!Scatterer.Instance.unifiedCameraMode ? "[Active] " : "[Inactive] ") + "Dual camera mode (1.8, 1.9 and 1.10 Opengl):"); GUILayout.BeginHorizontal (); { GUILayout.Label ("\t"); GUILayout.BeginVertical (); { GUILayout.BeginHorizontal (); { GUILayout.Label ("Shadows Distance (in meters):"); Scatterer.Instance.mainSettings.dualCamShadowsDistance = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowsDistance.ToString ("0"))); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); { GUILayout.Label ("Shadowmap resolution (power of 2, zero for no override):"); Scatterer.Instance.mainSettings.dualCamShadowResolutionOverride = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowResolutionOverride.ToString ()))); } GUILayout.EndHorizontal (); GUIvector3NoButton ("Shadow cascade splits (zeroes for no override):", ref Scatterer.Instance.mainSettings.dualCamShadowCascadeSplitsOverride); GUILayout.BeginHorizontal (); { GUILayout.Label ("Shadow bias (0 for no override)"); Scatterer.Instance.mainSettings.dualCamShadowBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowBiasOverride.ToString ("0.000"))); GUILayout.Label ("Normal bias (0 for no override)"); Scatterer.Instance.mainSettings.dualCamShadowNormalBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowNormalBiasOverride.ToString ("0.000"))); } GUILayout.EndHorizontal (); } GUILayout.EndVertical (); } GUILayout.EndHorizontal (); GUILayout.EndVertical (); } GUILayout.EndHorizontal (); } } } else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Sunflare) { Scatterer.Instance.mainSettings.fullLensFlareReplacement = GUILayout.Toggle (Scatterer.Instance.mainSettings.fullLensFlareReplacement, "Lens flare shader"); } else if (selectedIndividualSettingsTab == IndividualSettingsTabs.EVEintegration) { Scatterer.Instance.mainSettings.integrateWithEVEClouds = GUILayout.Toggle (Scatterer.Instance.mainSettings.integrateWithEVEClouds, "Integrate effects with EVE clouds (may require restart)"); // if (Scatterer.Instance.mainSettings.integrateWithEVEClouds) // { // Scatterer.Instance.mainSettings.integrateEVECloudsGodrays = GUILayout.Toggle (Scatterer.Instance.mainSettings.integrateEVECloudsGodrays, "EVE clouds cast godrays (require godrays)"); // } } else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Misc) { GUILayout.BeginHorizontal (); { Scatterer.Instance.mainSettings.overrideNearClipPlane = GUILayout.Toggle (Scatterer.Instance.mainSettings.overrideNearClipPlane, "Override Near ClipPlane (not recommended - restart on disable)"); Scatterer.Instance.mainSettings.nearClipPlane = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.nearClipPlane.ToString ("0.000"))); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); { Scatterer.Instance.mainSettings.useDithering = GUILayout.Toggle (Scatterer.Instance.mainSettings.useDithering, "Use dithering (Reduces color banding in sky and scattering, disable if you notice dithering patterns"); } GUILayout.EndHorizontal (); } } public void GUIvector3NoButton (string label, ref Vector3 target) { GUILayout.BeginHorizontal (); GUILayout.Label (label); target.x = float.Parse (GUILayout.TextField (target.x.ToString ("0.0000"))); target.y = float.Parse (GUILayout.TextField (target.y.ToString ("0.0000"))); target.z = float.Parse (GUILayout.TextField (target.z.ToString ("0.0000"))); GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/AbstractGUIModule.cs ================================================ //Generic GUIModule, to be overriden by concrete classes that provide their own implementation of RenderGUI using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public abstract class AbstractGUIModule { static protected BindingFlags Flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; public AbstractGUIModule () { } public abstract void RenderGUI (); } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleBool.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleBool : AbstractGUIModule { bool localVariable = false; string label = ""; object targetObject; FieldInfo targetField; public GUIModuleBool (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (bool) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); GUILayout.TextField (targetField.GetValue(targetObject).ToString ()); if (GUILayout.Button ("Toggle")) { targetField.SetValue(targetObject, !(bool)targetField.GetValue(targetObject)); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleFloat.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleFloat : AbstractGUIModule { float localVariable = 0f; string label = ""; object targetObject; FieldInfo targetField; public GUIModuleFloat (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (float) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); localVariable = float.Parse (GUILayout.TextField (localVariable.ToString ())); if (GUILayout.Button ("Set")) { targetField.SetValue(targetObject, localVariable); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleInt.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleInt : AbstractGUIModule { int localVariable = 0; string label = ""; object targetObject; FieldInfo targetField; public GUIModuleInt (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (int) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); localVariable = (Int32)(Convert.ToInt32 (GUILayout.TextField (localVariable.ToString ()))); if (GUILayout.Button ("Set")) { targetField.SetValue(targetObject, localVariable); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleLabel.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleLabel : AbstractGUIModule { string label = ""; public GUIModuleLabel (string label) { this.label = label; } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleString.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleString : AbstractGUIModule { string localVariable = ""; string label = ""; object targetObject; FieldInfo targetField; public GUIModuleString (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (string) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); localVariable = GUILayout.TextField (localVariable); if (GUILayout.Button ("Set")) { targetField.SetValue(targetObject, localVariable); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleVector2.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleVector2 : AbstractGUIModule { Vector2 localVariable = new Vector2(0f,0f); string label = ""; object targetObject; FieldInfo targetField; public GUIModuleVector2 (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (Vector2) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); localVariable.x = float.Parse (GUILayout.TextField (localVariable.x.ToString ())); localVariable.y = float.Parse (GUILayout.TextField (localVariable.y.ToString ())); if (GUILayout.Button ("Set")) { targetField.SetValue(targetObject, localVariable); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleVector3.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleVector3 : AbstractGUIModule { Vector3 localVariable = new Vector3(0f,0f,0f); string label = ""; object targetObject; FieldInfo targetField; public GUIModuleVector3 (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (Vector3) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); localVariable.x = float.Parse (GUILayout.TextField (localVariable.x.ToString ())); localVariable.y = float.Parse (GUILayout.TextField (localVariable.y.ToString ())); localVariable.z = float.Parse (GUILayout.TextField (localVariable.z.ToString ())); if (GUILayout.Button ("Set")) { targetField.SetValue(targetObject, localVariable); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/GUIModuleVector4.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class GUIModuleVector4 : AbstractGUIModule { Vector4 localVariable = new Vector4(0f,0f,0f,0f); string label = ""; object targetObject; FieldInfo targetField; public GUIModuleVector4 (string label, object targetObject, string fieldName) { this.label = label; this.targetObject = targetObject; Type targetType = targetObject.GetType (); this.targetField = targetType.GetField(fieldName, Flags); this.localVariable = (Vector4) targetField.GetValue(targetObject); } public override void RenderGUI() { GUILayout.BeginHorizontal (); GUILayout.Label (label); localVariable.x = float.Parse (GUILayout.TextField (localVariable.x.ToString ())); localVariable.y = float.Parse (GUILayout.TextField (localVariable.y.ToString ())); localVariable.z = float.Parse (GUILayout.TextField (localVariable.z.ToString ())); localVariable.w = float.Parse (GUILayout.TextField (localVariable.w.ToString ())); if (GUILayout.Button ("Set")) { targetField.SetValue(targetObject, localVariable); } GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/ModularGUI/ModularGUI.cs ================================================ //A modular gui class to simplify writing a GUI //Define the gui once and have render everything //Submodules can be used to access and modify private fields of the main types, and hold their own local variables so I don't have to juggle them using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using UnityEngine; namespace Scatterer { public class ModularGUI { List Modules = new List(); public ModularGUI () { } public void RenderGUI() { foreach (AbstractGUIModule module in Modules) { module.RenderGUI(); } } public void AddModule(AbstractGUIModule module) { this.Modules.Add (module); } public void ClearModules() { Modules.Clear (); } } } ================================================ FILE: scatterer/GUI/OceanGUI.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class OceanGUI { ModularGUI oceanModularGUI = new ModularGUI(); private Vector2 _scroll; public OceanGUI () { } public void buildOceanGUI(int selectedPlanet) { OceanFFTgpu oceanNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode (); oceanModularGUI.ClearModules (); oceanModularGUI.AddModule(new GUIModuleLabel("To apply press \"rebuild ocean\" and wait")); oceanModularGUI.AddModule(new GUIModuleLabel("Keep in mind this saves your current settings")); oceanModularGUI.AddModule(new GUIModuleLabel("")); oceanModularGUI.AddModule(new GUIModuleLabel("Waves physical model settings")); oceanModularGUI.AddModule(new GUIModuleFloat("Wave amplitude (AMP)", oceanNode, "AMP")); oceanModularGUI.AddModule(new GUIModuleFloat("Wind Speed (m/s)", oceanNode, "m_windSpeed")); oceanModularGUI.AddModule(new GUIModuleFloat("Omega (inverse wave age)", oceanNode, "m_omega")); oceanModularGUI.AddModule(new GUIModuleFloat("Gravity (m/s², set to 0 for auto)", oceanNode, "m_gravity")); oceanModularGUI.AddModule(new GUIModuleFloat("Off screen vertex coverage (Increase with big waves)", oceanNode, "offScreenVertexStretch")); oceanModularGUI.AddModule(new GUIModuleLabel("")); oceanModularGUI.AddModule (new GUIModuleLabel ("Surface shading settings")); oceanModularGUI.AddModule(new GUIModuleVector3("Ocean Upwelling Color", oceanNode, "m_oceanUpwellingColor")); oceanModularGUI.AddModule(new GUIModuleFloat("Transparency Depth", oceanNode, "transparencyDepth")); oceanModularGUI.AddModule(new GUIModuleFloat("Foam strength (m_whiteCapStr)", oceanNode, "m_whiteCapStr")); oceanModularGUI.AddModule(new GUIModuleFloat("Shore/shallow foam strength", oceanNode, "shoreFoam")); oceanModularGUI.AddModule(new GUIModuleFloat("Far foam strength (m_farWhiteCapStr)", oceanNode, "m_farWhiteCapStr")); oceanModularGUI.AddModule(new GUIModuleFloat("Far foam strength radius (alphaRadius)", oceanNode, "alphaRadius")); oceanModularGUI.AddModule(new GUIModuleFloat("Sky reflection strength", oceanNode, "skyReflectionStrength")); oceanModularGUI.AddModule(new GUIModuleLabel("")); oceanModularGUI.AddModule (new GUIModuleLabel ("Underwater shading Settings")); oceanModularGUI.AddModule(new GUIModuleFloat("Refraction Index", oceanNode, "refractionIndex")); oceanModularGUI.AddModule(new GUIModuleFloat("Darkness Depth", oceanNode, "darknessDepth")); oceanModularGUI.AddModule(new GUIModuleVector3("Ocean Underwater Color", oceanNode, "m_UnderwaterColor")); if (Scatterer.Instance.mainSettings.oceanCaustics || Scatterer.Instance.mainSettings.oceanLightRays) { oceanModularGUI.AddModule(new GUIModuleLabel("")); oceanModularGUI.AddModule(new GUIModuleLabel("Caustics/lightrays Settings")); oceanModularGUI.AddModule (new GUIModuleString ("Caustics texture path", oceanNode, "causticsTexturePath")); oceanModularGUI.AddModule (new GUIModuleVector2 ("Caustics layer 1 scale", oceanNode, "causticsLayer1Scale")); oceanModularGUI.AddModule (new GUIModuleVector2 ("caustics layer 1 speed", oceanNode, "causticsLayer1Speed")); oceanModularGUI.AddModule (new GUIModuleVector2 ("Caustics Layer 2 scale", oceanNode, "causticsLayer2Scale")); oceanModularGUI.AddModule (new GUIModuleVector2 ("caustics Layer 2 speed", oceanNode, "causticsLayer2Speed")); oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics texture multiply", oceanNode, "causticsMultiply")); oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics underwater light boost", oceanNode, "causticsUnderwaterLightBoost")); oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics minimum brightness (of dark areas in the caustics texture)", oceanNode, "causticsMinBrightness")); oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics blur depth", oceanNode, "causticsBlurDepth")); oceanModularGUI.AddModule (new GUIModuleFloat ("Light rays strength", oceanNode, "lightRaysStrength")); } oceanModularGUI.AddModule(new GUIModuleLabel("")); oceanModularGUI.AddModule (new GUIModuleLabel ("Performance settings")); oceanModularGUI.AddModule (new GUIModuleLabel ("Current fourierGridSize (change from KSC menu): " + Scatterer.Instance.mainSettings.m_fourierGridSize.ToString ())); oceanModularGUI.AddModule (new GUIModuleLabel ("Current mesh resolution (change from KSC menu): " + Scatterer.Instance.mainSettings.oceanMeshResolution.ToString ())); } public void drawOceanGUI (int selectedPlanet) { OceanFFTgpu oceanNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode (); //GUItoggle("Toggle ocean", ref stockOcean); _scroll = GUILayout.BeginScrollView (_scroll, false, true, GUILayout.Width (400), GUILayout.Height (Scatterer.Instance.pluginData.scrollSectionHeight + 100)); { oceanModularGUI.RenderGUI(); } GUILayout.EndScrollView (); GUILayout.BeginHorizontal (); if (GUILayout.Button ("Apply settings/Rebuild ocean")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().saveToConfigNode (); Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.reBuildOcean (); buildOceanGUI(selectedPlanet); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); if (!Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch) { if (GUILayout.Button ("Save ocean")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().saveToConfigNode (); } } if (GUILayout.Button ("Load ocean")) { Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().loadFromConfigNode (); buildOceanGUI (selectedPlanet); } GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label (".cfg file used:"); GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().configUrl.parent.url); GUILayout.EndHorizontal (); } } } ================================================ FILE: scatterer/GUI/SunflareGUI.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.Runtime; using KSP; using KSP.IO; using UnityEngine; namespace Scatterer { public class SunflareGUI { String[] sunflareStrings; int selSunflareGridInt = 0; private Vector2 sunflareListScrollPosition = new Vector2(); bool editingSunflare = false; string sunflareText = ""; private Vector2 sunflareEditScrollPosition = new Vector2(); public SunflareGUI () { } public void InitSunflareGUI() { sunflareStrings = new string[Scatterer.Instance.sunflareManager.scattererSunFlares.Count]; for (int i=0; i latest C:\Program Files\Unity2019.2\Editor\Data\Tools\RoslynScripts unity_csc.bat Debug AnyCPU 10.0.20506 2.0 {1BA7E86D-23C1-619A-C471-A2388FCC27DA} Library Properties Assembly-CSharp-Editor v4.7.1 512 . true full false Temp\bin\Debug\ DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_4_6;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER prompt 4 0169 False pdbonly true Temp\bin\Release\ prompt 4 0169 False true true false false false C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEngine/UnityEngine.dll C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEditor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.TestRunner.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.TestRunner.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll C:/Program Files/Unity2019.2/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEditor.Graphs.dll C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/WindowsStandaloneSupport/UnityEditor.WindowsStandalone.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/WebGLSupport/UnityEditor.WebGL.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/MacStandaloneSupport/UnityEditor.OSXStandalone.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/LinuxStandaloneSupport/UnityEditor.LinuxStandalone.Extensions.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll {87622294-0BFC-2C93-A2E6-774E6D27C210} Assembly-CSharp ================================================ FILE: scatterer/OldShaders/scattererShaders/Assembly-CSharp-Editor.csproj.orig ================================================  latest C:\Program Files\Unity2019.4\Editor\Data\Tools\RoslynScripts unity_csc.bat Debug AnyCPU 10.0.20506 2.0 {1BA7E86D-23C1-619A-C471-A2388FCC27DA} Library Properties Assembly-CSharp-Editor v4.7.1 512 . true full false Temp\bin\Debug\ <<<<<<< HEAD DEBUG;TRACE;UNITY_2019_4_18;UNITY_2019_4;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_4_6;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER ======= DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_4_6;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER >>>>>>> parent of d91e357... Revert "Experiments with blending + eclipse raymarching, stashed for later" prompt 4 0169 False pdbonly true Temp\bin\Release\ prompt 4 0169 False true true false false false C:\Program Files\Unity2019.4\Editor\Data\Managed/UnityEngine/UnityEngine.dll C:\Program Files\Unity2019.4\Editor\Data\Managed/UnityEditor.dll <<<<<<< HEAD C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.dll ======= C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.TestRunner.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.TestRunner.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll >>>>>>> parent of d91e357... Revert "Experiments with blending + eclipse raymarching, stashed for later" C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SubsystemsModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEditor.dll C:/Program Files/Unity2019.4/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEditor.Graphs.dll C:/Program Files/Unity2019.4/Editor/Data/PlaybackEngines/WindowsStandaloneSupport/UnityEditor.WindowsStandalone.Extensions.dll C:/Program Files/Unity2019.4/Editor/Data/PlaybackEngines/WebGLSupport/UnityEditor.WebGL.Extensions.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.6/net35/unity-custom/nunit.framework.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.TestRunner.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.TestRunner.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll {87622294-0BFC-2C93-A2E6-774E6D27C210} Assembly-CSharp ================================================ FILE: scatterer/OldShaders/scattererShaders/Assembly-CSharp.csproj ================================================  latest C:\Program Files\Unity2019.2\Editor\Data\Tools\RoslynScripts unity_csc.bat Debug AnyCPU 10.0.20506 2.0 {87622294-0BFC-2C93-A2E6-774E6D27C210} Library Properties Assembly-CSharp v4.7.1 512 . true full false Temp\bin\Debug\ DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER prompt 4 0169 False pdbonly true Temp\bin\Release\ prompt 4 0169 False true true false false false C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEngine/UnityEngine.dll C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEditor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll ================================================ FILE: scatterer/OldShaders/scattererShaders/Assembly-CSharp.csproj.orig ================================================  latest C:\Program Files\Unity2019.2\Editor\Data\Tools\RoslynScripts unity_csc.bat Debug AnyCPU 10.0.20506 2.0 {87622294-0BFC-2C93-A2E6-774E6D27C210} Library Properties Assembly-CSharp v4.7.1 512 . true full false Temp\bin\Debug\ DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER prompt 4 0169 False pdbonly true Temp\bin\Release\ prompt 4 0169 False true true false false false C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEngine/UnityEngine.dll C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEditor.dll <<<<<<< HEAD ======= >>>>>>> c935259... split into individual maps, is slower, therefore I think the compiler optimizes 1-2 channel accesses C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll ================================================ FILE: scatterer/OldShaders/scattererShaders/Assembly-UnityScript.unityproj ================================================ Debug AnyCPU 10.0.20506 2.0 {07FD5666-7B78-6483-21E2-6D1791113BE7} Library Properties Assembly-UnityScript v3.5 512 Assets true full false Temp\bin\Debug\ DEBUG;TRACE;UNITY_5_2_4;UNITY_5_2;UNITY_5;ENABLE_NEW_BUGREPORTER;ENABLE_2D_PHYSICS;ENABLE_4_6_FEATURES;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_FRAME_DEBUGGER;ENABLE_GENERICS;ENABLE_HOME_SCREEN;ENABLE_IMAGEEFFECTS;ENABLE_LIGHT_PROBES_LEGACY;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_PLUGIN_INSPECTOR;ENABLE_SHADOWS;ENABLE_SINGLE_INSTANCE_BUILD_SETTING;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_UNET;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_METRICS;ENABLE_REFLECTION_BUFFERS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;INCLUDE_IL2CPP;INCLUDE_DIRECTX12;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_LOCALIZATION;ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_TEXTUREID_MAP;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_LOG_MIXED_STACKTRACE;ENABLE_UNITYWEBREQUEST;ENABLE_EVENT_QUEUE;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN prompt 4 0169 pdbonly true Temp\bin\Release\ prompt 4 0169 E:/gh/Unity5/Editor/Data/Managed/UnityEngine.dll E:/gh/Unity5/Editor/Data/Managed/UnityEditor.dll E:/gh/Unity5/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll E:/gh/Unity5/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll E:/gh/Unity5/Editor/Data/Managed/Mono.Cecil.dll E:/gh/Unity5/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Xcode.dll ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/AssetBundles/AssetBundles.meta ================================================ fileFormatVersion: 2 guid: fb1eb8dd5509788428a96514cc36f0d0 timeCreated: 1520625575 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/AssetBundles.meta ================================================ fileFormatVersion: 2 guid: 5d4d7b45df12a6845beb7d6a034a41a2 folderAsset: yes timeCreated: 1520623653 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/ExportAssetBundle.cs ================================================ using UnityEditor; using UnityEngine; using System; using System.Linq; using System.IO; using System.Collections; namespace scattererShaders { public class CreateAssetBundles { [MenuItem ("Assets/Build AssetBundles for release")] static void BuildAllAssetBundles () { BuildTarget[] platforms = { BuildTarget.StandaloneWindows, BuildTarget.StandaloneOSX, BuildTarget.StandaloneLinux64 }; string[] platformExts = { "-windows", "-macosx", "-linux" }; BuildBundles(platforms, platformExts); } [MenuItem ("Assets/Build AssetBundles for local openGL")] static void BuildOpenGL () { BuildTarget[] platforms = {BuildTarget.StandaloneLinux64}; string[] platformExts = { "-linux"}; BuildBundles(platforms, platformExts); } [MenuItem ("Assets/Build AssetBundles for local dx11")] static void BuildDx11 () { BuildTarget[] platforms = {BuildTarget.StandaloneWindows}; string[] platformExts = { "-windows"}; BuildBundles(platforms, platformExts); } static void BuildBundles (BuildTarget[] platforms, string[] platformExts) { // Put the bundles in a folder called "AssetBundles" //var outDir = "Assets/AssetBundles"; var outDir = "C:/Steam/steamapps/common/Kerbal Space Program/GameData/scatterer/shaders"; var outDir2 = "C:/Steam/steamapps/common/Kerbal Space Program 1.9/GameData/scatterer/shaders"; if (!Directory.Exists (outDir)) Directory.CreateDirectory (outDir); if (!Directory.Exists (outDir2)) Directory.CreateDirectory (outDir2); var opts = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.ForceRebuildAssetBundle; for (var i = 0; i < platforms.Length; ++i) { BuildPipeline.BuildAssetBundles(outDir, opts, platforms[i]); var outFile = outDir + "/scatterershaders" + platformExts[i]; var outFile2 = outDir2 + "/scatterershaders" + platformExts[i]; FileUtil.ReplaceFile(outDir + "/scatterershaders", outFile); FileUtil.ReplaceFile(outDir + "/scatterershaders", outFile2); } //cleanup foreach (string file in Directory.GetFiles(outDir, "*.*").Where(item => (item.EndsWith(".meta") || item.EndsWith(".manifest")))) { File.Delete(file); } File.Delete (outDir + "/CompiledAssetBundles"); File.Delete(outDir+"/scatterershaders"); File.Delete(outDir+"/shaders"); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/ExportAssetBundle.cs.meta ================================================ fileFormatVersion: 2 guid: 661266b8a30572e4fb9365bba3866896 timeCreated: 1474706063 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/KSPCurveEditor.cs ================================================ using UnityEngine; using UnityEditor; using UnityEditorInternal; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MuMech { public class KSPCurveEditor : EditorWindow { [MenuItem("KSP/Curve Editor")] static void Init() { EditorWindow.GetWindow(typeof(KSPCurveEditor)); } AnimationCurve curve = new AnimationCurve(); Vector2 scrollPos = new Vector2(); string textVersion; List points = new List(); bool curveNeedsUpdate = false, textChanged = false; float lastCurve = 0; void OnGUI() { textChanged = false; GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.Height(50)); EditorGUILayout.LabelField("Click curve to edit ->", GUILayout.ExpandWidth(false)); curve = EditorGUILayout.CurveField(curve, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); GUILayout.EndHorizontal(); string newT = EditorGUILayout.TextArea(textVersion, GUILayout.ExpandWidth(true), GUILayout.Height(100)); if (newT != textVersion) { textVersion = newT; textChanged = true; } scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginVertical(); GUILayout.Label("X", GUILayout.ExpandWidth(true)); foreach (FloatString4 p in points) { string ns = EditorGUILayout.TextField(p.strings[0]); if (ns != p.strings[0]) { p.strings[0] = ns; p.UpdateFloats(); curveNeedsUpdate = true; } } GUILayout.EndVertical(); GUILayout.BeginVertical(); GUILayout.Label("Y", GUILayout.ExpandWidth(true)); foreach (FloatString4 p in points) { string ns = EditorGUILayout.TextField(p.strings[1]); if (ns != p.strings[1]) { p.strings[1] = ns; p.UpdateFloats(); curveNeedsUpdate = true; } } GUILayout.EndVertical(); GUILayout.BeginVertical(); GUILayout.Label("Auto", GUILayout.ExpandWidth(true)); foreach (FloatString4 p in points) { bool a = EditorGUILayout.Toggle(p.twoMode); if (a != p.twoMode) { p.twoMode = a; curveNeedsUpdate = true; } } GUILayout.EndVertical(); GUILayout.BeginVertical(); GUILayout.Label("In Tangent", GUILayout.ExpandWidth(true)); foreach (FloatString4 p in points) { if (!p.twoMode) { string ns = EditorGUILayout.TextField(p.strings[2]); if (ns != p.strings[2]) { p.strings[2] = ns; p.UpdateFloats(); curveNeedsUpdate = true; } } else { EditorGUILayout.TextField(""); } } GUILayout.EndVertical(); GUILayout.BeginVertical(); GUILayout.Label("Out Tangent", GUILayout.ExpandWidth(true)); foreach (FloatString4 p in points) { if (!p.twoMode) { string ns = EditorGUILayout.TextField(p.strings[3]); if (ns != p.strings[3]) { p.strings[3] = ns; p.UpdateFloats(); curveNeedsUpdate = true; } } else { EditorGUILayout.TextField(""); } } GUILayout.EndVertical(); GUILayout.EndHorizontal(); EditorGUILayout.EndScrollView(); } static float HashAnimationCurve(AnimationCurve c) { float h = 0; foreach (Keyframe k in c.keys) { h += k.time + k.value + k.inTangent + k.outTangent + k.tangentMode; } return h; } void Update() { if (textChanged) { StringToCurve(textVersion); } if (curveNeedsUpdate) { UpdateCurve(); } float newCurve = HashAnimationCurve(curve); if (lastCurve != newCurve) { points = new List(); for (int i = 0; i < curve.keys.Length; i++) { FloatString4 nv = new FloatString4(curve.keys[i].time, curve.keys[i].value, curve.keys[i].inTangent, curve.keys[i].outTangent, (curve.keys[i].tangentMode == 10)); nv.UpdateStrings(); points.Add(nv); } if (!textChanged) { textVersion = CurveToString(); } lastCurve = newCurve; } } string CurveToString() { string buff = ""; foreach (FloatString4 p in points) { if (p.twoMode) { buff += "key = " + p.floats.x + " " + p.floats.y + "\n"; } else { buff += "key = " + p.floats.x + " " + p.floats.y + " " + p.floats.z + " " + p.floats.w + "\n"; } } return buff; } void StringToCurve(string data) { points = new List(); string[] lines = data.Split('\n'); foreach (string line in lines) { string[] pcs = line.Split(new char[] { '=', ' ' }, StringSplitOptions.RemoveEmptyEntries); if ((pcs.Length >= 3) && (pcs[0] == "key")) { FloatString4 nv = new FloatString4(); if (pcs.Length >= 5) { nv.strings = new string[] { pcs[1], pcs[2], pcs[3], pcs[4] }; nv.twoMode = false; } else { nv.strings = new string[] { pcs[1], pcs[2], "0", "0" }; nv.twoMode = true; } nv.UpdateFloats(); points.Add(nv); } } if (!textChanged) { textVersion = CurveToString(); } curveNeedsUpdate = true; } void UpdateCurve() { points.Sort(); curve = new AnimationCurve(); foreach (FloatString4 v in points) { Keyframe k = new Keyframe(v.floats.x, v.floats.y, v.floats.z, v.floats.w); if (v.twoMode) { k.tangentMode = 10; } else { k.tangentMode = 1; } curve.AddKey(k); } for (int i = 0; i < curve.keys.Length; i++) { if (points[i].twoMode) { curve.SmoothTangents(i, 0); } } if (!textChanged) { textVersion = CurveToString(); } lastCurve = HashAnimationCurve(curve); curveNeedsUpdate = false; } } public class FloatString4 : IComparable { public Vector4 floats; public string[] strings; public bool twoMode; public int CompareTo(FloatString4 other) { if (other == null) return 1; return floats.x.CompareTo(other.floats.x); } public FloatString4() { floats = new Vector4(); strings = new string[] { "0", "0", "0", "0" }; twoMode = false; } public FloatString4(float x, float y, float z = 0, float w = 0, bool twoMode = true) { floats = new Vector4(x, y, z, w); this.twoMode = twoMode; UpdateStrings(); } public void UpdateFloats() { float x, y, z, w; float.TryParse(strings[0], out x); float.TryParse(strings[1], out y); float.TryParse(strings[2], out z); float.TryParse(strings[3], out w); floats = new Vector4(x, y, z, w); } public void UpdateStrings() { strings = new string[] { floats.x.ToString(), floats.y.ToString(), floats.z.ToString(), floats.w.ToString() }; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/KSPCurveEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 63cd91d36b6b0e4479ef6e61ad4f6f9a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Editor.meta ================================================ fileFormatVersion: 2 guid: 98bf0690f0c9686468d3866e3c0e5e45 folderAsset: yes timeCreated: 1520625078 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/AreaTex.tga.meta ================================================ fileFormatVersion: 2 guid: b7c13973a7ed1444fb514d09b5e7e579 TextureImporter: internalIDToNameTable: [] externalObjects: {} serializedVersion: 10 mipmaps: mipMapMode: 0 enableMipMap: 0 sRGBTexture: 0 linearTexture: 1 fadeOut: 0 borderMipMap: 0 mipMapsPreserveCoverage: 0 alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 2048 textureSettings: serializedVersion: 2 filterMode: 1 aniso: 0 mipBias: -100 wrapU: 1 wrapV: 1 wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 0 alphaIsTransparency: 0 spriteTessellationDetail: -1 textureType: 0 textureShape: 1 singleChannelComponent: 0 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: iPhone maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: WebGL maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: PS4 maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 spriteSheet: serializedVersion: 2 sprites: [] outline: [] physicsShape: [] bones: [] spriteID: internalID: 0 vertices: [] indices: edges: [] weights: [] secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/CustomTAA.shader ================================================ // Modified TAA shader to not blur out the scatterer ocean Shader "Scatterer/TemporalAntialiasing" { SubShader { Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Pass { Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Cull Off ZTest Off ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON sampler2D _ScreenColor; float4 _ScreenColor_TexelSize; sampler2D _HistoryTex; sampler2D _CameraDepthTexture; float4 _CameraDepthTexture_TexelSize; sampler2D _CameraMotionVectorsTexture; #if defined (CUSTOM_OCEAN_ON) uniform sampler2D ScattererDepthCopy; #endif float2 _Jitter; float4 _FinalBlendParameters; // x: static, y: dynamic, z: motion amplification float _Sharpness; // Constants #define HALF_MAX 65504.0 // (2 - 2^-10) * 2^15 #define HALF_MAX_MINUS1 65472.0 // (2 - 2^-9) * 2^15 #define EPSILON 1.0e-4 #define PI 3.14159265359 #define TWO_PI 6.28318530718 #define FOUR_PI 12.56637061436 #define INV_PI 0.31830988618 #define INV_TWO_PI 0.15915494309 #define INV_FOUR_PI 0.07957747155 #define HALF_PI 1.57079632679 #define INV_HALF_PI 0.636619772367 #define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0 #define FLT_MIN 1.175494351e-38 // Minimum representable positive floating-point number #define FLT_MAX 3.402823466e+38 // Maximum representable floating-point number struct v2f { float4 pos : SV_POSITION; float4 screenPos : TEXCOORD0; }; v2f vert (appdata_base v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.screenPos = ComputeScreenPos(o.pos); return o; } float2 GetClosestFragment(float2 uv) { float2 k = _CameraDepthTexture_TexelSize.xy; float4 neighborhood = float4( tex2D(_CameraDepthTexture, uv - k).r, tex2D(_CameraDepthTexture, uv + float2(k.x, -k.y)).r, tex2D(_CameraDepthTexture, uv + float2(-k.x, k.y)).r, tex2D(_CameraDepthTexture, uv + k).r ); #if SHADER_API_D3D11 #define COMPARE_DEPTH(a, b) step(b, a) #else #define COMPARE_DEPTH(a, b) step(a, b) #endif float3 result = float3(0.0, 0.0, SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)); result = lerp(result, float3(-1.0, -1.0, neighborhood.x), COMPARE_DEPTH(neighborhood.x, result.z)); result = lerp(result, float3( 1.0, -1.0, neighborhood.y), COMPARE_DEPTH(neighborhood.y, result.z)); result = lerp(result, float3(-1.0, 1.0, neighborhood.z), COMPARE_DEPTH(neighborhood.z, result.z)); result = lerp(result, float3( 1.0, 1.0, neighborhood.w), COMPARE_DEPTH(neighborhood.w, result.z)); return (uv + result.xy * k); } float3 Min3(float3 a, float3 b, float3 c) { return min(min(a, b), c); } float4 ClipToAABB(float4 color, float3 minimum, float3 maximum) { // Note: only clips towards aabb center (but fast!) float3 center = 0.5 * (maximum + minimum); float3 extents = 0.5 * (maximum - minimum); // This is actually `distance`, however the keyword is reserved float3 offset = color.rgb - center; float3 ts = abs(extents / (offset + 0.0001)); float t = saturate(Min3(ts.x, ts.y, ts.z)); color.rgb = center + offset * t; return color; } float4 Solve(float2 motion, float2 texcoord) { const float2 k = _ScreenColor_TexelSize.xy; float2 uv = texcoord - _Jitter; float4 color = tex2Dlod(_ScreenColor, float4(uv,0.0,0.0)); float4 topLeft = tex2D(_ScreenColor, (uv - k * 0.5)); float4 bottomRight = tex2D(_ScreenColor, (uv + k * 0.5)); float4 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color; // Sharpen output color += (color - (corners * 0.166667)) * 2.718282 * _Sharpness; color = clamp(color, 0.0, HALF_MAX_MINUS1); // Tonemap color and history samples float4 average = (corners + color) * 0.142857; float4 history = tex2D(_HistoryTex, texcoord - motion); float motionLength = length(motion); float2 luma = float2(Luminance(average), Luminance(color)); //float nudge = 4.0 * abs(luma.x - luma.y); float nudge = lerp(4.0, 0.25, saturate(motionLength * 100.0)) * abs(luma.x - luma.y); float4 minimum = min(bottomRight, topLeft) - nudge; float4 maximum = max(topLeft, bottomRight) + nudge; // Clip history samples history = ClipToAABB(history, minimum.xyz, maximum.xyz); // Blend method float weight = clamp( lerp(_FinalBlendParameters.x, _FinalBlendParameters.y, motionLength * _FinalBlendParameters.z), _FinalBlendParameters.y, _FinalBlendParameters.x ); #if defined (CUSTOM_OCEAN_ON) float oceanDepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0)); float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0)); if (oceanDepth != zdepth) { weight*= 0.35; //seems to be the best of both worlds, still antialiases but doesn't blur the ocean much } #endif color = lerp(color, history, weight); color = clamp(color, 0.0, HALF_MAX_MINUS1); return color; } float4 frag(v2f i) : SV_Target { float2 uv = i.screenPos.xy / i.screenPos.w; #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;} #endif float2 closest = GetClosestFragment(uv); float2 motion = tex2Dlod(_CameraMotionVectorsTexture, float4(closest,0.0,0.0)).xy; return Solve(motion, uv); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/CustomTAA.shader.meta ================================================ fileFormatVersion: 2 guid: ad09d3e70e7b09244b56b51e495a319c ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.cginc ================================================ // Ported to Unity & tweaked by Thomas Hourdel (thomas@hourdel.com) //#include "Colors.hlsl" /** * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) * * Permission is hereby granted, free of charge, to any person obtaining a copy * 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: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. As clarification, there * is no requirement that the copyright notice and permission be included in * binary distributions of the Software. * * 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. */ /** * _______ ___ ___ ___ ___ * / || \/ | / \ / \ * | (---- | \ / | / ^ \ / ^ \ * \ \ | |\/| | / /_\ \ / /_\ \ * ----) | | | | | / _____ \ / _____ \ * |_______/ |__| |__| /__/ \__\ /__/ \__\ * * E N H A N C E D * S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G * * http://www.iryoku.com/smaa/ * * Hi, welcome aboard! * * Here you'll find instructions to get the shader up and running as fast as * possible. * * IMPORTANTE NOTICE: when updating, remember to update both this file and the * precomputed textures! They may change from version to version. * * The shader has three passes, chained together as follows: * * |input|------------------� * v | * [ SMAA*EdgeDetection ] | * v | * |edgesTex| | * v | * [ SMAABlendingWeightCalculation ] | * v | * |blendTex| | * v | * [ SMAANeighborhoodBlending ] <------� * v * |output| * * Note that each [pass] has its own vertex and pixel shader. Remember to use * oversized triangles instead of quads to avoid overshading along the * diagonal. * * You've three edge detection methods to choose from: luma, color or depth. * They represent different quality/performance and anti-aliasing/sharpness * tradeoffs, so our recommendation is for you to choose the one that best * suits your particular scenario: * * - Depth edge detection is usually the fastest but it may miss some edges. * * - Luma edge detection is usually more expensive than depth edge detection, * but catches visible edges that depth edge detection can miss. * * - Color edge detection is usually the most expensive one but catches * chroma-only edges. * * For quickstarters: just use luma edge detection. * * The general advice is to not rush the integration process and ensure each * step is done correctly (don't try to integrate SMAA T2x with predicated edge * detection from the start!). Ok then, let's go! * * 1. The first step is to create two RGBA temporal render targets for holding * |edgesTex| and |blendTex|. * * In DX10 or DX11, you can use a RG render target for the edges texture. * In the case of NVIDIA GPUs, using RG render targets seems to actually be * slower. * * On the Xbox 360, you can use the same render target for resolving both * |edgesTex| and |blendTex|, as they aren't needed simultaneously. * * 2. Both temporal render targets |edgesTex| and |blendTex| must be cleared * each frame. Do not forget to clear the alpha channel! * * 3. The next step is loading the two supporting precalculated textures, * 'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as * C++ headers, and also as regular DDS files. They'll be needed for the * 'SMAABlendingWeightCalculation' pass. * * If you use the C++ headers, be sure to load them in the format specified * inside of them. * * You can also compress 'areaTex' and 'searchTex' using BC5 and BC4 * respectively, if you have that option in your content processor pipeline. * When compressing then, you get a non-perceptible quality decrease, and a * marginal performance increase. * * 4. All samplers must be set to linear filtering and clamp. * * After you get the technique working, remember that 64-bit inputs have * half-rate linear filtering on GCN. * * If SMAA is applied to 64-bit color buffers, switching to point filtering * when accesing them will increase the performance. Search for * 'SMAASamplePoint' to see which textures may benefit from point * filtering, and where (which is basically the color input in the edge * detection and resolve passes). * * 5. All texture reads and buffer writes must be non-sRGB, with the exception * of the input read and the output write in * 'SMAANeighborhoodBlending' (and only in this pass!). If sRGB reads in * this last pass are not possible, the technique will work anyway, but * will perform antialiasing in gamma space. * * IMPORTANT: for best results the input read for the color/luma edge * detection should *NOT* be sRGB. * * 6. Before including SMAA.h you'll have to setup the render target metrics, * the target and any optional configuration defines. Optionally you can * use a preset. * * You have the following targets available: * SMAA_HLSL_3 * SMAA_HLSL_4 * SMAA_HLSL_4_1 * SMAA_GLSL_3 * * SMAA_GLSL_4 * * * * (See SMAA_INCLUDE_VS and SMAA_INCLUDE_PS below). * * And four presets: * SMAA_PRESET_LOW (%60 of the quality) * SMAA_PRESET_MEDIUM (%80 of the quality) * SMAA_PRESET_HIGH (%95 of the quality) * SMAA_PRESET_ULTRA (%99 of the quality) * * For example: * #define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0) * #define SMAA_HLSL_4 * #define SMAA_PRESET_HIGH * #include "SMAA.h" * * Note that SMAA_RT_METRICS doesn't need to be a macro, it can be a * uniform variable. The code is designed to minimize the impact of not * using a constant value, but it is still better to hardcode it. * * Depending on how you encoded 'areaTex' and 'searchTex', you may have to * add (and customize) the following defines before including SMAA.h: * #define SMAA_AREATEX_SELECT(sample) sample.rg * #define SMAA_SEARCHTEX_SELECT(sample) sample.r * * If your engine is already using porting macros, you can define * SMAA_CUSTOM_SL, and define the porting functions by yourself. * * 7. Then, you'll have to setup the passes as indicated in the scheme above. * You can take a look into SMAA.fx, to see how we did it for our demo. * Checkout the function wrappers, you may want to copy-paste them! * * 8. It's recommended to validate the produced |edgesTex| and |blendTex|. * You can use a screenshot from your engine to compare the |edgesTex| * and |blendTex| produced inside of the engine with the results obtained * with the reference demo. * * 9. After you get the last pass to work, it's time to optimize. You'll have * to initialize a stencil buffer in the first pass (discard is already in * the code), then mask execution by using it the second pass. The last * pass should be executed in all pixels. * * * After this point you can choose to enable predicated thresholding, * temporal supersampling and motion blur integration: * * a) If you want to use predicated thresholding, take a look into * SMAA_PREDICATION; you'll need to pass an extra texture in the edge * detection pass. * * b) If you want to enable temporal supersampling (SMAA T2x): * * 1. The first step is to render using subpixel jitters. I won't go into * detail, but it's as simple as moving each vertex position in the * vertex shader, you can check how we do it in our DX10 demo. * * 2. Then, you must setup the temporal resolve. You may want to take a look * into SMAAResolve for resolving 2x modes. After you get it working, you'll * probably see ghosting everywhere. But fear not, you can enable the * CryENGINE temporal reprojection by setting the SMAA_REPROJECTION macro. * Check out SMAA_DECODE_VELOCITY if your velocity buffer is encoded. * * 3. The next step is to apply SMAA to each subpixel jittered frame, just as * done for 1x. * * 4. At this point you should already have something usable, but for best * results the proper area textures must be set depending on current jitter. * For this, the parameter 'subsampleIndices' of * 'SMAABlendingWeightCalculationPS' must be set as follows, for our T2x * mode: * * @SUBSAMPLE_INDICES * * | S# | Camera Jitter | subsampleIndices | * +----+------------------+---------------------+ * | 0 | ( 0.25, -0.25) | float4(1, 1, 1, 0) | * | 1 | (-0.25, 0.25) | float4(2, 2, 2, 0) | * * These jitter positions assume a bottom-to-top y axis. S# stands for the * sample number. * * More information about temporal supersampling here: * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf * * c) If you want to enable spatial multisampling (SMAA S2x): * * 1. The scene must be rendered using MSAA 2x. The MSAA 2x buffer must be * created with: * - DX10: see below (*) * - DX10.1: D3D10_STANDARD_MULTISAMPLE_PATTERN or * - DX11: D3D11_STANDARD_MULTISAMPLE_PATTERN * * This allows to ensure that the subsample order matches the table in * @SUBSAMPLE_INDICES. * * (*) In the case of DX10, we refer the reader to: * - SMAA::detectMSAAOrder and * - SMAA::msaaReorder * * These functions allow to match the standard multisample patterns by * detecting the subsample order for a specific GPU, and reordering * them appropriately. * * 2. A shader must be run to output each subsample into a separate buffer * (DX10 is required). You can use SMAASeparate for this purpose, or just do * it in an existing pass (for example, in the tone mapping pass, which has * the advantage of feeding tone mapped subsamples to SMAA, which will yield * better results). * * 3. The full SMAA 1x pipeline must be run for each separated buffer, storing * the results in the final buffer. The second run should alpha blend with * the existing final buffer using a blending factor of 0.5. * 'subsampleIndices' must be adjusted as in the SMAA T2x case (see point * b). * * d) If you want to enable temporal supersampling on top of SMAA S2x * (which actually is SMAA 4x): * * 1. SMAA 4x consists on temporally jittering SMAA S2x, so the first step is * to calculate SMAA S2x for current frame. In this case, 'subsampleIndices' * must be set as follows: * * | F# | S# | Camera Jitter | Net Jitter | subsampleIndices | * +----+----+--------------------+-------------------+----------------------+ * | 0 | 0 | ( 0.125, 0.125) | ( 0.375, -0.125) | float4(5, 3, 1, 3) | * | 0 | 1 | ( 0.125, 0.125) | (-0.125, 0.375) | float4(4, 6, 2, 3) | * +----+----+--------------------+-------------------+----------------------+ * | 1 | 2 | (-0.125, -0.125) | ( 0.125, -0.375) | float4(3, 5, 1, 4) | * | 1 | 3 | (-0.125, -0.125) | (-0.375, 0.125) | float4(6, 4, 2, 4) | * * These jitter positions assume a bottom-to-top y axis. F# stands for the * frame number. S# stands for the sample number. * * 2. After calculating SMAA S2x for current frame (with the new subsample * indices), previous frame must be reprojected as in SMAA T2x mode (see * point b). * * e) If motion blur is used, you may want to do the edge detection pass * together with motion blur. This has two advantages: * * 1. Pixels under heavy motion can be omitted from the edge detection process. * For these pixels we can just store "no edge", as motion blur will take * care of them. * 2. The center pixel tap is reused. * * Note that in this case depth testing should be used instead of stenciling, * as we have to write all the pixels in the motion blur pass. * * That's it! */ //----------------------------------------------------------------------------- // SMAA Presets /** * Note that if you use one of these presets, the following configuration * macros will be ignored if set in the "Configurable Defines" section. */ #if defined(SMAA_PRESET_LOW) #define SMAA_THRESHOLD 0.15 #define SMAA_MAX_SEARCH_STEPS 4 #define SMAA_DISABLE_DIAG_DETECTION #define SMAA_DISABLE_CORNER_DETECTION #elif defined(SMAA_PRESET_MEDIUM) #define SMAA_THRESHOLD 0.1 #define SMAA_MAX_SEARCH_STEPS 8 #define SMAA_DISABLE_DIAG_DETECTION #define SMAA_DISABLE_CORNER_DETECTION #elif defined(SMAA_PRESET_HIGH) #define SMAA_THRESHOLD 0.1 #define SMAA_MAX_SEARCH_STEPS 16 #define SMAA_MAX_SEARCH_STEPS_DIAG 8 #define SMAA_CORNER_ROUNDING 25 #elif defined(SMAA_PRESET_ULTRA) #define SMAA_THRESHOLD 0.05 #define SMAA_MAX_SEARCH_STEPS 32 #define SMAA_MAX_SEARCH_STEPS_DIAG 16 #define SMAA_CORNER_ROUNDING 25 #endif //----------------------------------------------------------------------------- // Configurable Defines /** * SMAA_THRESHOLD specifies the threshold or sensitivity to edges. * Lowering this value you will be able to detect more edges at the expense of * performance. * * Range: [0, 0.5] * 0.1 is a reasonable value, and allows to catch most visible edges. * 0.05 is a rather overkill value, that allows to catch 'em all. * * If temporal supersampling is used, 0.2 could be a reasonable value, as low * contrast edges are properly filtered by just 2x. */ #ifndef SMAA_THRESHOLD #define SMAA_THRESHOLD 0.1 #endif /** * SMAA_DEPTH_THRESHOLD specifies the threshold for depth edge detection. * * Range: depends on the depth range of the scene. */ #ifndef SMAA_DEPTH_THRESHOLD #define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) #endif /** * SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the * horizontal/vertical pattern searches, at each side of the pixel. * * In number of pixels, it's actually the double. So the maximum line length * perfectly handled by, for example 16, is 64 (by perfectly, we meant that * longer lines won't look as good, but still antialiased). * * Range: [0, 112] */ #ifndef SMAA_MAX_SEARCH_STEPS #define SMAA_MAX_SEARCH_STEPS 16 #endif /** * SMAA_MAX_SEARCH_STEPS_DIAG specifies the maximum steps performed in the * diagonal pattern searches, at each side of the pixel. In this case we jump * one pixel at time, instead of two. * * Range: [0, 20] * * On high-end machines it is cheap (between a 0.8x and 0.9x slower for 16 * steps), but it can have a significant impact on older machines. * * Define SMAA_DISABLE_DIAG_DETECTION to disable diagonal processing. */ #ifndef SMAA_MAX_SEARCH_STEPS_DIAG #define SMAA_MAX_SEARCH_STEPS_DIAG 8 #endif /** * SMAA_CORNER_ROUNDING specifies how much sharp corners will be rounded. * * Range: [0, 100] * * Define SMAA_DISABLE_CORNER_DETECTION to disable corner processing. */ #ifndef SMAA_CORNER_ROUNDING #define SMAA_CORNER_ROUNDING 25 #endif /** * If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times * bigger contrast than current edge, current edge will be discarded. * * This allows to eliminate spurious crossing edges, and is based on the fact * that, if there is too much contrast in a direction, that will hide * perceptually contrast in the other neighbors. */ #ifndef SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR #define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0 #endif /** * Predicated thresholding allows to better preserve texture details and to * improve performance, by decreasing the number of detected edges using an * additional buffer like the light accumulation buffer, object ids or even the * depth buffer (the depth buffer usage may be limited to indoor or short range * scenes). * * It locally decreases the luma or color threshold if an edge is found in an * additional buffer (so the global threshold can be higher). * * This method was developed by Playstation EDGE MLAA team, and used in * Killzone 3, by using the light accumulation buffer. More information here: * http://iryoku.com/aacourse/downloads/06-MLAA-on-PS3.pptx */ #ifndef SMAA_PREDICATION #define SMAA_PREDICATION 0 #endif /** * Threshold to be used in the additional predication buffer. * * Range: depends on the input, so you'll have to find the magic number that * works for you. */ #ifndef SMAA_PREDICATION_THRESHOLD #define SMAA_PREDICATION_THRESHOLD 0.01 #endif /** * How much to scale the global threshold used for luma or color edge * detection when using predication. * * Range: [1, 5] */ #ifndef SMAA_PREDICATION_SCALE #define SMAA_PREDICATION_SCALE 2.0 #endif /** * How much to locally decrease the threshold. * * Range: [0, 1] */ #ifndef SMAA_PREDICATION_STRENGTH #define SMAA_PREDICATION_STRENGTH 0.4 #endif /** * Temporal reprojection allows to remove ghosting artifacts when using * temporal supersampling. We use the CryEngine 3 method which also introduces * velocity weighting. This feature is of extreme importance for totally * removing ghosting. More information here: * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf * * Note that you'll need to setup a velocity buffer for enabling reprojection. * For static geometry, saving the previous depth buffer is a viable * alternative. */ #ifndef SMAA_REPROJECTION #define SMAA_REPROJECTION 0 #endif /** * Temporal reprojection allows to remove ghosting artifacts when using * temporal supersampling. However, the default reprojection requires a velocity buffer * in order to function properly. * * A velocity buffer might not always be available (hi Unity 5!). To handle such cases * we provide a UV-based approximation for calculating motion vectors on the fly. */ #ifndef SMAA_UV_BASED_REPROJECTION #define SMAA_UV_BASED_REPROJECTION 0 #endif /** * SMAA_REPROJECTION_WEIGHT_SCALE controls the velocity weighting. It allows to * remove ghosting trails behind the moving object, which are not removed by * just using reprojection. Using low values will exhibit ghosting, while using * high values will disable temporal supersampling under motion. * * Behind the scenes, velocity weighting removes temporal supersampling when * the velocity of the subsamples differs (meaning they are different objects). * * Range: [0, 80] */ #ifndef SMAA_REPROJECTION_WEIGHT_SCALE #define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 #endif /** * On some compilers, discard cannot be used in vertex shaders. Thus, they need * to be compiled separately. */ #ifndef SMAA_INCLUDE_VS #define SMAA_INCLUDE_VS 1 #endif #ifndef SMAA_INCLUDE_PS #define SMAA_INCLUDE_PS 1 #endif //----------------------------------------------------------------------------- // Texture Access Defines #ifndef SMAA_AREATEX_SELECT #if defined(SMAA_HLSL_3) #define SMAA_AREATEX_SELECT(sample) sample.ra #else #define SMAA_AREATEX_SELECT(sample) sample.rg #endif #endif #ifndef SMAA_SEARCHTEX_SELECT #define SMAA_SEARCHTEX_SELECT(sample) sample.r #endif #ifndef SMAA_DECODE_VELOCITY #define SMAA_DECODE_VELOCITY(sample) sample.rg #endif //----------------------------------------------------------------------------- // Non-Configurable Defines #define SMAA_AREATEX_MAX_DISTANCE 16 #define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 #define SMAA_AREATEX_PIXEL_SIZE (1.0 / float2(160.0, 560.0)) #define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) #define SMAA_SEARCHTEX_SIZE float2(66.0, 33.0) #define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0, 16.0) #define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0) //----------------------------------------------------------------------------- // Porting Functions #if defined(SMAA_HLSL_3) #define SMAATexture2D(tex) sampler2D tex #define SMAATexturePass2D(tex) tex #define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) #define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) #define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0)) #define SMAASample(tex, coord) tex2D(tex, coord) #define SMAASamplePoint(tex, coord) tex2D(tex, coord) #define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy) //#define SMAA_FLATTEN [flatten] //#define SMAA_BRANCH [branch] #define SMAA_FLATTEN #define SMAA_BRANCH #endif #if defined(SMAA_HLSL_4) || defined(SMAA_HLSL_4_1) //SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; //SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; #define SMAATexture2D(tex) Texture2D tex #define SMAATexturePass2D(tex) tex #define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) #define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) #define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) #define SMAASample(tex, coord) tex.Sample(LinearSampler, coord) #define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord) #define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset) #define SMAA_FLATTEN [flatten] #define SMAA_BRANCH [branch] #define SMAATexture2DMS2(tex) Texture2DMS tex #define SMAALoad(tex, pos, sample) tex.Load(pos, sample) #if defined(SMAA_HLSL_4_1) #define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0) #endif #endif #if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) #define SMAATexture2D(tex) sampler2D tex #define SMAATexturePass2D(tex) tex #define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0) #define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0) #define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset) #define SMAASample(tex, coord) texture(tex, coord) #define SMAASamplePoint(tex, coord) texture(tex, coord) #define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset) #define SMAA_FLATTEN #define SMAA_BRANCH #define lerp(a, b, t) mix(a, b, t) #define saturate(a) clamp(a, 0.0, 1.0) #if defined(SMAA_GLSL_4) #define mad(a, b, c) fma(a, b, c) #define SMAAGather(tex, coord) textureGather(tex, coord) #else #define mad(a, b, c) (a * b + c) #endif #define float2 vec2 #define float3 vec3 #define float4 vec4 #define int2 ivec2 #define int3 ivec3 #define int4 ivec4 #define bool2 bvec2 #define bool3 bvec3 #define bool4 bvec4 #endif #if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL) #error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL #endif //----------------------------------------------------------------------------- // Misc functions /** * Gathers current pixel, and the top-left neighbors. */ float3 SMAAGatherNeighbours(float2 texcoord, float4 offset[3], SMAATexture2D(tex)) { #ifdef SMAAGather return SMAAGather(tex, texcoord + SMAA_RT_METRICS.xy * float2(-0.5, -0.5)).grb; #else float P = SMAASamplePoint(tex, texcoord).r; float Pleft = SMAASamplePoint(tex, offset[0].xy).r; float Ptop = SMAASamplePoint(tex, offset[0].zw).r; return float3(P, Pleft, Ptop); #endif } /** * Adjusts the threshold by means of predication. */ float2 SMAACalculatePredicatedThreshold(float2 texcoord, float4 offset[3], SMAATexture2D(predicationTex)) { float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(predicationTex)); float2 delta = abs(neighbours.xx - neighbours.yz); float2 edges = step(SMAA_PREDICATION_THRESHOLD, delta); return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges); } /** * Conditional move: */ void SMAAMovc(bool2 cond, inout float2 variable, float2 value) { SMAA_FLATTEN if (cond.x) variable.x = value.x; SMAA_FLATTEN if (cond.y) variable.y = value.y; } void SMAAMovc(bool4 cond, inout float4 variable, float4 value) { SMAAMovc(cond.xy, variable.xy, value.xy); SMAAMovc(cond.zw, variable.zw, value.zw); } #if SMAA_INCLUDE_VS //----------------------------------------------------------------------------- // Vertex Shaders /** * Edge Detection Vertex Shader */ void SMAAEdgeDetectionVS(float2 texcoord, out float4 offset[3]) { offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), texcoord.xyxy); offset[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); offset[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, -2.0), texcoord.xyxy); } /** * Blend Weight Calculation Vertex Shader */ void SMAABlendingWeightCalculationVS(float2 texcoord, out float2 pixcoord, out float4 offset[3]) { pixcoord = texcoord * SMAA_RT_METRICS.zw; // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.25, -0.125, 1.25, -0.125), texcoord.xyxy); offset[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, -0.25, -0.125, 1.25), texcoord.xyxy); // And these for the searches, they indicate the ends of the loops: offset[2] = mad(SMAA_RT_METRICS.xxyy, float4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS), float4(offset[0].xz, offset[1].yw)); } /** * Neighborhood Blending Vertex Shader */ void SMAANeighborhoodBlendingVS(float2 texcoord, out float4 offset) { offset = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); } #endif // SMAA_INCLUDE_VS #if SMAA_INCLUDE_PS //----------------------------------------------------------------------------- // Edge Detection Pixel Shaders (First Pass) /** * Luma Edge Detection * * IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and * thus 'colorTex' should be a non-sRGB texture. */ float2 SMAALumaEdgeDetectionPS(float2 texcoord, float4 offset[3], SMAATexture2D(colorTex) #if SMAA_PREDICATION , SMAATexture2D(predicationTex) #endif ) { // Calculate the threshold: #if SMAA_PREDICATION float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex)); #else float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); #endif // Calculate lumas: float3 weights = float3(0.2126, 0.7152, 0.0722); float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights); float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights); float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights); // We do the usual threshold: float4 delta; delta.xy = abs(L - float2(Lleft, Ltop)); float2 edges = step(threshold, delta.xy); // Then discard if there is no edge: if (dot(edges, float2(1.0, 1.0)) == 0.0) discard; // Calculate right and bottom deltas: float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights); float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights); delta.zw = abs(L - float2(Lright, Lbottom)); // Calculate the maximum delta in the direct neighborhood: float2 maxDelta = max(delta.xy, delta.zw); // Calculate left-left and top-top deltas: float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights); float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights); delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop)); // Calculate the final maximum delta: maxDelta = max(maxDelta.xy, delta.zw); float finalDelta = max(maxDelta.x, maxDelta.y); // Local contrast adaptation: #if !defined(SHADER_API_OPENGL) edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); #endif return edges; } /** * Color Edge Detection * * IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and * thus 'colorTex' should be a non-sRGB texture. */ float2 SMAAColorEdgeDetectionPS(float2 texcoord, float4 offset[3], SMAATexture2D(colorTex) #if SMAA_PREDICATION , SMAATexture2D(predicationTex) #endif ) { // Calculate the threshold: #if SMAA_PREDICATION float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex); #else float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); #endif // Calculate color deltas: float4 delta; float3 C = SMAASamplePoint(colorTex, texcoord).rgb; float3 Cleft = SMAASamplePoint(colorTex, offset[0].xy).rgb; float3 t = abs(C - Cleft); delta.x = max(max(t.r, t.g), t.b); float3 Ctop = SMAASamplePoint(colorTex, offset[0].zw).rgb; t = abs(C - Ctop); delta.y = max(max(t.r, t.g), t.b); // We do the usual threshold: float2 edges = step(threshold, delta.xy); // Then discard if there is no edge: if (dot(edges, float2(1.0, 1.0)) == 0.0) discard; // Calculate right and bottom deltas: float3 Cright = SMAASamplePoint(colorTex, offset[1].xy).rgb; t = abs(C - Cright); delta.z = max(max(t.r, t.g), t.b); float3 Cbottom = SMAASamplePoint(colorTex, offset[1].zw).rgb; t = abs(C - Cbottom); delta.w = max(max(t.r, t.g), t.b); // Calculate the maximum delta in the direct neighborhood: float2 maxDelta = max(delta.xy, delta.zw); // Calculate left-left and top-top deltas: float3 Cleftleft = SMAASamplePoint(colorTex, offset[2].xy).rgb; t = abs(Cleft - Cleftleft); delta.z = max(max(t.r, t.g), t.b); float3 Ctoptop = SMAASamplePoint(colorTex, offset[2].zw).rgb; t = abs(Ctop - Ctoptop); delta.w = max(max(t.r, t.g), t.b); // Calculate the final maximum delta: maxDelta = max(maxDelta.xy, delta.zw); float finalDelta = max(maxDelta.x, maxDelta.y); // Local contrast adaptation: #if !defined(SHADER_API_OPENGL) edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); #endif return edges; } /** * Depth Edge Detection */ float2 SMAADepthEdgeDetectionPS(float2 texcoord, float4 offset[3], SMAATexture2D(depthTex)) { float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(depthTex)); float2 delta = abs(neighbours.xx - float2(neighbours.y, neighbours.z)); float2 edges = step(SMAA_DEPTH_THRESHOLD, delta); if (dot(edges, float2(1.0, 1.0)) == 0.0) discard; return edges; } //----------------------------------------------------------------------------- // Diagonal Search Functions #if !defined(SMAA_DISABLE_DIAG_DETECTION) /** * Allows to decode two binary values from a bilinear-filtered access. */ float2 SMAADecodeDiagBilinearAccess(float2 e) { // Bilinear access for fetching 'e' have a 0.25 offset, and we are // interested in the R and G edges: // // +---G---+-------+ // | x o R x | // +-------+-------+ // // Then, if one of these edge is enabled: // Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0 // Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0 // // This function will unpack the values (mad + mul + round): // wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1 e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75); return round(e); } float4 SMAADecodeDiagBilinearAccess(float4 e) { e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75); return round(e); } /** * These functions allows to perform diagonal pattern searches. */ float2 SMAASearchDiag1(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { float4 coord = float4(texcoord, -1.0, 1.0); float3 t = float3(SMAA_RT_METRICS.xy, 1.0); while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && coord.w > 0.9) { coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); e = SMAASampleLevelZero(edgesTex, coord.xy).rg; coord.w = dot(e, float2(0.5, 0.5)); } return coord.zw; } float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { float4 coord = float4(texcoord, -1.0, 1.0); coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization float3 t = float3(SMAA_RT_METRICS.xy, 1.0); while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && coord.w > 0.9) { coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); // @SearchDiag2Optimization // Fetch both edges at once using bilinear filtering: e = SMAASampleLevelZero(edgesTex, coord.xy).rg; e = SMAADecodeDiagBilinearAccess(e); // Non-optimized version: // e.g = SMAASampleLevelZero(edgesTex, coord.xy).g; // e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r; coord.w = dot(e, float2(0.5, 0.5)); } return coord.zw; } /** * Similar to SMAAArea, this calculates the area corresponding to a certain * diagonal distance and crossing edges 'e'. */ float2 SMAAAreaDiag(SMAATexture2D(areaTex), float2 dist, float2 e, float offset) { float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist); // We do a scale and bias for mapping to texel space: texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); // Diagonal areas are on the second half of the texture: texcoord.x += 0.5; // Move to proper place, according to the subpixel offset: texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; // Do it! return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); } /** * This searches for diagonal patterns and returns the corresponding weights. */ float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex), float2 texcoord, float2 e, float4 subsampleIndices) { float2 weights = float2(0.0, 0.0); // Search for the line ends: float4 d; float2 end; if (e.r > 0.0) { d.xz = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, 1.0), end); d.x += float(end.y > 0.9); } else d.xz = float2(0.0, 0.0); d.yw = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, -1.0), end); SMAA_BRANCH if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 // Fetch the crossing edges: float4 coords = mad(float4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), SMAA_RT_METRICS.xyxy, texcoord.xyxy); float4 c; c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).rg; c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).rg; c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw); // Non-optimized version: // float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); // float4 c; // c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; // c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0)).r; // c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).g; // c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1)).r; // Merge crossing edges at each side into a single value: float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); // Remove the crossing edge if we didn't found the end of the line: SMAAMovc(bool2(step(float2(0.9, 0.9), d.zw)), cc, float2(0.0, 0.0)); // Fetch the areas for this line: weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.z); } // Search for the line ends: d.xz = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, -1.0), end); if (SMAASampleLevelZeroOffset(edgesTex, texcoord, int2(1, 0)).r > 0.0) { d.yw = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, 1.0), end); d.y += float(end.y > 0.9); } else d.yw = float2(0.0, 0.0); SMAA_BRANCH if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 // Fetch the crossing edges: float4 coords = mad(float4(-d.x, -d.x, d.y, d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); float4 c; c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, -1)).r; c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).gr; float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); // Remove the crossing edge if we didn't found the end of the line: SMAAMovc(bool2(step(float2(0.9, 0.9), d.zw)), cc, float2(0.0, 0.0)); // Fetch the areas for this line: weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.w).gr; } return weights; } #endif //----------------------------------------------------------------------------- // Horizontal/Vertical Search Functions /** * This allows to determine how much length should we add in the last step * of the searches. It takes the bilinearly interpolated edge (see * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and * crossing edges are active. */ float SMAASearchLength(SMAATexture2D(searchTex), float2 e, float offset) { // The texture is flipped vertically, with left and right cases taking half // of the space horizontally: float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5, -1.0); float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0); // Scale and bias to access texel centers: scale += float2(-1.0, 1.0); bias += float2( 0.5, -0.5); // Convert from pixel coordinates to texcoords: // (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped) scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; // Lookup the search texture: return SMAA_SEARCHTEX_SELECT(SMAASampleLevelZero(searchTex, mad(scale, e, bias))); } /** * Horizontal/vertical search functions for the 2nd pass. */ float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { /** * @PSEUDO_GATHER4 * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to * sample between edge, thus fetching four edges in a row. * Sampling with different offsets in each direction allows to disambiguate * which edges are active from the four fetched ones. */ float2 e = float2(0.0, 1.0); while (texcoord.x > end && e.g > 0.8281 && // Is there some edge not activated? e.r == 0.0) { // Or is there a crossing edge that breaks the line? e = SMAASampleLevelZero(edgesTex, texcoord).rg; texcoord = mad(-float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); } float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0), 3.25); return mad(SMAA_RT_METRICS.x, offset, texcoord.x); // Non-optimized version: // We correct the previous (-0.25, -0.125) offset we applied: // texcoord.x += 0.25 * SMAA_RT_METRICS.x; // The searches are bias by 1, so adjust the coords accordingly: // texcoord.x += SMAA_RT_METRICS.x; // Disambiguate the length added by the last step: // texcoord.x += 2.0 * SMAA_RT_METRICS.x; // Undo last step // texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0); // return mad(SMAA_RT_METRICS.x, offset, texcoord.x); } float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { float2 e = float2(0.0, 1.0); while (texcoord.x < end && e.g > 0.8281 && // Is there some edge not activated? e.r == 0.0) { // Or is there a crossing edge that breaks the line? e = SMAASampleLevelZero(edgesTex, texcoord).rg; texcoord = mad(float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); } float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.5), 3.25); return mad(-SMAA_RT_METRICS.x, offset, texcoord.x); } float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { float2 e = float2(1.0, 0.0); while (texcoord.y > end && e.r > 0.8281 && // Is there some edge not activated? e.g == 0.0) { // Or is there a crossing edge that breaks the line? e = SMAASampleLevelZero(edgesTex, texcoord).rg; texcoord = mad(-float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); } float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.0), 3.25); return mad(SMAA_RT_METRICS.y, offset, texcoord.y); } float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { float2 e = float2(1.0, 0.0); while (texcoord.y < end && e.r > 0.8281 && // Is there some edge not activated? e.g == 0.0) { // Or is there a crossing edge that breaks the line? e = SMAASampleLevelZero(edgesTex, texcoord).rg; texcoord = mad(float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); } float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.5), 3.25); return mad(-SMAA_RT_METRICS.y, offset, texcoord.y); } /** * Ok, we have the distance and both crossing edges. So, what are the areas * at each side of current edge? */ float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) { // Rounding prevents precision errors of bilinear filtering: float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * float2(e1, e2)), dist); // We do a scale and bias for mapping to texel space: texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); // Move to proper place, according to the subpixel offset: texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); // Do it! return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); } //----------------------------------------------------------------------------- // Corner Detection Functions void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { #if !defined(SMAA_DISABLE_CORNER_DETECTION) float2 leftRight = step(d.xy, d.yx); float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line. float2 factor = float2(1.0, 1.0); factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, 1)).r; factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, 1)).r; factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, -2)).r; factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, -2)).r; weights *= saturate(factor); #endif } void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { #if !defined(SMAA_DISABLE_CORNER_DETECTION) float2 leftRight = step(d.xy, d.yx); float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; rounding /= leftRight.x + leftRight.y; float2 factor = float2(1.0, 1.0); factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2( 1, 0)).g; factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2( 1, 1)).g; factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(-2, 0)).g; factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(-2, 1)).g; weights *= saturate(factor); #endif } //----------------------------------------------------------------------------- // Blending Weight Calculation Pixel Shader (Second Pass) float4 SMAABlendingWeightCalculationPS(float2 texcoord, float2 pixcoord, float4 offset[3], SMAATexture2D(edgesTex), SMAATexture2D(areaTex), SMAATexture2D(searchTex), float4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. float4 weights = float4(0.0, 0.0, 0.0, 0.0); float2 e = SMAASample(edgesTex, texcoord).rg; SMAA_BRANCH if (e.g > 0.0) { // Edge at north #if !defined(SMAA_DISABLE_DIAG_DETECTION) // Diagonals have both north and west edges, so searching for them in // one of the boundaries is enough. weights.rg = SMAACalculateDiagWeights(SMAATexturePass2D(edgesTex), SMAATexturePass2D(areaTex), texcoord, e, subsampleIndices); // We give priority to diagonals, so if we find a diagonal we skip // horizontal/vertical processing. SMAA_BRANCH if (weights.r == -weights.g) { // weights.r + weights.g == 0.0 #endif float2 d; // Find the distance to the left: float3 coords; coords.x = SMAASearchXLeft(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].xy, offset[2].x); coords.y = offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET) d.x = coords.x; // Now fetch the left crossing edges, two at a time using bilinear // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to // discern what value each edge has: float e1 = SMAASampleLevelZero(edgesTex, coords.xy).r; // Find the distance to the right: coords.z = SMAASearchXRight(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].zw, offset[2].y); d.y = coords.z; // We want the distances to be in pixel units (doing this here allow to // better interleave arithmetic and memory accesses): d = abs(round(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx))); // SMAAArea below needs a sqrt, as the areas texture is compressed // quadratically: float2 sqrt_d = sqrt(d); // Fetch the right crossing edges: float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, int2(1, 0)).r; // Ok, we know how this pattern looks like, now it is time for getting // the actual area: weights.rg = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.y); // Fix corners: coords.y = texcoord.y; SMAADetectHorizontalCornerPattern(SMAATexturePass2D(edgesTex), weights.rg, coords.xyzy, d); #if !defined(SMAA_DISABLE_DIAG_DETECTION) } else e.r = 0.0; // Skip vertical processing. #endif } SMAA_BRANCH if (e.r > 0.0) { // Edge at west float2 d; // Find the distance to the top: float3 coords; coords.y = SMAASearchYUp(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].xy, offset[2].z); coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_RT_METRICS.x; d.x = coords.y; // Fetch the top crossing edges: float e1 = SMAASampleLevelZero(edgesTex, coords.xy).g; // Find the distance to the bottom: coords.z = SMAASearchYDown(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].zw, offset[2].w); d.y = coords.z; // We want the distances to be in pixel units: d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy))); // SMAAArea below needs a sqrt, as the areas texture is compressed // quadratically: float2 sqrt_d = sqrt(d); // Fetch the bottom crossing edges: float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, int2(0, 1)).g; // Get the area for this direction: weights.ba = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x); // Fix corners: coords.x = texcoord.x; SMAADetectVerticalCornerPattern(SMAATexturePass2D(edgesTex), weights.ba, coords.xyxz, d); } return weights; } //----------------------------------------------------------------------------- // UV-based reprojection functions #if SMAA_UV_BASED_REPROJECTION float2 SMAAReproject(float2 texcoord) { // UV to clip-position: // -- This must be sampled at exactly mip 0 due to possible gradient divergence // -- as this function is called within a control flow block down below. float depth = SMAASampleLevelZero(_CameraDepthTexture, texcoord).r; float3 clipPosition = float3(2. * texcoord - 1., depth); // Reproject float4 previousClipPosition = mul(_ReprojectionMatrix, float4(clipPosition, 1.)); previousClipPosition.xyz /= previousClipPosition.w; // Clip-position to UV return (.5 * previousClipPosition.xy + .5); } #endif //----------------------------------------------------------------------------- // Neighborhood Blending Pixel Shader (Third Pass) float4 SMAANeighborhoodBlendingPS(float2 texcoord, float4 offset, SMAATexture2D(colorTex), SMAATexture2D(blendTex) #if SMAA_REPROJECTION , SMAATexture2D(velocityTex) #endif ) { // Fetch the blending weights for current pixel: float4 a; a.x = SMAASample(blendTex, offset.xy).a; // Right a.y = SMAASample(blendTex, offset.zw).g; // Top a.wz = SMAASample(blendTex, texcoord).xz; // Bottom / Left // Is there any blending weight with a value greater than 0.0? SMAA_BRANCH if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { float4 color = SMAASampleLevelZero(colorTex, texcoord); #if SMAA_REPROJECTION float2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord)); #elif SMAA_UV_BASED_REPROJECTION float2 velocity = texcoord - SMAAReproject(texcoord); #endif #if (SMAA_REPROJECTION || SMAA_UV_BASED_REPROJECTION) // Pack velocity into the alpha channel: color.a = sqrt(5.0 * length(velocity)); #endif return color; } else { bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) // Calculate the blending offsets: float4 blendingOffset = float4(0.0, a.y, 0.0, a.w); float2 blendingWeight = a.yw; SMAAMovc(bool4(h, h, h, h), blendingOffset, float4(a.x, 0.0, a.z, 0.0)); SMAAMovc(bool2(h, h), blendingWeight, a.xz); blendingWeight /= dot(blendingWeight, float2(1.0, 1.0)); // Calculate the texture coordinates: float4 blendingCoord = mad(blendingOffset, float4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy); // We exploit bilinear filtering to mix current pixel with the chosen // neighbor: float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy); color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw); #if SMAA_REPROJECTION // Antialias velocity for proper reprojection in a later stage: float2 velocity = blendingWeight.x * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.xy)); velocity += blendingWeight.y * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.zw)); #elif SMAA_UV_BASED_REPROJECTION // Antialias velocity for proper reprojection in a later stage: float2 velocity = blendingWeight.x * (blendingCoord.xy - SMAAReproject(blendingCoord.xy)); velocity += blendingWeight.y * (blendingCoord.zw - SMAAReproject(blendingCoord.zw)); #endif #if (SMAA_REPROJECTION || SMAA_UV_BASED_REPROJECTION) // Pack velocity into the alpha channel: color.a = sqrt(5.0 * length(velocity)); #endif return color; } } //----------------------------------------------------------------------------- // Temporal Resolve Pixel Shader (Optional Pass) float4 SMAAResolvePS(float2 texcoord, SMAATexture2D(currentColorTex), SMAATexture2D(previousColorTex) #if SMAA_REPROJECTION , SMAATexture2D(velocityTex) #endif ) { #if SMAA_REPROJECTION // Velocity is assumed to be calculated for motion blur, so we need to // inverse it for reprojection: float2 velocity = -SMAA_DECODE_VELOCITY(SMAASamplePoint(velocityTex, texcoord).rg); #elif SMAA_UV_BASED_REPROJECTION float2 velocity = SMAAReproject(texcoord) - texcoord; #endif #if (SMAA_REPROJECTION || SMAA_UV_BASED_REPROJECTION) // Fetch current pixel: float4 current = SMAASamplePoint(currentColorTex, texcoord); // Reproject current coordinates and fetch previous pixel: float4 previous = SMAASamplePoint(previousColorTex, texcoord + velocity); // Attenuate the previous pixel if the velocity is different: float delta = abs(current.a * current.a - previous.a * previous.a) / 5.0; float weight = 0.5 * saturate(1.0 - sqrt(delta) * SMAA_REPROJECTION_WEIGHT_SCALE); // Blend the pixels according to the calculated weight: // return lerp(current, previous, weight); // Neighbour clamp // Contributed by pommak float4 n0 = SMAASampleOffset(currentColorTex, texcoord, float2(-1, -1)); float4 n1 = SMAASampleOffset(currentColorTex, texcoord, float2(+1, -1)); float4 n2 = SMAASampleOffset(currentColorTex, texcoord, float2(-1, +1)); float4 n3 = SMAASampleOffset(currentColorTex, texcoord, float2(+1, +1)); float4 cmax = max(n0, max(n1, max(n2, n3))); float4 cmin = min(n0, min(n1, min(n2, n3))); float4 avg = 0.25 * (n0+n1+n2+n3); float4 wk = abs(avg - current); float blend = saturate(lerp(0.35, 0.85, wk)); // Clamp previous to neighbours colors float4 previousClamped = clamp(previous, cmin, cmax); float4 color = lerp(lerp(current, previousClamped, 0.5*weight), previousClamped, weight); return color; #else // Just blend the pixels: float4 current = SMAASamplePoint(currentColorTex, texcoord); float4 previous = SMAASamplePoint(previousColorTex, texcoord); return lerp(current, previous, 0.5); #endif } //----------------------------------------------------------------------------- // Separate Multisamples Pixel Shader (Optional Pass) #ifdef SMAALoad void SMAASeparatePS(float4 position, float2 texcoord, out float4 target0, out float4 target1, SMAATexture2DMS2(colorTexMS)) { int2 pos = int2(position.xy); target0 = SMAALoad(colorTexMS, pos, 0); target1 = SMAALoad(colorTexMS, pos, 1); } #endif //----------------------------------------------------------------------------- #endif // SMAA_INCLUDE_PS ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.cginc.meta ================================================ fileFormatVersion: 2 guid: 3edf75dd062cabf449c243d3c0da9464 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.shader ================================================ Shader "Scatterer/SubpixelMorphologicalAntialiasing" { SubShader { Cull Off ZWrite Off ZTest Always // 0 - Edge detection (Low) Pass { CGPROGRAM #pragma vertex VertEdge #pragma fragment FragEdge #define SMAA_PRESET_LOW #include "SMAABridge.cginc" ENDCG } // 1 - Edge detection (Medium) Pass { CGPROGRAM #pragma vertex VertEdge #pragma fragment FragEdge #define SMAA_PRESET_MEDIUM #include "SMAABridge.cginc" ENDCG } // 2 - Edge detection (High) Pass { CGPROGRAM #pragma vertex VertEdge #pragma fragment FragEdge #define SMAA_PRESET_HIGH #include "SMAABridge.cginc" ENDCG } // 3 - Blend Weights Calculation (Low) Pass { CGPROGRAM #pragma vertex VertBlend #pragma fragment FragBlend #define SMAA_PRESET_LOW #include "SMAABridge.cginc" ENDCG } // 4 - Blend Weights Calculation (Medium) Pass { CGPROGRAM #pragma vertex VertBlend #pragma fragment FragBlend #define SMAA_PRESET_MEDIUM #include "SMAABridge.cginc" ENDCG } // 5 - Blend Weights Calculation (High) Pass { CGPROGRAM #pragma vertex VertBlend #pragma fragment FragBlend #define SMAA_PRESET_HIGH #include "SMAABridge.cginc" ENDCG } // 6 - Neighborhood Blending Pass { CGPROGRAM #pragma vertex VertNeighbor #pragma fragment FragNeighbor #include "SMAABridge.cginc" ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.shader.meta ================================================ fileFormatVersion: 2 guid: 89df79cf5061c394d82abd40383976e5 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAABridge.cginc ================================================ #ifndef UNITY_POSTFX_SMAA_BRIDGE #define UNITY_POSTFX_SMAA_BRIDGE //#include "StdLib.hlsl" sampler2D _MainTexture; sampler2D _BlendTex; sampler2D _AreaTex; sampler2D _SearchTex; float4 _MainTexture_TexelSize; #define SMAA_RT_METRICS _MainTexture_TexelSize #define SMAA_AREATEX_SELECT(s) s.rg #define SMAA_SEARCHTEX_SELECT(s) s.a #define LinearSampler sampler_MainTexture #define PointSampler sampler_MainTexture #define SMAA_HLSL_3 #include "SMAA.cginc" struct AttributesDefault { float3 vertex : POSITION; }; struct VaryingsDefault { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float2 texcoordStereo : TEXCOORD1; #if STEREO_INSTANCING_ENABLED uint stereoTargetEyeIndex : SV_RenderTargetArrayIndex; #endif }; // Vertex manipulation float2 TransformTriangleVertexToUV(float2 vertex) { //float2 uv = (vertex + 1.0) * 0.5; float2 uv = vertex; return uv; } // ---------------------------------------------------------------------------------------- // Edge Detection struct VaryingsEdge { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float4 offsets[3] : TEXCOORD1; }; VaryingsEdge VertEdge(AttributesDefault v) { VaryingsEdge o; o.vertex = float4((v.vertex.xy-0.5)*2.0, 0.0, 1.0); o.texcoord = TransformTriangleVertexToUV(v.vertex.xy); #if UNITY_UV_STARTS_AT_TOP o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0); #endif o.offsets[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), o.texcoord.xyxy); o.offsets[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), o.texcoord.xyxy); o.offsets[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, -2.0), o.texcoord.xyxy); return o; } float4 FragEdge(VaryingsEdge i) : SV_Target { return float4(SMAAColorEdgeDetectionPS(i.texcoord, i.offsets, _MainTexture), 0.0, 0.0); } // ---------------------------------------------------------------------------------------- // Blend Weights Calculation struct VaryingsBlend { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float2 pixcoord : TEXCOORD1; float4 offsets[3] : TEXCOORD2; }; VaryingsBlend VertBlend(AttributesDefault v) { VaryingsBlend o; o.vertex = float4((v.vertex.xy-0.5)*2.0, 0.0, 1.0); o.texcoord = TransformTriangleVertexToUV(v.vertex.xy); #if UNITY_UV_STARTS_AT_TOP o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0); #endif o.pixcoord = o.texcoord * SMAA_RT_METRICS.zw; // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): o.offsets[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.250, -0.125, 1.250, -0.125), o.texcoord.xyxy); o.offsets[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, -0.250, -0.125, 1.250), o.texcoord.xyxy); // And these for the searches, they indicate the ends of the loops: o.offsets[2] = mad(SMAA_RT_METRICS.xxyy, float4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS), float4(o.offsets[0].xz, o.offsets[1].yw)); //potentially the offsets or pixcoord are broken, texcoord seems to be fine //textures _AreaTex and _SearchTex should be fine but not sure //perhaps mad is messed up? return o; } float4 FragBlend(VaryingsBlend i) : SV_Target { return SMAABlendingWeightCalculationPS(i.texcoord, i.pixcoord, i.offsets, _MainTexture, _AreaTex, _SearchTex, 0); } // ---------------------------------------------------------------------------------------- // Neighborhood Blending struct VaryingsNeighbor { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float4 offset : TEXCOORD1; }; VaryingsNeighbor VertNeighbor(AttributesDefault v) { VaryingsNeighbor o; o.vertex = float4((v.vertex.xy-0.5)*2.0, 0.0, 1.0); o.texcoord = TransformTriangleVertexToUV(v.vertex.xy); #if UNITY_UV_STARTS_AT_TOP o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0); #endif o.offset = mad(SMAA_RT_METRICS.xyxy, float4(1.0, 0.0, 0.0, 1.0), o.texcoord.xyxy); return o; } float4 FragNeighbor(VaryingsNeighbor i) : SV_Target { return SMAANeighborhoodBlendingPS(i.texcoord, i.offset, _MainTexture, _BlendTex); } #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAABridge.cginc.meta ================================================ fileFormatVersion: 2 guid: d12fd27d9e34a1e43b79b04f9202d548 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SearchTex.tga.meta ================================================ fileFormatVersion: 2 guid: b14b67faac4aff04fac7127cf1ab4f97 TextureImporter: internalIDToNameTable: [] externalObjects: {} serializedVersion: 10 mipmaps: mipMapMode: 0 enableMipMap: 0 sRGBTexture: 0 linearTexture: 1 fadeOut: 0 borderMipMap: 0 mipMapsPreserveCoverage: 0 alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 grayScaleToAlpha: 1 generateCubemap: 6 cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: 1 maxTextureSize: 2048 textureSettings: serializedVersion: 2 filterMode: 0 aniso: -1 mipBias: -100 wrapU: 1 wrapV: 1 wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 2 alphaIsTransparency: 0 spriteTessellationDetail: -1 textureType: 10 textureShape: 1 singleChannelComponent: 0 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 - serializedVersion: 3 buildTarget: PS4 maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 1 spriteSheet: serializedVersion: 2 sprites: [] outline: [] physicsShape: [] bones: [] spriteID: internalID: 0 vertices: [] indices: edges: [] weights: [] secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA.meta ================================================ fileFormatVersion: 2 guid: 7db44d889e0cbbf4281132a752f96ce1 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/CompositeDownscaledScattering.shader ================================================ Shader "Scatterer/CompositeDownscaledScattering" { SubShader { Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Pass { Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Cull Off ZTest Off ZWrite [_ZwriteVariable] Blend SrcAlpha OneMinusSrcAlpha //traditional alpha-blending CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON uniform sampler2D DownscaledScattering0; //Scattering RGB, extinction.R uniform sampler2D DownscaledScattering1; //Extinction.GB uniform sampler2D ScattererDownscaledScatteringDepth; float4 ScattererDownscaledScatteringDepth_TexelSize; #if defined (CUSTOM_OCEAN_ON) uniform sampler2D ScattererScreenCopy; uniform sampler2D ScattererDepthCopy; float4 ScattererDepthCopy_TexelSize; #define fullresDepthTexture ScattererDepthCopy; #define fullresDepthTexture_TexelSize ScattererDepthCopy_TexelSize; #else uniform sampler2D _CameraDepthTexture; float4 _CameraDepthTexture_TexelSize; #define fullresDepthTexture _CameraDepthTexture; #define fullresDepthTexture_TexelSize _CameraDepthTexture_TexelSize; uniform sampler2D ScattererScreenCopyBeforeOcean; #endif struct v2f { float4 screenPos : TEXCOORD0; }; v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { v2f o; #if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0); #else outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0); #endif o.screenPos = ComputeScreenPos(outpos); return o; } struct fout { float4 color : COLOR; #if defined (CUSTOM_OCEAN_ON) float depth : DEPTH; #endif }; void UpdateNearestSample( inout float MinDist, inout float2 NearestUV, float Z, float2 UV, float ZFull ) { float Dist = abs(Z - ZFull); #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if ((Dist < MinDist) && (Z > 0.0)) #else if ((Dist < MinDist) && (Z < 1.0)) #endif { MinDist = Dist; NearestUV = UV; } } fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) { float2 uv = i.screenPos.xy / i.screenPos.w; #if defined (CUSTOM_OCEAN_ON) float zdepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0)); #else float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0)); #endif //read full resolution depth float ZFull = Linear01Depth(zdepth); #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;} if (zdepth == 0.0) {discard;} #else if (zdepth == 1.0) {discard;} #endif //find low res depth texture texel size float2 lowResTexelSize = ScattererDownscaledScatteringDepth_TexelSize.xy; float2 lowResUV = uv; float MinDist = 1.0; float2 UV00 = lowResUV - 0.5 * lowResTexelSize; float2 NearestUV = UV00; float Z00 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV00) ); UpdateNearestSample(MinDist, NearestUV, Z00, UV00, ZFull); float2 UV10 = float2(UV00.x+lowResTexelSize.x, UV00.y); float Z10 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV10) ); UpdateNearestSample(MinDist, NearestUV, Z10, UV10, ZFull); float2 UV01 = float2(UV00.x, UV00.y+lowResTexelSize.y); float Z01 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV01) ); UpdateNearestSample(MinDist, NearestUV, Z01, UV01, ZFull); float2 UV11 = UV00 + lowResTexelSize; float Z11 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV11) ); UpdateNearestSample(MinDist, NearestUV, Z11, UV11, ZFull); float4 col0 = tex2Dlod(DownscaledScattering0, float4(NearestUV,0,0)); float2 col1 = tex2Dlod(DownscaledScattering1, float4(NearestUV,0,0)).rg; float3 inscatter = col0.rgb; float3 extinction = float3(col0.a,col1.rg); #if defined (CUSTOM_OCEAN_ON) float3 backGrnd = tex2Dlod(ScattererScreenCopy, float4(uv.x, uv.y,0.0,0.0)); #else float3 backGrnd = tex2Dlod(ScattererScreenCopyBeforeOcean, float4(uv.x, uv.y,0.0,0.0)); #endif //composite backGround by extinction backGrnd*=extinction; //composite background with inscatter, soft-blend it backGrnd+= (1.0 - backGrnd) * dither(inscatter, screenPos); fout output; output.color = float4(backGrnd,1.0); #if defined (CUSTOM_OCEAN_ON) output.depth = zdepth; //this needs to only be done if rendering with an ocean #endif return output; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/CompositeDownscaledScattering.shader.meta ================================================ fileFormatVersion: 2 guid: 94a7f67cf7303d94fa3f076bd9f33095 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/DepthBufferScattering.shader ================================================ Shader "Scatterer/DepthBufferScattering" { SubShader { Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Pass { //Pass 0: render to screen directly Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Cull Off ZTest Off ZWrite [_ZwriteVariable] Blend SrcAlpha OneMinusSrcAlpha //traditional alpha-blending CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" #include "Godrays/GodraysCommon.cginc" // #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON // #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON #pragma multi_compile DITHERING_OFF DITHERING_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON uniform float _global_alpha; uniform float _global_depth; uniform float3 _planetPos; //planet origin, in world space uniform float3 _camForward; //camera's viewing direction, in world space uniform float _ScatteringExposure; uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace uniform float _Post_Extinction_Tint; uniform float extinctionThickness; #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif uniform float _openglThreshold; #if defined (CUSTOM_OCEAN_ON) uniform sampler2D ScattererScreenCopy; uniform sampler2D ScattererDepthCopy; #else uniform sampler2D ScattererScreenCopyBeforeOcean; #endif float4x4 CameraToWorld; #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { float3 camPosRelPlanet : TEXCOORD0; float4 screenPos : TEXCOORD1; }; v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { v2f o; #if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0); #else outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0); #endif o.camPosRelPlanet = _WorldSpaceCameraPos - _planetPos; o.screenPos = ComputeScreenPos(outpos); return o; } //this needs to only be done if rendering with an ocean //probably hurts performance on low-spec machines so disable it struct fout { float4 color : COLOR; #if defined (CUSTOM_OCEAN_ON) float depth : DEPTH; #endif }; fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) { float2 uv = i.screenPos.xy / i.screenPos.w; #if defined (CUSTOM_OCEAN_ON) float zdepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0)); #else float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0)); #endif #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;} if (zdepth == 0.0) {discard;} #else if (zdepth == 1.0) {discard;} #endif float3 absWorldPos = getPreciseWorldPosFromDepth(i.screenPos.xy / i.screenPos.w, zdepth, CameraToWorld); float3 worldPos = absWorldPos - _planetPos; //worldPos relative to planet origin float3 groundPos = normalize (worldPos) * Rg * 1.0008; float Rt2 = Rg + (Rt - Rg) * _experimentalAtmoScale; worldPos = (length(worldPos) < Rt2) ? lerp(groundPos,worldPos,_PlanetOpacity) : worldPos; //fades to flatScaledSpace planet shading to ease the transition to scaledSpace worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix #if defined (CUSTOM_OCEAN_ON) float3 backGrnd = tex2Dlod(ScattererScreenCopy, float4(uv.x, uv.y,0.0,0.0)); #else float3 backGrnd = tex2Dlod(ScattererScreenCopyBeforeOcean, float4(uv.x, uv.y,0.0,0.0)); #endif float minDistance = length(worldPos-i.camPosRelPlanet); float3 inscatter=0.0; float3 extinction=1.0; #if defined (GODRAYS_ON) //extinction of the full distance to the terrain, not just the lit part when factoring in godrays float3 fullSegmentExtinction = getExtinction(i.camPosRelPlanet, worldPos, 1.0, 1.0, 1.0); float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, uv, 1.0); //trying to find the optical depth from the terrain level float muTerrain = dot(normalize(worldPos), normalize(_WorldSpaceCameraPos - absWorldPos)); godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance); worldPos -= godrayDepth * normalize(worldPos-i.camPosRelPlanet); #endif inscatter+= InScattering2(i.camPosRelPlanet, worldPos,SUN_DIR,extinction); inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha; #if defined (GODRAYS_ON) extinction = fullSegmentExtinction; #endif float extinctionAverage=(extinction.r+extinction.g+extinction.b)/3; //lerped manually because of an issue with opengl or whatever extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(extinctionAverage,extinctionAverage,extinctionAverage); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); //composite backGround by extinction backGrnd*=extinction; //composite background with inscatter, soft-blend it backGrnd+= (1.0 - backGrnd) * dither(inscatter,screenPos); fout output; output.color = float4(backGrnd,1.0); #if defined (CUSTOM_OCEAN_ON) output.depth = zdepth; //this needs to only be done if rendering with an ocean #endif return output; } ENDCG } Pass { //Pass 1: render to 1/4 res textures Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Cull Off ZTest Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" #include "Godrays/GodraysCommon.cginc" // #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON // #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON uniform float _global_alpha; uniform float _global_depth; uniform float3 _planetPos; //planet origin, in world space uniform float3 _camForward; //camera's viewing direction, in world space uniform float _ScatteringExposure; uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace uniform float _Post_Extinction_Tint; uniform float extinctionThickness; #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif uniform float _openglThreshold; uniform sampler2D ScattererDownscaledScatteringDepth; float4x4 CameraToWorld; #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { float3 camPosRelPlanet : TEXCOORD0; float4 screenPos : TEXCOORD1; }; v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { v2f o; #if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0); #else outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0); #endif o.camPosRelPlanet = _WorldSpaceCameraPos - _planetPos; o.screenPos = ComputeScreenPos(outpos); return o; } struct fout { float4 col0 : COLOR0; float4 col1 : COLOR1; }; fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) { fout output; float2 uv = i.screenPos.xy / i.screenPos.w; float zdepth = tex2Dlod(ScattererDownscaledScatteringDepth, float4(uv,0,0)); #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;} if (zdepth == 0.0) {discard;} #else if (zdepth == 1.0) {discard;} #endif float3 absWorldPos = getPreciseWorldPosFromDepth(i.screenPos.xy / i.screenPos.w, zdepth, CameraToWorld); float3 worldPos = absWorldPos - _planetPos; //worldPos relative to planet origin float3 groundPos = normalize (worldPos) * Rg * 1.0008; float Rt2 = Rg + (Rt - Rg) * _experimentalAtmoScale; worldPos = (length(worldPos) < Rt2) ? lerp(groundPos,worldPos,_PlanetOpacity) : worldPos; //fades to flatScaledSpace planet shading to ease the transition to scaledSpace //this wasn't applied in extinction shader, not sure if it will be an issue worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix float minDistance = length(worldPos-i.camPosRelPlanet); #if defined (GODRAYS_ON) //extinction of the full distance to the terrain, not just the lit part when factoring in godrays float3 fullSegmentExtinction = getExtinction(i.camPosRelPlanet, worldPos, 1.0, 1.0, 1.0); float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, uv, 1.0); //trying to find the optical depth from the terrain level float muTerrain = dot(normalize(worldPos), normalize(_WorldSpaceCameraPos - absWorldPos)); godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance); worldPos -= godrayDepth * normalize(worldPos-i.camPosRelPlanet); #endif float3 inscatter=0.0; float3 extinction=1.0; inscatter+= InScattering2(i.camPosRelPlanet, worldPos,SUN_DIR,extinction); inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha; output.col0.rgb = inscatter; #if defined (GODRAYS_ON) extinction = fullSegmentExtinction; #endif float extinctionAverage=(extinction.r+extinction.g+extinction.b)/3; //lerped manually because of an issue with opengl or whatever extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(extinctionAverage,extinctionAverage,extinctionAverage); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); output.col0.a = extinction.r; output.col1 = float4(extinction.g,extinction.b,1.0,1.0); return output; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/DepthBufferScattering.shader.meta ================================================ fileFormatVersion: 2 guid: 470fdf3cd8176d94e8aadd242240fe3c ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ComputeInverseShadowMatrices.compute ================================================ #pragma kernel CSMain float4x4 unity_WorldToShadow[4]; RWStructuredBuffer resultBuffer; //from https://answers.unity.com/questions/218333/shader-inversefloat4x4-function.html float4x4 inverse(float4x4 input) { #define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c)) float4x4 cofactors = float4x4( minor(_22_23_24, _32_33_34, _42_43_44), -minor(_21_23_24, _31_33_34, _41_43_44), minor(_21_22_24, _31_32_34, _41_42_44), -minor(_21_22_23, _31_32_33, _41_42_43), -minor(_12_13_14, _32_33_34, _42_43_44), minor(_11_13_14, _31_33_34, _41_43_44), -minor(_11_12_14, _31_32_34, _41_42_44), minor(_11_12_13, _31_32_33, _41_42_43), minor(_12_13_14, _22_23_24, _42_43_44), -minor(_11_13_14, _21_23_24, _41_43_44), minor(_11_12_14, _21_22_24, _41_42_44), -minor(_11_12_13, _21_22_23, _41_42_43), -minor(_12_13_14, _22_23_24, _32_33_34), minor(_11_13_14, _21_23_24, _31_33_34), -minor(_11_12_14, _21_22_24, _31_32_34), minor(_11_12_13, _21_22_23, _31_32_33) ); #undef minor return transpose(cofactors) / determinant(input); } [numthreads(1,1,1)] void CSMain (uint id : SV_DispatchThreadID) { resultBuffer[id] = inverse(unity_WorldToShadow[id]); } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ComputeInverseShadowMatrices.compute.meta ================================================ fileFormatVersion: 2 guid: eac7b0dfe80ae8b41b71e9e0c040a433 ComputeShaderImporter: externalObjects: {} currentAPIMask: 131076 userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/GodraysCommon.cginc ================================================ //Factor to divide the godray depth by before storing //Half have a max value of ~65000, we need to divide the depth value to be able to store it in a half texture #define textureDivisionFactor 100.0; inline float sampleGodrayDepth(sampler2D _godrayDepthTexture, float2 depthUV, float _godrayStrength) { float godrayDepth = tex2Dlod(_godrayDepthTexture, float4(depthUV,0,0)).r; godrayDepth*=_godrayStrength*textureDivisionFactor; return max(godrayDepth,0.0); } inline float writeGodrayToTexture(float depth) { return depth / textureDivisionFactor; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/GodraysCommon.cginc.meta ================================================ fileFormatVersion: 2 guid: 9f2f480fb2536e54ab8493a4e7421720 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ShadowVolumeUtils.cginc ================================================ //check if ray defined by origin and end intersects frustum //for it to intersect frustum origin and end must be on different ends of one of the axes bool intersectsFrustum(float3 origin, float3 end) { return !(origin.x > 1.0 && end.x > 1.0 || origin.x < -1.0 && end.x < -1.0) || !(origin.y > 1.0 && end.y > 1.0 || origin.y < -1.0 && end.y < -1.0) || !(origin.z < 0.0 && end.z < 0.0); } float rayDistanceToPoint(float3 rayOrigin, float3 rayDirection, float3 targetPoint) { return length(cross(rayDirection, targetPoint - rayOrigin)); } inline bool between(float a, float b, float x) { return (x > a) && (x < b); } //cascadeWeights -> 0,1,2,3 -> zero is the most detailed -> 3 is the least detailed //0 is in lower left corner, 1 in lower right corner, 2 in upper left corner, 3 in upper right corner, in the case of regular cascades no split spheres, not sure about splitSpheres //Still need to check the shadowMap for each cascade though to make sure we have a depth value at that coordinate inline fixed pickMostDetailedCascade(float4 wpos, out float4 shadowPos, sampler2D shadowMap) { float zdepth = 0; shadowPos = 0; for (int i=0; i<4;i++) { float3 coords = mul (unity_WorldToShadow[i], wpos).xyz; zdepth = tex2Dlod(shadowMap, float4(coords.xy,0.0,0.0)).r; float startX = fmod(i,2) * 0.5; float startY = (i/2) * 0.5; if (between(startX, startX+0.5, coords.x) && between(startY, startY+0.5, coords.y) && (zdepth > 0.0) && ((zdepth < 0.98) || (i==3) )) { shadowPos = float4(coords.xy, zdepth, 1.0); return i; } } return -1; } //same but pick between regular shadowMap and cloud shadowMap inline fixed pickMostDetailedCascadeCloud(float4 wpos, out float4 shadowPos, sampler2D shadowMap, sampler2D cloudShadowMap, out float isCloud) { shadowPos = 0; for (int i=0; i<4;i++) { float3 coords = mul (unity_WorldToShadow[i], wpos).xyz; float zdepth = tex2Dlod(shadowMap, float4(coords.xy,0.0,0.0)).r; float zdepthCloud = tex2Dlod(cloudShadowMap, float4(coords.xy,0.0,0.0)).r; float maxDepth = max(zdepth,zdepthCloud); float startX = fmod(i,2) * 0.5; float startY = (i/2) * 0.5; if (between(startX, startX+0.5, coords.x) && between(startY, startY+0.5, coords.y) && (maxDepth > 0.0) && ((maxDepth < 0.98) || (i==3) )) { isCloud = (zdepthCloud > zdepth) ? 1.0 : 0.0; shadowPos = float4(coords.xy, maxDepth, 1.0); return i; } } return -1; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ShadowVolumeUtils.cginc.meta ================================================ fileFormatVersion: 2 guid: c14a5e4bdca08454eb523515cecf43c2 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth - Copy.shader.BAK ================================================ Shader "Scatterer/VolumeDepth" { Properties { } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Cull Off ZWrite Off ZTest Always Blend One One // Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma hull hull #pragma domain domain #include "UnityCG.cginc" #include "UnityShadowLibrary.cginc" #include "ShadowVolumeUtils.cginc" #pragma multi_compile DUAL_DEPTH_OFF DUAL_DEPTH_ON sampler2D _ShadowMapTextureCopyScatterer; sampler2D _CameraDepthTexture; float4x4 CameraToWorld; #if defined(DUAL_DEPTH_ON) UNITY_DECLARE_DEPTH_TEXTURE(AdditionalDepthBuffer); float4x4 ScattererAdditionalInvProjection; #endif StructuredBuffer inverseShadowMatricesBuffer; float4x4 lightToWorld; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2t //vertex 2 tesselation { float4 pos : INTERNALTESSPOS; float4 worldOriginPos : TEXCOORD0; float4 worldEndPos : TEXCOORD1; }; struct d2f //domain 2 frag { float4 pos : SV_POSITION; float3 outputColor: TEXCOORD0; float4 viewPos: TEXCOORD1; float4 projPos : TEXCOORD2; float displacedPatch : TEXCOORD3; }; v2t vert (appdata v) { v2t o; //o.pos = float4(2.0*(v.uv-0.5),0.0,1.0); //try modifying this, clip space goes from -1 to 1, our UVs go from?to? //o.pos = float4(2.5*(v.uv-0.5),0.0,1.0); o.pos = float4(3.0*(v.uv-0.5),0.0,1.0); //HOLY FUCK THIS FIXES THE DISAPPEARING CHUNKS WHAT THE FUCK, so there was some weird boundary issue, also 10 KM WORKS WELL, 50 KM has glitches, 35 KM also has glitches //20 KM also still has glitches what the fuck?? o.worldOriginPos = mul(lightToWorld,o.pos); o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,10.0,1.0)); //o.worldEndPos = mul(lightToWorld,float4(0.5,0.5,10.0,1.0)); //eliminates box issue but causes holes //o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,100.0,1.0)); //o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,10000.0,1.0)); return o; } struct OutputPatchConstant { float edge[3]: SV_TessFactor; float inside : SV_InsideTessFactor; }; OutputPatchConstant constantsFixed(InputPatch patch) { OutputPatchConstant o; // bool isVisible = false; // // for (int i=0;i<3;i++) // { // float4 clipSpaceOrigin = mul(UNITY_MATRIX_VP, patch[i].worldOriginPos); // float4 clipSpaceEnd = mul(UNITY_MATRIX_VP, patch[i].worldEndPos); // isVisible = isVisible || intersectsFrustum(clipSpaceOrigin.xyz/clipSpaceOrigin.w, clipSpaceEnd.xyz/clipSpaceEnd.w); //consider this to be working though I'm not sure, maybe pass a color? // } // // if (!isVisible) // { // o.edge[0] = 0.0; // o.edge[1] = 0.0; // o.edge[2] = 0.0; // o.inside = 0.0; // } // else { // //this was really complicated to get working, and although I'm not completely sure about it, it has less holes than my cascade method float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); float maxTesselationFactor = 64.0; float distEdge0 = rayDistanceToPoint(0.5*(patch[1].worldOriginPos+patch[2].worldOriginPos), lightDir, _WorldSpaceCameraPos); float distEdge1 = rayDistanceToPoint(0.5*(patch[2].worldOriginPos+patch[0].worldOriginPos), lightDir, _WorldSpaceCameraPos); float distEdge2 = rayDistanceToPoint(0.5*(patch[0].worldOriginPos+patch[1].worldOriginPos), lightDir, _WorldSpaceCameraPos); // //// float factor0 = clamp(maxTesselationFactor * 25.0 / distEdge0,1.0,maxTesselationFactor); //// float factor1 = clamp(maxTesselationFactor * 25.0 / distEdge1,1.0,maxTesselationFactor); //// float factor2 = clamp(maxTesselationFactor * 25.0 / distEdge2,1.0,maxTesselationFactor); // float factor0 = clamp(maxTesselationFactor * 225.0 / distEdge0,1.0,maxTesselationFactor); float factor1 = clamp(maxTesselationFactor * 225.0 / distEdge1,1.0,maxTesselationFactor); float factor2 = clamp(maxTesselationFactor * 225.0 / distEdge2,1.0,maxTesselationFactor); //float insideFactor = max(factor0, max(factor1,factor2)); //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max o.edge[0] = factor0; o.edge[1] = factor1; o.edge[2] = factor2; o.inside = (factor0 + factor1 + factor2) / 3.0; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max // o.edge[0] = 16; // o.edge[1] = 16; // o.edge[2] = 16; // o.inside = 16; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max // o.edge[0] = 1; // o.edge[1] = 1; // o.edge[2] = 1; // o.inside = 1; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max } return o; } [domain("tri")] [partitioning("integer")] [outputtopology("triangle_cw")] [patchconstantfunc("constantsFixed")] [outputcontrolpoints(3)] v2t hull(InputPatch patch, uint id : SV_OutputControlPointID) { return patch[id]; } inline bool between(float a, float b, float x) { return (x > a) && (x < b); } //cascadeWeights -> 0,1,2,3 -> zero is the most detailed -> 3 is the least detailed //0 is in lower left corner, 1 in lower right corner, 2 in upper left corner, 3 in upper right corner, in the case of regular cascades no split spheres, not sure about splitSpheres //Still need to check the shadowMap for each cascade though to make sure we have a depth value at that coordinate inline fixed pickMostDetailedCascade(float4 wpos, out float4 shadowPos, sampler2D shadowMap) { float3 coords0 = mul (unity_WorldToShadow[0], wpos).xyz; float3 coords1 = mul (unity_WorldToShadow[1], wpos).xyz; float3 coords2 = mul (unity_WorldToShadow[2], wpos).xyz; float3 coords3 = mul (unity_WorldToShadow[3], wpos).xyz; float zdepth = 0; shadowPos = 0; if (between(0.0, 0.5, coords0.x) && between(0.0, 0.5, coords0.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords0.xy,0.0,0.0)).r) > 0.0 ) && (zdepth<1.0)) { shadowPos = float4(coords0.xy, zdepth, 1.0); return 0; } else if (between(0.5, 1.0, coords1.x) && between(0.0, 0.5, coords1.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords1.xy,0.0,0.0)).r) > 0.0) && (zdepth<1.0)) { shadowPos = float4(coords1.xy, zdepth, 1.0); return 1; } else if (between(0.0, 0.5, coords2.x) && between(0.5, 1.0, coords2.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords2.xy,0.0,0.0)).r) > 0.0) && (zdepth<1.0)) { shadowPos = float4(coords2.xy, zdepth, 1.0); return 2; } else if (between(0.5, 1.0, coords3.x) && between(0.5, 1.0, coords3.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords3.xy,0.0,0.0)).r) > 0.0) && (zdepth<1.0)) { shadowPos = float4(coords3.xy, zdepth, 1.0); return 3; } else { return -1; } } [domain("tri")] d2f domain(OutputPatchConstant tessFactors,const OutputPatch vs, float3 d:SV_DomainLocation) { d2f o; float3 worldPos = vs[0].worldOriginPos.xyz/vs[0].worldOriginPos.w * d.x + vs[1].worldOriginPos.xyz/vs[1].worldOriginPos.w * d.y + vs[2].worldOriginPos.xyz/vs[2].worldOriginPos.w * d.z; float4 finalWorldPos = 0; float4 shadowPos = 0; fixed cascadeIndex = pickMostDetailedCascade (float4(worldPos,1.0), shadowPos, _ShadowMapTextureCopyScatterer); //only support 4 cascades here float4x4 shadowToWorld = inverseShadowMatricesBuffer[max(cascadeIndex,0)]; //finalWorldPos = (cascadeIndex > -1) ? mul( shadowToWorld, shadowPos) : float4(worldPos.xyz - 750000.0 * normalize(_WorldSpaceLightPos0.xyz), 1.0); //finalWorldPos = (cascadeIndex > -1) ? mul( shadowToWorld, shadowPos) : float4(_WorldSpaceCameraPos.xyz - 100000.0 * normalize(_WorldSpaceLightPos0.xyz), 1.0); //eliminates the glitchy square thing //finalWorldPos = (cascadeIndex > -1) ? mul( shadowToWorld, shadowPos) : float4(_WorldSpaceCameraPos.xyz - 700000.0 * normalize(_WorldSpaceLightPos0.xyz), 1.0); //still has holes although it seems to project to infinity o.displacedPatch=1.0; finalWorldPos = mul( shadowToWorld, shadowPos); if (cascadeIndex < 0.0) { // float3 coords3 = mul (unity_WorldToShadow[3], float4(worldPos,1.0)).xyz; // //float4 madeUpShadowPos = float4( coords3.xy, 10.0, 1.0); // float4 madeUpShadowPos = float4( 0.75,0.75, 10000.0, 1.0); float3 worldEndPos = vs[0].worldEndPos.xyz/vs[0].worldEndPos.w * d.x + vs[1].worldEndPos.xyz/vs[1].worldEndPos.w * d.y + vs[2].worldEndPos.xyz/vs[2].worldEndPos.w * d.z; //ideally we would project this to our far plane and tag it as undisplaced //worldEndPos-= 100000.0 * normalize(_WorldSpaceLightPos0.xyz); finalWorldPos = float4(worldEndPos,1.0); //finalWorldPos = float4(worldPos,1.0); o.displacedPatch = 0.0; } //maybe project by the final cascade and a made up depth anyway? //color debugging stuff o.outputColor = float3(cascadeIndex == 0, cascadeIndex == 1, cascadeIndex ==2); o.outputColor = (cascadeIndex == -1) ? 0 : ((cascadeIndex == 3) ? 1.0 : o.outputColor ); o.pos=UnityWorldToClipPos(finalWorldPos); //o.pos=UnityWorldToClipPos(worldPos); o.viewPos = float4(UnityWorldToViewPos(finalWorldPos),1.0); o.projPos = ComputeScreenPos(o.pos); return o; } float4 frag (d2f i, fixed facing : VFACE) : SV_Target { float2 depthUV = i.projPos.xy/i.projPos.w; float zdepth = tex2Dlod(_CameraDepthTexture, float4(depthUV,0,0)); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 depthClipPos = float4(depthUV, zdepth, 1.0); depthClipPos.xyz = 2.0f * depthClipPos.xyz - 1.0f; float4 depthViewPos = mul(unity_CameraInvProjection, depthClipPos); float depthLength = length(depthViewPos.xyz/depthViewPos.w); //#if defined(DUAL_DEPTH_ON) // zdepth = SAMPLE_DEPTH_TEXTURE(AdditionalDepthBuffer, depthUV); // //#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) // zdepth = 1 - zdepth; //#endif // depthClipPos = float4(depthUV, zdepth, 1.0); // depthClipPos.xyz = 2.0f * depthClipPos.xyz - 1.0f; // float4 depthViewPos2 = mul(ScattererAdditionalInvProjection, depthClipPos); // // depthLength = (depthLength < 8000) || (depthLength > 50000) ? depthLength : length(depthViewPos2.xyz/depthViewPos2.w); //the 50000 is hardcoded shadow distance, hopefully we don't even need this crap //#endif float viewLength = length(i.viewPos.xyz/i.viewPos.w); //viewLength = (zdepth > 0.0) ? min(viewLength, depthLength) : viewLength; //viewLength = (zdepth > 0.0) ? min(viewLength, depthLength) : viewLength; //this is for the sky //viewLength = min(viewLength, depthLength); if (viewLength>depthLength) //discard what is behind terrain, will probably not work for clouds? viewLength = 0.0; // if (i.displacedPatch == 0.0) //not working with a factor of 3 // viewLength = 0.0; // return facing > 0 ? viewLength : -viewLength; // float cameraDepth = abs(i.viewPos.z/i.viewPos.w) / 750000; // // if (cameraDepth >= 0.9) // { // viewLength = 0.0; // //return float4(0.0,0.0,0.0,0.0); // } return facing > 0 ? viewLength : -viewLength; //return float4(cameraDepth,cameraDepth,cameraDepth,1.0); //reaches nearly white on that goddamn square, why isn't it clipped? // return facing > 0 ? float4(0.0,1.0,0.0,1.0) : float4(1.0,0.0,0.0,1.0); //return i.displacedPatch > 0.0 ? float4(1.0,1.0,1.0,1.0) : float4(1.0,0.0,0.0,1.0); //return float4(i.outputColor,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth - Copy.shader.BAK.meta ================================================ fileFormatVersion: 2 guid: 78213b1ce4da5e6438195d405c9da0f5 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth.shader ================================================ Shader "Scatterer/VolumeDepth" { Properties { } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Cull Off ZWrite Off ZTest Always Blend One One // Cull Off // Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma hull hull #pragma domain domain #include "UnityCG.cginc" #include "UnityShadowLibrary.cginc" #include "ShadowVolumeUtils.cginc" #include "../../IntersectCommon.cginc" #include "GodraysCommon.cginc" //if no ocean -> use camera depth buffer: OCEAN_INTERSECT_OFF //if ocean and in depth buffer mode -> use ocean depth buffer: OCEAN_INTERSECT_DEPTH //if ocean and in projector mode -> use analytical ocean intersect: OCEAN_INTERSECT_ANALYTICAL #pragma multi_compile OCEAN_INTERSECT_OFF OCEAN_INTERSECT_ANALYTICAL #pragma multi_compile CLOUDSMAP_OFF CLOUDSMAP_ON #pragma multi_compile DOWNSCALE_DEPTH_OFF DOWNSCALE_DEPTH_ON sampler2D _ShadowMapTextureCopyScatterer; sampler2D _CameraDepthTexture; float4 _CameraDepthTexture_TexelSize; float4x4 CameraToWorld; float3 lightDirection; float3 _planetPos; float Rg; float Rt; float _experimentalAtmoScale; sampler2D cloudShadowMap; StructuredBuffer inverseShadowMatricesBuffer; float4x4 lightToWorld; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2t //vertex 2 tesselation { float4 pos : INTERNALTESSPOS; float4 worldOriginPos : TEXCOORD0; float4 worldEndPos : TEXCOORD1; }; struct d2f //domain 2 frag { float4 pos : SV_POSITION; float4 viewPos: TEXCOORD0; float4 projPos : TEXCOORD1; float4 finalWorldPos : TEXCOORD2; float isCloud : TEXCOORD3; }; v2t vert (appdata v) { v2t o; //o.pos = float4(2.0*(v.uv-0.5),0.0,1.0); //try modifying this, clip space goes from -1 to 1, our UVs go from?to? //o.pos = float4(3.0*(v.uv-0.5),0.0,1.0); //HOLY FUCK THIS FIXES THE DISAPPEARING CHUNKS WHAT THE FUCK o.pos = float4(2.9*(v.uv-0.5),0.0,1.0); o.worldOriginPos = mul(lightToWorld,o.pos); o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,1.0,1.0)); return o; } struct OutputPatchConstant { float edge[3]: SV_TessFactor; float inside : SV_InsideTessFactor; }; OutputPatchConstant tesselationConstants(InputPatch patch) { OutputPatchConstant o; bool isVisible = false; for (int i=0;i<3;i++) { float4 clipSpaceOrigin = mul(UNITY_MATRIX_VP, patch[i].worldOriginPos); float4 clipSpaceEnd = mul(UNITY_MATRIX_VP, patch[i].worldEndPos); isVisible = isVisible || intersectsFrustum(clipSpaceOrigin.xyz/clipSpaceOrigin.w, clipSpaceEnd.xyz/clipSpaceEnd.w); //consider this to be working though I'm not sure, maybe pass a color? } if (!isVisible) { o.edge[0] = 0.0; o.edge[1] = 0.0; o.edge[2] = 0.0; o.inside = 0.0; } else { float maxTesselationFactor = 64.0; float distEdge0 = rayDistanceToPoint(0.5*(patch[1].worldOriginPos+patch[2].worldOriginPos), lightDirection, _WorldSpaceCameraPos); float distEdge1 = rayDistanceToPoint(0.5*(patch[2].worldOriginPos+patch[0].worldOriginPos), lightDirection, _WorldSpaceCameraPos); float distEdge2 = rayDistanceToPoint(0.5*(patch[0].worldOriginPos+patch[1].worldOriginPos), lightDirection, _WorldSpaceCameraPos); float factor0 = clamp(maxTesselationFactor * 225.0 / distEdge0,1.0,maxTesselationFactor); float factor1 = clamp(maxTesselationFactor * 225.0 / distEdge1,1.0,maxTesselationFactor); float factor2 = clamp(maxTesselationFactor * 225.0 / distEdge2,1.0,maxTesselationFactor); // float factor0 = clamp(maxTesselationFactor * 225.0 / distEdge0,4.0,maxTesselationFactor); // min of 4.0 is slooooow // float factor1 = clamp(maxTesselationFactor * 225.0 / distEdge1,4.0,maxTesselationFactor); // float factor2 = clamp(maxTesselationFactor * 225.0 / distEdge2,4.0,maxTesselationFactor); //float insideFactor = max(factor0, max(factor1,factor2)); //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max o.edge[0] = factor0; o.edge[1] = factor1; o.edge[2] = factor2; o.inside = (factor0 + factor1 + factor2) / 3.0; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max } return o; } [domain("tri")] [partitioning("integer")] [outputtopology("triangle_cw")] [patchconstantfunc("tesselationConstants")] [outputcontrolpoints(3)] v2t hull(InputPatch patch, uint id : SV_OutputControlPointID) { return patch[id]; } [domain("tri")] d2f domain(OutputPatchConstant tessFactors,const OutputPatch vs, float3 d:SV_DomainLocation) { d2f o; float3 worldPos = vs[0].worldOriginPos.xyz/vs[0].worldOriginPos.w * d.x + vs[1].worldOriginPos.xyz/vs[1].worldOriginPos.w * d.y + vs[2].worldOriginPos.xyz/vs[2].worldOriginPos.w * d.z; float4 finalWorldPos = 0; float4 shadowPos = 0; float isCloud = 0; //only support 4 cascades here #if defined(CLOUDSMAP_ON) fixed cascadeIndex = pickMostDetailedCascadeCloud (float4(worldPos,1.0), shadowPos, _ShadowMapTextureCopyScatterer, cloudShadowMap, isCloud); #else fixed cascadeIndex = pickMostDetailedCascade (float4(worldPos,1.0), shadowPos, _ShadowMapTextureCopyScatterer); #endif float4x4 shadowToWorld = inverseShadowMatricesBuffer[max(cascadeIndex,0)]; finalWorldPos = mul( shadowToWorld, shadowPos); if (cascadeIndex < 0.0) { //finalWorldPos = float4(_WorldSpaceCameraPos.xyz + lightDirection * 700000,1.0); //this works well for stock but breaks with parallax, what gives? finalWorldPos = float4(_WorldSpaceCameraPos.xyz + lightDirection * 500000,1.0); } o.pos=UnityWorldToClipPos(finalWorldPos); o.viewPos = float4(UnityWorldToViewPos(finalWorldPos),1.0); o.projPos = ComputeScreenPos(o.pos); o.finalWorldPos = finalWorldPos; o.isCloud = isCloud; return o; } // optical depth for ray (r,mu) of length d, using analytic formula // (mu=cos(view zenith angle)), intersections with ground ignored // H=height scale of exponential density function float OpticalDepth(float H, float r, float mu, float d) { float a = sqrt((0.5/H)*r); float2 a01 = a*float2(mu, mu + d / r); float2 a01s = sign(a01); float2 a01sq = a01*a01; float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; float2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * float2(1.0, exp(-d/H*(d/(2.0*r)+mu))); return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, float2(1.0, -1.0))); } //gets the min depth for surrounding 4 depth texels, in downscaled case float getMinDepth(float2 uv) { float2 texelSize = 0.5 * _CameraDepthTexture_TexelSize.xy; float2 taps[4] = { float2(uv + float2(-1,-1)*texelSize), float2(uv + float2(-1,1)*texelSize), float2(uv + float2(1,-1)*texelSize), float2(uv + float2(1,1)*texelSize) }; float depth1 = tex2D(_CameraDepthTexture, taps[0]).r; float depth2 = tex2D(_CameraDepthTexture, taps[1]).r; float depth3 = tex2D(_CameraDepthTexture, taps[2]).r; float depth4 = tex2D(_CameraDepthTexture, taps[3]).r; //Only return zero if all samples are zero, otherwise return the smallest which isn't zero float result = depth4; result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3); result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2); result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1); return result; } float4 frag (d2f i, fixed facing : VFACE) : SV_Target { float2 depthUV = i.projPos.xy/i.projPos.w; #if defined(DOWNSCALE_DEPTH_ON) float zdepth = getMinDepth(depthUV); #else float zdepth = tex2Dlod(_CameraDepthTexture, float4(depthUV,0,0)); #endif float linearDepth = Linear01Depth(zdepth); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 depthClipPos = float4(depthUV, zdepth, 1.0); depthClipPos.xyz = 2.0 * depthClipPos.xyz - 1.0; float4 depthViewPos = mul(unity_CameraInvProjection, depthClipPos); depthViewPos.xyz /= depthViewPos.w; float3 rayDirection = normalize(depthViewPos.xyz); float3 cameraForwardDir = float3(0,0,-1); float aa = dot(rayDirection, cameraForwardDir); depthViewPos.xyz = rayDirection * linearDepth/aa * _ProjectionParams.z; float depthLength = length(depthViewPos.xyz); float3 viewDir = normalize(i.finalWorldPos.xyz/i.finalWorldPos.w - _WorldSpaceCameraPos); float viewLength = length(i.viewPos.xyz/i.viewPos.w); if (zdepth != 1.0) //cap by terrain distance { viewLength = min(depthLength, viewLength); } // else //ray going into the sky // { // if (i.isCloud > 0.0) // { // viewLength*= 0.3; //this looks nice against the sky but where terrain and shadow meet it looks like shite // } // } #if defined(OCEAN_INTERSECT_ANALYTICAL) //cap by boundary to ocean float oceanIntersectDistance = intersectSphereOutside(_WorldSpaceCameraPos, viewDir, _planetPos, Rg); if ((oceanIntersectDistance > 0.0) && (oceanIntersectDistance <= viewLength)) { viewLength = oceanIntersectDistance; } #endif float mu = dot(normalize(_WorldSpaceCameraPos-_planetPos), viewDir); viewLength = OpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(_WorldSpaceCameraPos-_planetPos), mu, viewLength); viewLength = writeGodrayToTexture(viewLength); return facing > 0 ? viewLength : -viewLength; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth.shader.meta ================================================ fileFormatVersion: 2 guid: 4e82512e02403f342aefc6129f4d04a4 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays.meta ================================================ fileFormatVersion: 2 guid: d399317a9fcc74045a7924c9fdf2bcf6 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Preprocessing.meta ================================================ fileFormatVersion: 2 guid: 6124ad3c57404c3429a93ca37df030e9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ProjectorScattering.shader ================================================ Shader "Scatterer/AtmosphericLocalScatter" { SubShader { Tags {"Queue" = "Transparent-497" "IgnoreProjector" = "True" "RenderType" = "Transparent"} //extinction pass Pass { Tags {"Queue" = "Transparent-497" "IgnoreProjector" = "True" "RenderType" = "Transparent"} //Cull Front Cull Back ZTest LEqual ZWrite Off Blend DstColor Zero //multiplicative Offset 0.0, -0.07 CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON uniform float _global_alpha; uniform float _global_depth; uniform float3 _planetPos; //planet origin, in world space uniform float3 _camForward; //camera's viewing direction, in world space uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace uniform float _Post_Extinction_Tint; uniform float extinctionThickness; uniform float _openglThreshold; uniform float4x4 _Globals_CameraToWorld; // //eclipse uniforms //#if defined (ECLIPSES_ON) // uniform float4 sunPosAndRadius; //xyz sun pos w radius // uniform float4x4 lightOccluders1; //array of light occluders // //for each float4 xyz pos w radius // uniform float4x4 lightOccluders2; //#endif #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { float4 pos: SV_POSITION; float4 worldPos : TEXCOORD0; float3 _camPos : TEXCOORD1; }; v2f vert(appdata_base v) { v2f o; float4 worldPos = mul(unity_ObjectToWorld,v.vertex); worldPos.xyz/=worldPos.w; //needed? #if defined (CUSTOM_OCEAN_ON) worldPos.xyz = (_PlanetOpacity < 1.0) && (length(worldPos.xyz-_planetPos) < Rg) ? _planetPos+Rg* normalize(worldPos.xyz-_planetPos) : worldPos.xyz; #endif o.worldPos = float4(worldPos.xyz,1.0); o.pos = mul (UNITY_MATRIX_VP,o.worldPos); o._camPos = _WorldSpaceCameraPos - _planetPos; return o; } half4 frag(v2f i) : SV_Target { float3 worldPos = i.worldPos.xyz/i.worldPos.w - _planetPos; //worldPos relative to planet origin half returnPixel = (( (length(i._camPos)-Rg) < 1000 ) && (length(worldPos) < (Rg-50))) ? 0.0: 1.0; //enable in case of ocean and close enough to water surface, works well for kerbin worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix float3 extinction = getExtinction(i._camPos, worldPos, 1.0, 1.0, 1.0); float average=(extinction.r+extinction.g+extinction.b)/3; //lerped manually because of an issue with opengl or whatever extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); extinction = (returnPixel == 1.0) ? extinction : float3(1.0,1.0,1.0); return float4(extinction,1.0); } ENDCG } //scattering pass Pass { Tags {"Queue" = "Transparent-498" "IgnoreProjector" = "True" "RenderType" = "Transparent"} //Cull Front Cull Back ZTest LEqual ZWrite [_ZwriteVariable] Blend OneMinusDstColor One //soft additive //Blend SrcAlpha OneMinusSrcAlpha //alpha Offset 0.0, -0.07 CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #include "Godrays/GodraysCommon.cginc" // #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON #pragma multi_compile DITHERING_OFF DITHERING_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON uniform float _global_alpha; uniform float _global_depth; uniform float3 _planetPos; //planet origin, in world space uniform float3 _camForward; //camera's viewing direction, in world space uniform float _ScatteringExposure; uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif uniform float _openglThreshold; uniform float4x4 _Globals_CameraToWorld; // //eclipse uniforms //#if defined (ECLIPSES_ON) // uniform float4 sunPosAndRadius; //xyz sun pos w radius // uniform float4x4 lightOccluders1; //array of light occluders // //for each float4 xyz pos w radius // uniform float4x4 lightOccluders2; //#endif #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { float4 worldPos : TEXCOORD0; float3 _camPos : TEXCOORD1; #if defined (GODRAYS_ON) float4 projPos : TEXCOORD2; #endif }; v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { v2f o; float4 worldPos = mul(unity_ObjectToWorld,v.vertex); worldPos.xyz/=worldPos.w; //needed? //display scattering at ocean level when we are fading out local shading //at the same time ocean stops rendering it's own scattering #if defined (CUSTOM_OCEAN_ON) worldPos.xyz = (_PlanetOpacity < 1.0) && (length(worldPos.xyz-_planetPos) < Rg) ? _planetPos+Rg* normalize(worldPos.xyz-_planetPos) : worldPos.xyz; #endif o.worldPos = float4(worldPos.xyz,1.0); o.worldPos.xyz*=worldPos.w; outpos = mul (UNITY_MATRIX_VP,o.worldPos); o._camPos = _WorldSpaceCameraPos - _planetPos; #if defined (GODRAYS_ON) o.projPos = ComputeScreenPos(outpos); #endif return o; } half4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target { float3 worldPos = i.worldPos.xyz/i.worldPos.w - _planetPos; //worldPos relative to planet origin half returnPixel = (( (length(i._camPos)-Rg) < 1000 ) && (length(worldPos) < (Rg-50))) ? 0.0: 1.0; //enable in case of ocean and close enough to water surface, works well for kerbin float3 groundPos = normalize (worldPos) * Rg*1.0008; float Rt2 = Rg + (Rt - Rg) * _experimentalAtmoScale; worldPos = (length(worldPos) < Rt2) ? lerp(groundPos,worldPos,_PlanetOpacity) : worldPos; //fades to flatScaledSpace planet shading to ease the transition to scaledSpace worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix float minDistance = length(worldPos-i._camPos); float3 inscatter=0.0; float3 extinction=1.0; //TODO: put planetshine stuff in callable function #if defined (PLANETSHINE_ON) for (int j=0; j<4;++j) { if (planetShineRGB[j].w == 0) break; float intensity=1; if (planetShineSources[j].w != 1.0f) { intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[j].xyz - worldPos),SUN_DIR)),0); //if source is not a sun compute intensity of light from angle to light source //totally made up formula by eyeballing it } inscatter+=InScattering2(i._camPos, worldPos, normalize(planetShineSources[j].xyz),extinction) //lot of potential extinction recomputations here *planetShineRGB[j].xyz*planetShineRGB[j].w*intensity; } #endif #if defined (GODRAYS_ON) float2 depthUV = i.projPos.xy/i.projPos.w; float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, depthUV, 1.0); //trying to find the optical depth from the terrain level float muTerrain = dot(normalize(i.worldPos.xyz/i.worldPos.w - _planetPos), normalize(_WorldSpaceCameraPos - i.worldPos.xyz/i.worldPos.w)); godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(i.worldPos.xyz/i.worldPos.w - _planetPos), muTerrain, godrayDepth, minDistance); worldPos -= godrayDepth * normalize(worldPos-i._camPos); #endif inscatter+= InScattering2(i._camPos, worldPos,SUN_DIR,extinction); inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces //#if defined (ECLIPSES_ON) // float eclipseShadow = 1; // // for (int i=0; i<4; ++i) // { // if (lightOccluders1[i].w <= 0) break; // eclipseShadow*=getEclipseShadow(worldPos, sunPosAndRadius.xyz,lightOccluders1[i].xyz, // lightOccluders1[i].w, sunPosAndRadius.w) ; // } // // for (int j=0; j<4; ++j) // { // if (lightOccluders2[j].w <= 0) break; // eclipseShadow*=getEclipseShadow(worldPos, sunPosAndRadius.xyz,lightOccluders2[j].xyz, // lightOccluders2[j].w, sunPosAndRadius.w) ; // } // // inscatter*=eclipseShadow; //#endif inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha; return float4(dither(inscatter,screenPos)*returnPixel,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ProjectorScattering.shader.meta ================================================ fileFormatVersion: 2 guid: 9052dff19a12cb34bb02a7f74b75c4dd ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ScaledPlanetScattering.shader ================================================ Shader "Scatterer/ScaledPlanetScattering" { SubShader { Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" } Pass { //extinction pass ZWrite Off ZTest LEqual Cull Back Offset -0.05, -0.05 Blend DstColor Zero //multiplicative CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag #include "../CommonAtmosphere.cginc" #include "../EclipseCommon.cginc" #include "../RingCommon.cginc" #define useAnalyticSkyTransmittance #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON #pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON #pragma multi_compile LOCAL_MODE_OFF LOCAL_MODE_ON uniform float _Alpha_Global; uniform float extinctionTint; uniform float extinctionThickness; uniform float3 _Sun_WorldSunDir; uniform float flatScaledSpaceModel; struct v2f { float4 pos: SV_POSITION; float3 worldPos : TEXCOORD0; float3 planetOrigin: TEXCOORD1; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); //this is a hack to make the scaledScattering "fill in" for the local scattering when it gets cut off bu the limited clip plane //essentially render both scaled scattering and sky at max depth and check the z-buffer, that way only render where localScattering hasn't rendered #if defined(LOCAL_MODE_ON) #ifdef SHADER_API_D3D11 OUT.pos.z = 0.00000000000001; #else OUT.pos.z = (1.0 - 0.00000000000001) * OUT.pos.w; OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL #endif #endif OUT.worldPos = mul(unity_ObjectToWorld, v.vertex); OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz; #if defined(LOCAL_MODE_OFF) OUT.worldPos *= 6000.0; OUT.planetOrigin *= 6000.0; #endif return OUT; } half4 frag(v2f IN): COLOR { float3 extinction=0.0; float3 WCP = _WorldSpaceCameraPos; #if defined(LOCAL_MODE_OFF) WCP*=6000.0; #endif float3 planetSurfacePosition = IN.worldPos-IN.planetOrigin; float3 planetSurfaceScatteringPosition = (flatScaledSpaceModel == 1.0) ? normalize(planetSurfacePosition) * Rg * 1.0001 : planetSurfacePosition * (6005.0/6000.0); //1.0001 Rg and 6005*6000 to avoid some precision artifacts extinction = getExtinction((WCP-IN.planetOrigin), planetSurfaceScatteringPosition, 1.0, 1.0, 1.0); #if defined (ECLIPSES_ON) extinction*= getEclipseShadows(IN.worldPos); #endif #if defined (RINGSHADOW_ON) extinction *= getLinearRingColor(IN.worldPos, _Sun_WorldSunDir, IN.planetOrigin).a; #endif float average=(extinction.r+extinction.g+extinction.b)/3; extinction = extinctionTint * extinction + (1-extinctionTint) * float3(average,average,average); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); return float4(extinction,1.0); } ENDCG } Pass { //scattering pass ZWrite On ZTest LEqual Cull Back Offset -0.05, -0.05 Blend OneMinusDstColor One //soft additive CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag #include "../CommonAtmosphere.cginc" #include "../EclipseCommon.cginc" #include "../RingCommon.cginc" #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON #pragma multi_compile LOCAL_MODE_OFF LOCAL_MODE_ON //#pragma fragmentoption ARB_precision_hint_nicest uniform float _Alpha_Global; uniform float3 _Sun_WorldSunDir; uniform float _ScatteringExposure; #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif //sampler2D _MainTex; uniform float flatScaledSpaceModel; struct v2f { float4 pos: SV_POSITION; float3 worldPos : TEXCOORD0; float3 planetOrigin: TEXCOORD1; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); #if defined(LOCAL_MODE_ON) #ifdef SHADER_API_D3D11 OUT.pos.z = 0.00000000000001; #else OUT.pos.z = (1.0 - 0.00000000000001) * OUT.pos.w; OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL #endif #endif OUT.worldPos = mul(unity_ObjectToWorld, v.vertex); OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz; #if defined(LOCAL_MODE_OFF) OUT.worldPos *= 6000.0; OUT.planetOrigin *= 6000.0; #endif return OUT; } half4 frag(v2f IN): COLOR { float3 inscatter=0.0; float3 extinction=0.0; float3 WCP = _WorldSpaceCameraPos; #if defined(LOCAL_MODE_OFF) WCP*=6000.0; #endif float3 planetSurfacePosition = IN.worldPos-IN.planetOrigin; float3 planetSurfaceScatteringPosition = (flatScaledSpaceModel == 1.0) ? normalize(planetSurfacePosition) * Rg * 1.0001 : planetSurfacePosition * (6005.0/6000.0); //1.0001 Rg and 6005*6000 to avoid some precision artifacts inscatter= InScattering2((WCP-IN.planetOrigin), planetSurfaceScatteringPosition, _Sun_WorldSunDir,extinction); #if defined (ECLIPSES_ON) inscatter *= getEclipseShadows(IN.worldPos); #endif #if defined (RINGSHADOW_ON) inscatter *= getLinearRingColor(IN.worldPos, _Sun_WorldSunDir, IN.planetOrigin).a; #endif ///////////////////PLANETSHINE/////////////////////////////// //#if defined (PLANETSHINE_ON) // float3 inscatter2=0; // float intensity=1; // for (int i=0; i<4; ++i) // { // if (planetShineRGB[i].w == 0) break; // // //if source is not a sun compute intensity of light from angle to light source // intensity=1; // if (planetShineSources[i].w != 1.0f) // { //// intensity = 0.5f*(1-dot(normalize(planetShineSources[i].xyz - worldPos),WSD)); // intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[i].xyz - planetSurfacePosition),WSD)),0); // } // // inscatter2+=SkyRadiance3(WCP - IN.planetOrigin, d, normalize(planetShineSources[i].xyz)) // *planetShineRGB[i].xyz*planetShineRGB[i].w*intensity; // } // // finalColor+=inscatter2; //#endif ///////////////////////////////////////////////////////////// return float4(hdr(inscatter,_ScatteringExposure),1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ScaledPlanetScattering.shader.meta ================================================ fileFormatVersion: 2 guid: f4452670096a14945b20cca112e82047 timeCreated: 1541873026 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/SkySphere.shader ================================================ Shader "Scatterer/SkySphere" { SubShader { Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" } Pass //extinction pass, I should really just put the shared components in an include file to clean this up { Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" } ZWrite Off cull Front Blend DstColor Zero //multiplicative blending CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag #include "../CommonAtmosphere.cginc" #pragma multi_compile LOCAL_SKY_OFF LOCAL_SKY_ON uniform float _Alpha_Global; uniform float _Extinction_Tint; uniform float extinctionMultiplier; uniform float _experimentalExtinctionScale; uniform float3 _Sun_WorldSunDir; uniform float extinctionThickness; struct v2f { float4 pos : SV_POSITION; float3 worldPos : TEXCOORD0; float3 planetOrigin: TEXCOORD1; }; v2f vert(appdata_base v) { v2f OUT; //v.vertex.xyz*= (_experimentalExtinctionScale * (Rt-Rg)+ Rg) / Rt; OUT.pos = UnityObjectToClipPos(v.vertex); //this is a hack to make the sky and scaledScattering "fill in" for the local scattering when it gets cut off bu the limited clip plane //essentially render both scaled scattering and sky at max depth and check the z-buffer, that way only render where localScattering hasn't rendered #if defined (LOCAL_SKY_ON) #ifdef SHADER_API_D3D11 OUT.pos.z = 0.0; #else OUT.pos.z = OUT.pos.w; OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL #endif #endif OUT.worldPos = mul(unity_ObjectToWorld, v.vertex); OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz; #if defined (LOCAL_SKY_OFF) OUT.planetOrigin *= 6000; //all calculations are done in localSpace #endif return OUT; } float4 frag(v2f IN) : COLOR { float3 extinction = float3(1,1,1); float3 WCP = _WorldSpaceCameraPos; #if defined (LOCAL_SKY_OFF) WCP *= 6000; #endif float3 viewDir = normalize(IN.worldPos-_WorldSpaceCameraPos); //Rt=Rg+(Rt-Rg)*_experimentalExtinctionScale; float3 viewdir=normalize(viewDir); float3 camera=WCP - IN.planetOrigin; float r = length(camera); float rMu = dot(camera, viewdir); float mu = rMu / r; float r0 = r; float mu0 = mu; float dSq = rMu * rMu - r * r + Rt*Rt; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0) { camera += din * viewdir; rMu += din; mu = rMu / Rt; r = Rt; } if (r > Rt || dSq < 0.0) { return float4(1.0,1.0,1.0,1.0); } extinction = Transmittance(r, mu); //this doesn't scale correctly as the view angle would have to be adjusted in a non-trivial way, and even then, intersections with the ground in the precomputed radius won't be adjusted for //Best to switch to analyticTransmittance, with scaling of HR and HM with experimentalAtmoScale, and rescaling HR and HM when applying config to the scaled Body float average=(extinction.r+extinction.g+extinction.b)/3; extinction = _Extinction_Tint * extinction + (1-_Extinction_Tint) * float3(average,average,average); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); return float4(extinction,1.0); } ENDCG } Pass //inscattering pass { Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" } ZWrite Off cull Front //Blend One One //additive blending Blend OneMinusDstColor One //soft additive CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag #include "../CommonAtmosphere.cginc" #include "../EclipseCommon.cginc" #include "../RingCommon.cginc" #include "Godrays/GodraysCommon.cginc" #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON #pragma multi_compile DITHERING_OFF DITHERING_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON #pragma multi_compile LOCAL_SKY_OFF LOCAL_SKY_ON uniform float _Alpha_Global; uniform float3 _Sun_WorldSunDir; uniform float _SkyExposure; #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; struct v2f { float4 pos : SV_POSITION; float3 worldPos : TEXCOORD0; float3 planetOrigin: TEXCOORD1; #if defined(GODRAYS_ON) && defined(LOCAL_SKY_ON) float4 projPos : TEXCOORD2; #endif }; v2f vert(appdata_base v) { v2f OUT; v.vertex.xyz*= (_experimentalAtmoScale * (Rt-Rg)+ Rg) / Rt; OUT.pos = UnityObjectToClipPos(v.vertex); #if defined (LOCAL_SKY_ON) #ifdef SHADER_API_D3D11 OUT.pos.z = 0.0; #else OUT.pos.z = OUT.pos.w; OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL #endif #endif OUT.worldPos = mul(unity_ObjectToWorld, v.vertex); OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz; #if defined (LOCAL_SKY_OFF) OUT.planetOrigin *= 6000; //all calculations are done in localSpace #endif #if defined(GODRAYS_ON) && defined(LOCAL_SKY_ON) OUT.projPos = ComputeScreenPos(OUT.pos); #endif return OUT; } float4 frag(v2f IN) : SV_Target { float3 WSD = _Sun_WorldSunDir; float3 WCP = _WorldSpaceCameraPos; #if defined (LOCAL_SKY_OFF) WCP *= 6000; #endif float3 viewDir = normalize(IN.worldPos-_WorldSpaceCameraPos); float3 scatteringCameraPos = WCP - IN.planetOrigin; #if defined(GODRAYS_ON) && defined(LOCAL_SKY_ON) float2 depthUV = IN.projPos.xy/IN.projPos.w; float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, depthUV, 1.0); //trying to find the optical depth from the camera level, should probably remove these from the boundary of the atmo and not the camera level? float muCamera = dot(normalize(_WorldSpaceCameraPos - IN.planetOrigin), viewDir); godrayDepth = DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(_WorldSpaceCameraPos - IN.planetOrigin), muCamera, godrayDepth, 500000.0); //cap by 0.3*distance to atmo boundary float skyIntersectDistance = intersectSphereInside(_WorldSpaceCameraPos, viewDir, IN.planetOrigin, Rg + _experimentalAtmoScale * (Rt-Rg)); godrayDepth = min(0.3 * skyIntersectDistance, godrayDepth); godrayDepth *= _godrayStrength; scatteringCameraPos = scatteringCameraPos + viewDir * godrayDepth ; #endif float3 inscatter = SkyRadiance3(scatteringCameraPos, viewDir, WSD); float3 finalColor = inscatter; float eclipseShadow = 1; //find worldPos of the point in the atmo we're looking at directly //necessary for eclipses, ring shadows and planetshine float3 worldPos; #if defined (PLANETSHINE_ON) || defined (ECLIPSES_ON) || defined (RINGSHADOW_ON) float interSectPt= intersectSphereInside(WCP,viewDir,IN.planetOrigin,Rt);//*_rimQuickFixMultiplier if (interSectPt != -1) { worldPos = WCP + viewDir * interSectPt; } #endif #if defined (ECLIPSES_ON) if (interSectPt != -1) { finalColor*= getEclipseShadows(worldPos); } #endif #if defined (RINGSHADOW_ON) if (interSectPt != -1) { finalColor *= getLinearRingColor(worldPos, _Sun_WorldSunDir, IN.planetOrigin).a; } #endif /////////////////PLANETSHINE/////////////////////////////// #if defined (PLANETSHINE_ON) float3 inscatter2=0; float intensity=1; for (int i=0; i<4; ++i) { if (planetShineRGB[i].w == 0) break; //if source is not a sun compute intensity of light from angle to light source intensity=1; if (planetShineSources[i].w != 1.0f) { // intensity = 0.5f*(1-dot(normalize(planetShineSources[i].xyz - worldPos),WSD)); intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[i].xyz - worldPos),WSD)),0); } inscatter2+=SkyRadiance3(WCP - IN.planetOrigin, viewDir, normalize(planetShineSources[i].xyz)) *planetShineRGB[i].xyz*planetShineRGB[i].w*intensity; } finalColor+=inscatter2; #endif /////////////////////////////////////////////////////////// return float4(_Alpha_Global*dither(hdr(finalColor,_SkyExposure), IN.pos),1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/SkySphere.shader.meta ================================================ fileFormatVersion: 2 guid: 1e5ee557da46d59498c484308be5067e timeCreated: 1541870321 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo.meta ================================================ fileFormatVersion: 2 guid: e5d490e301a36f04a9397d7257fb157b folderAsset: yes timeCreated: 1552241563 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ClippingUtils.cginc ================================================ uniform float _ScattererCameraOverlap; //not sure if good idea to use a bool bool fragmentInsideOfClippingRange(float depth) { UNITY_BRANCH if (_ProjectionParams.z > 1000.0) //if farcamera { return (depth > (_ProjectionParams.y+1.0+_ScattererCameraOverlap)); //if fragment depth outside of current camera clipping range, return empty pixel } else //if nearcamera { return (depth <= (_ProjectionParams.z+1.0)); } } bool oceanFragmentInsideOfClippingRange(float depth) { UNITY_BRANCH if (_ProjectionParams.z > 1000.0) //if farcamera { return (depth > (_ProjectionParams.y+_ScattererCameraOverlap)); //if fragment depth outside of current camera clipping range, return empty pixel } else //if nearcamera { return (depth <= (_ProjectionParams.z+1.0)); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ClippingUtils.cginc.meta ================================================ fileFormatVersion: 2 guid: a3c7ce509d225e740aed9d6579e2a1e9 timeCreated: 1545494286 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/CommonAtmosphere.cginc ================================================ // // Precomputed Atmospheric Scattering // Copyright (c) 2008 INRIA // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. Neither the name of the copyright holders nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // THE POSSIBILITY OF SUCH DAMAGE. // // Author: Eric Bruneton // Modified and ported to Unity by Justin Hawkins 2013 // // #define useHorizonHack #define useAnalyticTransmittance uniform sampler2D _Transmittance; uniform sampler2D _Inscatter; uniform sampler2D _Irradiance; uniform float TRANSMITTANCE_W; uniform float TRANSMITTANCE_H; uniform float SKY_W; uniform float SKY_H; uniform float M_PI; uniform float3 EARTH_POS; // Rayleigh uniform float HR; uniform float3 betaR; // Mie uniform float HM; uniform float3 betaMSca; uniform float3 betaMEx; uniform float mieG; uniform float Rg; uniform float Rt; uniform float RL; uniform float RES_R; uniform float RES_MU; uniform float RES_MU_S; uniform float RES_NU; uniform float3 SUN_DIR; #define _Sun_Intensity 100.0; uniform float3 _sunColor; uniform float _experimentalAtmoScale; uniform float _viewdirOffset; uniform float cloudTerminatorSmooth; #include "IntersectCommon.cginc" /** returns the matrix {{0.0,3.0},{2.0,1.0}} */ float bayer2(const float2 xy) { return fmod(3.0*xy.x+2.0*xy.y,4.0); } /** * Non-normalized Bayer-Pattern for power-of-two sized matrices (see https://en.wikipedia.org/wiki/Ordered_dithering for the formula). * sizeExpOfTwo determines the dimension of the matrix to generate. For instance having sizeExpOfTwo == 3 yields an 8x8 matrix, sizeExpOfTwo == 4 yields 16x16. * The needed normalization factor is (2**(sizeExpOfTwo))**2, so for sizeExpOfTwo == 3 the normalization would be 64. * xy: Indices inside the matrix. For performance reasons they are not sanitized, so make sure you use valid indices. * Floating point variant. Known to be exact up to sizeExpOfTwo == 12 (might be better, just not tested) */ float bayerPattern(const int sizeExpOfTwo, float2 xy) { float factor = 1.0; float summand = 0.0; //The code would get easier to read if a while-loop were used, but then the compiler would have a harder time unrolling it. for(int i=1;i 0.0 ? float4(1.0, 0.0, 0.0, 0.5 - 0.5 / RES_MU) : float4(-1.0, H * H, H, 0.5 + 0.5 / RES_MU); float uR = 0.5 / RES_R + rho / H * (1.0 - 1.0 / float(RES_R)); float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / RES_MU); // paper formula // float uMuS = 0.5 / float(RES_MU_S) + max((1.0 - exp(-3.0 * muS - 0.6)) / (1.0 - exp(-3.6)), 0.0) * (1.0 - 1.0 / float(RES_MU_S)); // better formula float uMuS = 0.5 / RES_MU_S + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / RES_MU_S); float _lerp = (nu + 1.0) / 2.0 * (RES_NU - 1.0); float uNu = floor(_lerp); _lerp = _lerp - uNu; //original 3D lookup //return tex3Dlod(table, float4((uNu + uMuS) / RES_NU, uMu, uR, 0)) * (1.0 - _lerp) + tex3Dlod(table, float4((uNu + uMuS + 1.0) / RES_NU, uMu, uR, 0)) * _lerp; //new 2D lookup float u_0 = floor(uR*RES_R-1)/(RES_R); float u_1 = floor(uR*RES_R)/(RES_R); float u_frac = frac(uR*RES_R); float4 A = tex2Dlod(table, float4((uNu + uMuS) / RES_NU, uMu / RES_R + u_0,0.0,0.0)) * (1.0 - _lerp) + tex2Dlod(table, float4((uNu + uMuS + 1.0) / RES_NU, uMu / RES_R + u_0,0.0,0.0)) * _lerp; float4 B = tex2Dlod(table, float4((uNu + uMuS) / RES_NU, uMu / RES_R + u_1,0.0,0.0)) * (1.0 - _lerp) + tex2Dlod(table, float4((uNu + uMuS + 1.0) / RES_NU, uMu / RES_R + u_1,0.0,0.0)) * _lerp; return (A * (1.0-u_frac) + B * u_frac); } float3 GetMie(float4 rayMie) { // approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision") // rayMie.rgb=C*, rayMie.w=Cm,r return rayMie.rgb * rayMie.w / max(rayMie.r, 1e-4) * (betaR.r / betaR); } float PhaseFunctionR(float mu) { // Rayleigh phase function return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); } float PhaseFunctionM(float mu) { // Mie phase function return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG); } float3 Transmittance(float r, float mu) { // transmittance(=transparency) of atmosphere for infinite ray (r,mu) // (mu=cos(view zenith angle)), intersections with ground ignored float uR, uMu; uR = sqrt((r - Rg) / (Rt - Rg)); uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; //#if !defined(SHADER_API_OPENGL) return tex2Dlod (_Transmittance, float4(uMu, uR,0.0,0.0)).rgb; //#else // return tex2D (_Transmittance, float2(uMu, uR)).rgb; //#endif } // optical depth for ray (r,mu) of length d, using analytic formula // (mu=cos(view zenith angle)), intersections with ground ignored // H=height scale of exponential density function float OpticalDepth(float H, float r, float mu, float d) { float a = sqrt((0.5/H)*r); float2 a01 = a*float2(mu, mu + d / r); float2 a01s = sign(a01); float2 a01sq = a01*a01; float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; float2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * float2(1.0, exp(-d/H*(d/(2.0*r)+mu))); return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, float2(1.0, -1.0))); } // transmittance(=transparency) of atmosphere for ray (r,mu) of length d // (mu=cos(view zenith angle)), intersections with ground ignored // uses analytic formula instead of transmittance texture float3 AnalyticTransmittance(float r, float mu, float d) { return exp(- betaR * OpticalDepth(HR * _experimentalAtmoScale, r, mu, d) - betaMEx * OpticalDepth(HM * _experimentalAtmoScale, r, mu, d)); } //search algorithm to find approx distance from optical depth float DistanceFromOpticalDepth(float H, float r, float mu, float targetOpticalDepth, float maxLength) { if (targetOpticalDepth == 0.0) return 0.0; int maxIterations = 12; int iteration = 0; float minDistance = 0; //maybe also init this with the targetOpticalDepth? float maxDistance = maxLength; float mid = 0.5 * (maxDistance + minDistance); float depth = 0; while ((iteration < maxIterations) && (depth != targetOpticalDepth)) { depth = OpticalDepth(H, r, mu, mid); if (depth >= targetOpticalDepth) { maxDistance = mid; } else { minDistance = mid; } mid = 0.5 * (maxDistance + minDistance); iteration++; } return mid; } //the extinction part extracted from the inscattering function //this is for objects in atmo, computed using analyticTransmittance (better precision and less artifacts) or the precomputed transmittance table float3 getExtinction(float3 camera, float3 _point, float shaftWidth, float scaleCoeff, float irradianceFactor) { float3 extinction = float3(1, 1, 1); float3 viewdir = _point - camera; float d = length(viewdir) * scaleCoeff; viewdir = viewdir / d; /////////////////////experimental block begin float RtResized = Rg + (Rt - Rg) * _experimentalAtmoScale; // viewdir.x += _viewdirOffset; viewdir = normalize(viewdir); /////////////////////experimental block end float r = length(camera) * scaleCoeff; if (r < 0.9 * Rg) { camera.y += Rg; r = length(camera) * scaleCoeff; } float rMu = dot(camera, viewdir); float mu = rMu / r; float dSq = rMu * rMu - r * r + RtResized*RtResized; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0 && din < d) { rMu += din; mu = rMu / RtResized; r = RtResized; d -= din; } if (r <= RtResized && dSq >= 0.0) { // if (r < Rg + 1600.0) // { // // avoids imprecision problems in aerial perspective near ground // //Not sure if necessary with extinction // float f = (Rg + 1600.0) / r; // r = r * f; // } r = (r < Rg + 1600.0) ? (Rg + 1600.0) : r; //wtf is this? //set to analyticTransmittance only atm #if defined (useAnalyticTransmittance) extinction = min(AnalyticTransmittance(r, mu, d), 1.0); #endif } else { //if out of atmosphere extinction = float3(1,1,1); } return extinction; } //Extinction for a ray going all the way to the end of the atmosphere //i.e an infinite ray //for clouds so no analyticTransmittance required, may change this to use analytic transmittance so that everything is consistent float3 getSkyExtinction(float3 camera, float3 viewdir) //instead of camera this is the cloud position { float3 extinction = float3(1,1,1); float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale; float r = length(camera); float rMu = dot(camera, viewdir); float mu = rMu / r; float dSq = rMu * rMu - r * r + RtResized*RtResized; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0) { camera += din * viewdir; rMu += din; mu = rMu / RtResized; r = RtResized; } extinction = Transmittance(r, mu); if (r > RtResized || dSq < 0.0) { extinction = float3(1,1,1); } // //return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? float3(0,0,0) : extinction; //why is this not needed? // // float terminatorAngle = -sqrt(1.0 - (Rg / r) * (Rg / r)); // //return mu < terminatorAngle ? float3(0,0,0) : extinction; // // float index= (mu - (terminatorAngle - cloudTerminatorSmooth)) / (cloudTerminatorSmooth); // // if (index>1) // return extinction; // else if (index < 0) // return float3(0,0,0); // else // return lerp (float3(0,0,0),extinction,index); return extinction; } float3 sunsetExtinction(float3 camera) { return(getSkyExtinction(camera,SUN_DIR)); } //Extinction for a ray going all the way to the end of the atmosphere //i.e an infinite ray //with analyticTransmittance //doesn't seem to be used float3 getSkyExtinctionAnaLyticTransmittance(float3 camera, float3 viewdir) //instead of camera this is the cloud position { float3 extinction = float3(1,1,1); float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale; float r = length(camera); float rMu = dot(camera, viewdir); float mu = rMu / r; float dSq = rMu * rMu - r * r + RtResized*RtResized; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0) { camera += din * viewdir; rMu += din; mu = rMu / RtResized; r = RtResized; } //extinction = Transmittance(r, mu); float distInAtmo = abs(intersectSphereInside(camera,viewdir,float3(0,0,0),RtResized)); extinction = AnalyticTransmittance(r, mu, distInAtmo); if (r > RtResized || dSq < 0.0) { extinction = float3(1,1,1); } //return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? float3(0,0,0) : extinction; //why is this not needed? // float terminatorAngle = -sqrt(1.0 - (Rg / r) * (Rg / r)); // //return mu < terminatorAngle ? float3(0,0,0) : extinction; // // float index= (mu - (terminatorAngle - cloudTerminatorSmooth)) / (cloudTerminatorSmooth); // // if (index>1) // return extinction; // else if (index < 0) // return float3(0,0,0); // else // return lerp (float3(0,0,0),extinction,index); return extinction; } float3 SkyRadiance2(float3 camera, float3 viewdir, float3 sundir, out float3 extinction) { extinction = float3(1,1,1); float3 result = float3(0,0,0); float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale; //viewdir.x+=_viewdirOffset; viewdir=normalize(viewdir); //camera *= scale; //camera += viewdir * max(shaftWidth, 0.0); float r = length(camera); float rMu = dot(camera, viewdir); rMu+=_viewdirOffset * r; float mu = rMu / r; // float r0 = r; // float mu0 = mu; float dSq = rMu * rMu - r * r + RtResized*RtResized; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0) { camera += din * viewdir; rMu += din; mu = rMu / RtResized; r = RtResized; } float nu = dot(viewdir, sundir); float muS = dot(camera, sundir) / r; // float4 inScatter = Texture4D(_Sky_Inscatter, r, rMu / r, muS, nu); float4 inScatter = Texture4D(_Inscatter, r, rMu / r, muS, nu,RtResized); extinction = Transmittance(r, mu); if (r <= RtResized && dSq >= 0.0) { // if (shaftWidth > 0.0) // { // if (mu > 0.0) { // inScatter *= min(Transmittance(r0, mu0) / Transmittance(r, mu), 1.0).rgbr; // } else { // inScatter *= min(Transmittance(r, -mu) / Transmittance(r0, -mu0), 1.0).rgbr; // } // } float3 inScatterM = GetMie(inScatter); float phase = PhaseFunctionR(nu); float phaseM = PhaseFunctionM(nu); result = inScatter.rgb * phase + inScatterM * phaseM; } else { result = float3(0,0,0); extinction = float3(1,1,1); } result*=_sunColor; return result * _Sun_Intensity; } //same as 2 but with no extinction float3 SkyRadiance3(float3 camera, float3 viewdir, float3 sundir)//, out float3 extinction)//, float shaftWidth) { float3 result = float3(0,0,0); float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale; //viewdir.x+=_viewdirOffset; viewdir=normalize(viewdir); //camera *= scale; //camera += viewdir * max(shaftWidth, 0.0); float r = max(length(camera),Rg+100.0); //fixes artifacts when camera is crossing water surface float rMu = dot(camera, viewdir); rMu+=_viewdirOffset * r; //float mu = rMu / r; float dSq = rMu * rMu - r * r + RtResized*RtResized; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0) { camera += din * viewdir; rMu += din; //mu = rMu / RtResized; r = RtResized; } float nu = dot(viewdir, sundir); float muS = dot(camera, sundir) / r; float4 inScatter = Texture4D(_Inscatter, r, rMu / r, muS, nu,RtResized); //extinction = Transmittance(r, mu); if (r <= RtResized && dSq >= 0.0) { // if (shaftWidth > 0.0) // { // if (mu > 0.0) { // inScatter *= min(Transmittance(r0, mu0) / Transmittance(r, mu), 1.0).rgbr; // } else { // inScatter *= min(Transmittance(r, -mu) / Transmittance(r0, -mu0), 1.0).rgbr; // } // } float3 inScatterM = GetMie(inScatter); float phase = PhaseFunctionR(nu); float phaseM = PhaseFunctionM(nu); result = inScatter.rgb * phase + inScatterM * phaseM; } else { result = float3(0,0,0); //extinction = float3(1,1,1); } result*=_sunColor; return result * _Sun_Intensity; } float2 GetIrradianceUV(float r, float muS) { float uR = (r - Rg) / (Rt - Rg); float uMuS = (muS + 0.2) / (1.0 + 0.2); return float2(uMuS, uR); } float3 Irradiance(sampler2D samp, float r, float muS) { float2 uv = GetIrradianceUV(r, muS); return tex2Dlod(samp,float4(uv,0.0,0.0)).rgb; } // incident sky light at given position, integrated over the hemisphere (irradiance) // r=length(x) // muS=dot(x,s) / r float3 SkyIrradiance(float r, float muS) { return Irradiance(_Irradiance, r, muS) * _sunColor * _Sun_Intensity; } // transmittance(=transparency) of atmosphere for infinite ray (r,mu) // (mu=cos(view zenith angle)), or zero if ray intersects ground // Change to analytic? float3 TransmittanceWithShadow(float r, float mu) { return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? float3(0,0,0) : Transmittance(r, mu); } // incident sun light at given position (radiance) // r=length(x) // muS=dot(x,s) / r float3 SunRadiance(float r, float muS) { return TransmittanceWithShadow(r, muS) * _sunColor * _Sun_Intensity; } void SunRadianceAndSkyIrradiance(float3 worldP, float3 worldN, float3 worldS, out float3 sunL, out float3 skyE) { // worldP *= scale; float r = length(worldP); if (r < 0.9 * Rg) { worldP.z += Rg; r = length(worldP); } float3 worldV = worldP / r; // vertical vector float muS = dot(worldV, worldS); float sunOcclusion = 1.0;// - sunShadow; //sunL = SunRadiance(r, muS) * sunOcclusion; sunL = TransmittanceWithShadow(r, muS) * _sunColor * _Sun_Intensity;//removed _Sun_Intensity multiplier // ambient occlusion due only to slope, does not take self shadowing into account float skyOcclusion = (1.0 + dot(worldV, worldN)) * 0.5; // factor 2.0 : hack to increase sky contribution (numerical simulation of // "precompued atmospheric scattering" gives less luminance than in reality) skyE = 2.0 * SkyIrradiance(r, muS) * skyOcclusion; } float3 SimpleSkyirradiance(float3 worldP, float3 worldN, float3 worldS) { float r = length(worldP); if (r < 0.9 * Rg) { worldP.z += Rg; r = length(worldP); } float3 worldV = worldP / r; // vertical vector float muS = dot(worldV, worldS); // ambient occlusion due only to slope, does not take self shadowing into account float skyOcclusion = (1.0 + dot(worldV, worldN)) * 0.5; // factor 2.0 : hack to increase sky contribution (numerical simulation of // "precompued atmospheric scattering" gives less luminance than in reality) float3 skyE = 2.0 * SkyIrradiance(r, muS) * skyOcclusion; return skyE; } //InScattering with modified atmo heights float3 InScattering2(float3 camera, float3 _point, float3 sunDir, out float3 extinction) { // single scattered sunlight between two points // camera=observer // point=point on the ground // sundir=unit vector towards the sun // return scattered light and extinction coefficient float3 result = float3(0, 0, 0); extinction=1.0; float3 viewdir = _point - camera; float d = length(viewdir); viewdir = viewdir / d; float RtResized = Rg + (Rt - Rg) * _experimentalAtmoScale; viewdir = normalize(viewdir); float r = length(camera); if (r < 0.9 * Rg) { camera.y += Rg; _point.y += Rg; r = length(camera); } float rMu = dot(camera, viewdir); float mu = rMu / r; float r0 = r; float mu0 = mu; float muExtinction=mu; _point -= viewdir * clamp(1.0, 0.0, d); float dSq = rMu * rMu - r * r + RtResized*RtResized; float deltaSq = sqrt(dSq); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0 && din < d) { camera += din * viewdir; rMu += din; mu = rMu / RtResized; r = RtResized; d -= din; } if (r <= RtResized && dSq >= 0.0) { float nu = dot(viewdir, sunDir); float muS = dot(camera, sunDir) / r; float4 inScatter; if (r < Rg + 1600.0) { // avoids imprecision problems in aerial perspective near ground float f = (Rg + 1600.0) / r; r = r * f; rMu = rMu * f; _point = _point * f; } float r1 = length(_point); float rMu1 = dot(_point, viewdir); float mu1 = rMu1 / r1; float muS1 = dot(_point, sunDir) / r1; // #if defined (useAnalyticTransmittance) extinction = min(AnalyticTransmittance(r, mu, d), 1.0); //#else // if (mu > 0.0) // { // extinction = min(Transmittance(r, mu, Rt) / Transmittance(r1, mu1, Rt), 1.0); // } // else // { // extinction = min(Transmittance(r1, -mu1, Rt) / Transmittance(r, -mu, Rt), 1.0); // } // #endif // #ifdef useHorizonHack //reduces it but doesn't fix it, have to try to get the other one //const float EPS = 0.004; const float EPS = 0.01; float lim = -sqrt(1.0 - (Rg / r) * (Rg / r)); if (abs(mu - lim) < EPS) { //float a = ((mu - lim) + EPS) / (2.0 * EPS); float a = saturate(2.0 * ((mu - lim) + EPS) / (2.0 * EPS)); //these make inScatterA black, let's try without and increase EPS to 0.01 //almost does it, still a faint outline of it visible, maybe debug if sqrt doesn't need to be 0 below? //trying 0.04, nope, still a faint outline visible //back to 0.01 with sqrt fix, doesn't work either, weird, maybe extinction is too strong? // mu = lim - EPS; // r1 = r * r + d * d + 2.0 * r * d * mu; // r1 = r1 > 0.0 ? sqrt(r1) : 1e30; // mu1 = (r * mu + d) / r1; float4 inScatter0 = Texture4D(_Inscatter, r, mu, muS, nu, RtResized); float4 inScatter1 = Texture4D(_Inscatter, r1, mu1, muS1, nu, RtResized); float4 inScatterA = max(inScatter0 - inScatter1 * extinction.rgbr, 0.0); mu = lim + EPS; r1 = sqrt(r * r + d * d + 2.0 * r * d * mu); mu1 = (r * mu + d) / r1; inScatter0 = Texture4D(_Inscatter, r, mu, muS, nu, RtResized); inScatter1 = Texture4D(_Inscatter, r1, mu1, muS1, nu, RtResized); float4 inScatterB = max(inScatter0 - inScatter1 * extinction.rgbr, 0.0); inScatter = lerp(inScatterA, inScatterB, a); } else // #endif { float4 inScatter0 = Texture4D(_Inscatter, r, mu, muS, nu,RtResized); float4 inScatter1 = Texture4D(_Inscatter, r1, mu1, muS1, nu,RtResized); inScatter = max(inScatter0 - inScatter1 * extinction.rgbr, 0.0); } // avoids imprecision problems in Mie scattering when sun is below horizon inScatter.w *= smoothstep(0.00, 0.02, muS); float3 inScatterM = GetMie(inScatter); float phase = PhaseFunctionR(nu); float phaseM = PhaseFunctionM(nu); result = inScatter.rgb * phase + inScatterM * phaseM; } else { //if out of atmosphere result = float3(0,0,0); // extinction = float3(1,1,1); } return result * _sunColor * _Sun_Intensity; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/CommonAtmosphere.cginc.meta ================================================ fileFormatVersion: 2 guid: ac742e1acf5f82f45b9d8ec53fe15b21 ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/DecodedToFloat.shader ================================================ Shader "EncodeFloat/DecodeToFloat" { SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _TexR, _TexG, _TexB, _TexA; uniform float _Max, _Min; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord.xy; return OUT; } //This is a built in function but I like to see the code float decodeFloatRGBA( float4 rgba ) { return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); } float4 frag(v2f IN) : COLOR { float R = decodeFloatRGBA(tex2D(_TexR, IN.uv.xy)); float G = decodeFloatRGBA(tex2D(_TexG, IN.uv.xy)); float B = decodeFloatRGBA(tex2D(_TexB, IN.uv.xy)); float A = decodeFloatRGBA(tex2D(_TexA, IN.uv.xy)); return (float4(R,G,B,A) * _Max) - _Min; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/DecodedToFloat.shader.meta ================================================ fileFormatVersion: 2 guid: 6aeb6a309c9b39647b273d5f92e593dd timeCreated: 1459689856 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/WriteToFloat.shader ================================================ Shader "EncodeFloat/WriteToFloat" { SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _TexR, _TexG, _TexB, _TexA; uniform float _Max, _Min; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord.xy; return OUT; } //This is a built in function but I like to see the code float decodeFloatRGBA( float4 rgba ) { return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); } float4 frag(v2f IN) : COLOR { float R = decodeFloatRGBA(tex2D(_TexR, IN.uv.xy)); float G = decodeFloatRGBA(tex2D(_TexG, IN.uv.xy)); float B = decodeFloatRGBA(tex2D(_TexB, IN.uv.xy)); float A = decodeFloatRGBA(tex2D(_TexA, IN.uv.xy)); return (float4(R,G,B,A) * _Max) - _Min; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/WriteToFloat.shader.meta ================================================ fileFormatVersion: 2 guid: 2c80ef0306e06ac4d8a4b0fe7e4536ac timeCreated: 1459689856 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode.meta ================================================ fileFormatVersion: 2 guid: 8e6115ff67c8ba44ba8780322ca78ef8 folderAsset: yes timeCreated: 1541842845 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/CopyCameraDepth.shader ================================================ Shader "Scatterer/CopyCameraDepth" { SubShader { Pass //pass 0, simple copy from camera's depth texture { ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _CameraDepthTexture; v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float frag(v2f IN) : SV_Depth { return float4(tex2Dlod(_CameraDepthTexture, float4(IN.uv,0.0,0.0)).rgb,1.0); } ENDCG } Pass //pass 1, same as 0 but with a small bias for depth pre-pass merging to screen { ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _CameraDepthTexture; v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float frag(v2f IN) : SV_Depth { return float4(tex2Dlod(_CameraDepthTexture, float4(IN.uv,0.0,0.0)).r * 0.9999, 0.0, 0.0, 1.0); } ENDCG } Pass //pass 2, same as 0 but from _MainTex { ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float frag(v2f IN) : SV_Depth { return float4(tex2Dlod(_MainTex, float4(IN.uv,0.0,0.0)).rgb,1.0); } ENDCG } } Fallback off } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/CopyCameraDepth.shader.meta ================================================ fileFormatVersion: 2 guid: 8db4dc37ed52fc24ba715aaa8e0fd20f ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DepthToDistance.shader ================================================  Shader "Scatterer/DepthToDistance" { SubShader { Tags {"IgnoreProjector" = "True" "RenderType" = "Transparent"} Pass { Cull Off ZTest Off ZWrite Off Blend SrcAlpha OneMinusSrcAlpha // Alpha blending CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" uniform sampler2D _CameraDepthTexture; struct v2f { float4 pos: SV_POSITION; float2 uv: TEXCOORD1; }; v2f vert(appdata_base v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = ComputeNonStereoScreenPos(o.pos); return o; } half4 frag(v2f i) : SV_Target { float zdepth = tex2Dlod(_CameraDepthTexture, float4(i.uv,0,0)); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(i.uv, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; float fragDistance = length(camPos.xyz) / 750000.0; return float4(fragDistance,fragDistance,fragDistance, (zdepth < 1.0) ? 1.0 : 0.0); //discard if zdepth is 1.0, ie nothing written to depth texture } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DepthToDistance.shader.meta ================================================ fileFormatVersion: 2 guid: 34fc60e2fe0cbfa4a87375cdfff9dc86 timeCreated: 1550493086 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DownscaleDepth.shader ================================================ Shader "Scatterer/DownscaleDepth" { SubShader { Pass //Pass 0, downscale default buffer to 1/4 { ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _CameraDepthTexture; float4 _CameraDepthTexture_TexelSize; // (1.0/width, 1.0/height, width, height) v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float4 frag(v2f input) : SV_Target { float2 texelSize = 0.5 * _CameraDepthTexture_TexelSize.xy; float2 taps[4] = { float2(input.uv + float2(-1,-1)*texelSize), float2(input.uv + float2(-1,1)*texelSize), float2(input.uv + float2(1,-1)*texelSize), float2(input.uv + float2(1,1)*texelSize) }; float depth1 = tex2D(_CameraDepthTexture, taps[0]).r; float depth2 = tex2D(_CameraDepthTexture, taps[1]).r; float depth3 = tex2D(_CameraDepthTexture, taps[2]).r; float depth4 = tex2D(_CameraDepthTexture, taps[3]).r; //float result = min(depth1, min(depth2, min(depth3, depth4))); //takes min depth, for reverse Z equivalent to taking farthest, may or may not be better for depth discontinuities, test both //good but should eliminate samples with depth 0.0 // //Only return zero if all samples are zero, otherwise return the smallest which isn't zero float result = depth4; result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3); result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2); result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1); return result; } ENDCG } Pass //Pass 1, downscale other buffer to a further 1/4 (so 1/16 final) { ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D ScattererDownscaledDepthIntermediate; float4 ScattererDownscaledDepthIntermediate_TexelSize; // (1.0/width, 1.0/height, width, height) v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float4 frag(v2f input) : SV_Target { float2 texelSize = 0.5 * ScattererDownscaledDepthIntermediate_TexelSize.xy; float2 taps[4] = { float2(input.uv + float2(-1,-1)*texelSize), float2(input.uv + float2(-1,1)*texelSize), float2(input.uv + float2(1,-1)*texelSize), float2(input.uv + float2(1,1)*texelSize) }; float depth1 = tex2D(ScattererDownscaledDepthIntermediate, taps[0]).r; float depth2 = tex2D(ScattererDownscaledDepthIntermediate, taps[1]).r; float depth3 = tex2D(ScattererDownscaledDepthIntermediate, taps[2]).r; float depth4 = tex2D(ScattererDownscaledDepthIntermediate, taps[3]).r; //Only return zero if all samples are zero, otherwise return the smalles which isn't zero float result = depth4; result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3); result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2); result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1); return result; } ENDCG } Pass //Pass 2, perform bilateral blurring { ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D ScattererDownscaledDepth; float4 ScattererDownscaledDepth_TexelSize; // (1.0/width, 1.0/height, width, height) float2 BlurDir; sampler2D TextureToBlur; float4 TextureToBlur_TexelSize; v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float4 frag(v2f input) : SV_Target { const float offset[4] = { 0, 1, 2, 3 }; const float weight[4] = { 0.266, 0.213, 0.1, 0.036 }; //linearise depth [0-1] float centralDepth = Linear01Depth(tex2D(ScattererDownscaledDepth, input.uv)); float result = tex2D(TextureToBlur, input.uv).r * weight[0]; float totalWeight = weight[0]; //float BlurDepthFalloff = 0.01; //probably change this //float BlurDepthFalloff = 1.0; //guess this is too much, try 0.1 float BlurDepthFalloff = 0.1; //seems ok but doesn't fix my issue though [unroll] for (int i = 1; i < 4; i++) { float depth = Linear01Depth(tex2D(ScattererDownscaledDepth, (input.uv + BlurDir * offset[i] * ScattererDownscaledDepth_TexelSize.xy ))); float w = abs(depth-centralDepth)* BlurDepthFalloff; w = exp(-w*w); result += tex2D(TextureToBlur, ( input.uv + BlurDir * offset[i] * TextureToBlur_TexelSize.xy )).r * w * weight[i]; totalWeight += w * weight[i]; depth = Linear01Depth(tex2D(ScattererDownscaledDepth, (input.uv - BlurDir * offset[i] * ScattererDownscaledDepth_TexelSize.xy ))); w = abs(depth-centralDepth)* BlurDepthFalloff; w = exp(-w*w); result += tex2D(TextureToBlur, ( input.uv - BlurDir * offset[i] * TextureToBlur_TexelSize.xy )).r * w* weight[i]; totalWeight += w * weight[i]; } return float4(result,result,result,1.0); } ENDCG } Pass //Pass 3, downscale custom depth buffer to 1/4 { ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D ScattererDepthCopy; float4 ScattererDepthCopy_TexelSize; // (1.0/width, 1.0/height, width, height) v2f vert( appdata_img v ) { v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } float4 frag(v2f input) : SV_Target { float2 texelSize = 0.5 * ScattererDepthCopy_TexelSize.xy; float2 taps[4] = { float2(input.uv + float2(-1,-1)*texelSize), float2(input.uv + float2(-1,1)*texelSize), float2(input.uv + float2(1,-1)*texelSize), float2(input.uv + float2(1,1)*texelSize) }; float depth1 = tex2D(ScattererDepthCopy, taps[0]).r; float depth2 = tex2D(ScattererDepthCopy, taps[1]).r; float depth3 = tex2D(ScattererDepthCopy, taps[2]).r; float depth4 = tex2D(ScattererDepthCopy, taps[3]).r; //Only return zero if all samples are zero, otherwise return the smallest which isn't zero float result = depth4; result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3); result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2); result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1); return result; } ENDCG } } Fallback off } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DownscaleDepth.shader.meta ================================================ fileFormatVersion: 2 guid: 2cb24b5a5793c654e899a06bf08ec3ae ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth.meta ================================================ fileFormatVersion: 2 guid: 230f3ac09b9ef234cba81ade9bd0e32a folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DepthCommon.cginc ================================================ #include "UnityCG.cginc" uniform sampler2D _CameraDepthTexture; uniform sampler2D _customDepthTexture; float3 getViewSpacePosFromDepth(float2 uv) { uv.y = 1.0 - uv.y; float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0)); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(uv, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; return camPos.xyz; } float3 getPreciseViewSpacePosFromDepth(float2 uv) { uv.y = 1.0 - uv.y; float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0)); float depth = Linear01Depth(zdepth); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(uv, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; float3 rayDirection = normalize(camPos.xyz); float3 cameraForwardDir = float3(0,0,1); float aa = dot(rayDirection, cameraForwardDir); float3 vposPersp = rayDirection * depth/aa * _ProjectionParams.z; return vposPersp; } float getScattererFragDistance(float2 uv) { #if defined (SCATTERER_MERGED_DEPTH_ON) return tex2Dlod(_customDepthTexture, float4(uv,0,0)).r* 750000; #else return length(getPreciseViewSpacePosFromDepth(uv).xyz); #endif } //checks if we have anything in the depth buffer or is empty at coordinate //used by sunflare to check if we should block the sun fixed checkDepthBufferEmpty(float2 uv) { #if defined (SCATTERER_MERGED_DEPTH_ON) float depth = tex2Dlod(_customDepthTexture,float4(uv,0.0,0.0)); //if there's something in the way don't render the flare return (depth < 1.0) ? 0.0 : 1.0 ; #else float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0)); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif return (zdepth < 1.0) ? 0.0 : 1.0 ; #endif } //get WorldPos from depth using inaccurate invprojection method float3 getWorldPosFromDepth(float2 uv, float zdepth, float4x4 CameraToWorld) { #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(uv, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); float4 worldPos = mul(CameraToWorld,camPos); return (worldPos.xyz/worldPos.w); } //hybrid method using the depth from the ray method and the direction from the invprojection method //seems to work pretty well //could be optimized further by moving the raydirection calculation to the vertex shader float3 getPreciseWorldPosFromDepth(float2 uv, float zdepth, float4x4 CameraToWorld) { float depth = Linear01Depth(zdepth); #if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(uv, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; float3 rayDirection = normalize(camPos.xyz); float3 cameraForwardDir = float3(0,0,-1); float aa = dot(rayDirection, cameraForwardDir); camPos.xyz = rayDirection * depth/aa * _ProjectionParams.z; float4 worldPos = mul(CameraToWorld,float4(camPos.xyz,1.0)); return (worldPos.xyz/worldPos.w); } //Refines the inaccurate worldPos from invprojection with a search algorithm //While this gives good results, it is no longer needed, the hybrid ray/projmatrix method is faster and gives similar precision float getRefinedDistanceFromDepth(float unrefinedDistance, float zdepth, float3 worldViewDir) { //maybe scale these based on distance? const int maxIterations = 10; //seems about perfect int iteration = 0; //This should considerably reduce the search space float maxSearchDistance = unrefinedDistance * 1.30; float minSearchDistance = unrefinedDistance * 0.70; float mid = 0; float3 worldPos0 = float3(0.0,0.0,0.0); float4 clipPos = float4(0.0,0.0,0.0,1.0); float depth = -10.0; while ((iteration < maxIterations) && (depth != zdepth)) { mid = 0.5 * (maxSearchDistance + minSearchDistance); worldPos0 = _WorldSpaceCameraPos + worldViewDir * mid; clipPos = mul(UNITY_MATRIX_VP, float4(worldPos0,1.0)); depth = clipPos.z/clipPos.w; maxSearchDistance = (depth < zdepth) ? mid : maxSearchDistance; minSearchDistance = (depth > zdepth) ? mid : minSearchDistance; iteration++; } return mid; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DepthCommon.cginc.meta ================================================ fileFormatVersion: 2 guid: 1b199a26663a15b4db765ffb1df401f2 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/CloudVolumeParticle.shader ================================================  Shader "Scatterer-EVE/CloudVolumeParticle" { Properties { _Tex("Particle Texture", 2D) = "white" {} _MainTex("Main (RGB)", 2D) = "white" {} _PerlinTex("Perlin (RGB)", 2D) = "white" {} _BumpMap("Normalmap", 2D) = "bump" {} _DetailTex("Detail (RGB)", 2D) = "white" {} _DetailScale("Detail Scale", Range(0,1000)) = 100 _DistFade("Distance Fade Near", Float) = 1.0 _DistFadeVert("Distance Fade Vertical", Float) = 0.0004 _MinScatter("Min Scatter", Float) = 1.05 _Opacity("Opacity", Float) = 1.05 _Color("Color Tint", Color) = (1,1,1,1) _InvFade("Soft Particles Factor", Range(0,1.0)) = .008 _Rotation("Rotation", Float) = 0 _MaxScale("Max Scale", Float) = 1 _MaxTrans("Max Translation", Vector) = (0,0,0) _NoiseScale("Noise Scale", Vector) = (1,2,.0005,100) _SunPos("_SunPos", Vector) = (0,0,0) _SunRadius("_SunRadius", Float) = 1 } Category { Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True" } Blend SrcAlpha OneMinusSrcAlpha Fog { Mode Global} AlphaTest Greater 0 ColorMask RGB Cull Back Lighting On ZWrite Off SubShader { Pass { Lighting On Tags { "LightMode"="ForwardBase"} CGPROGRAM #include "EVEUtils.cginc" #pragma target 3.0 #pragma glsl #pragma vertex vert #pragma fragment frag #define MAG_ONE 1.4142135623730950488016887242097 #pragma fragmentoption ARB_precision_hint_fastest // #pragma multi_compile_fwdbase #pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON #pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1 #ifndef MAP_TYPE_CUBE2_1 #pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1 #endif #include "noiseSimplex.cginc" #include "alphaMap.cginc" #include "cubeMap.cginc" #pragma multi_compile SCATTERER_OFF SCATTERER_ON #pragma multi_compile SCATTERER_USE_ORIG_DIR_COLOR_OFF SCATTERER_USE_ORIG_DIR_COLOR_ON #ifdef SCATTERER_ON #include "../CommonAtmosphere.cginc" #endif CUBEMAP_DEF_1(_MainTex) sampler2D _Tex; sampler2D _DetailTex; sampler2D _BumpMap; float4x4 _PosRotation; float _DetailScale; fixed4 _Color; float _DistFade; float _DistFadeVert; float _MinScatter; float _Opacity; float _InvFade; float _Rotation; float _MaxScale; float4 _NoiseScale; float3 _MaxTrans; sampler2D _CameraDepthTexture; // float4x4 _CameraToWorld; #ifdef SCATTERER_ON uniform float cloudColorMultiplier; uniform float cloudScatteringMultiplier; uniform float cloudSkyIrradianceMultiplier; uniform float3 _Sun_WorldSunDir; uniform float3 _PlanetWorldPos; uniform float3 scattererOrigDirectionalColor; #endif struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; fixed4 color : COLOR; half4 viewDir : TEXCOORD0; // float2 texcoordZY : TEXCOORD1; // float2 texcoordXZ : TEXCOORD2; // float2 texcoordXY : TEXCOORD3; // float2 uv : TEXCOORD4; // float4 projPos : TEXCOORD5; // float3 planetPos : TEXCOORD6; // float3 viewDirT : TEXCOORD7; // float3 lightDirT : TEXCOORD8; //store ZY+XZ and XY+uv together in two float4 to free up 2 interpolators float4 texcoordZYXZ : TEXCOORD1; float4 texcoordXYuv : TEXCOORD2; float4 projPos : TEXCOORD3; float3 planetPos : TEXCOORD4; float3 viewDirT : TEXCOORD5; float3 lightDirT : TEXCOORD6; // float3 inScattering : TEXCOORD7; // float3 relWorldPos : TEXCOORD8; // float3 sunExtinction : TEXCOORD8; }; v2f vert (appdata_t v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); float4 origin = mul(unity_ObjectToWorld, float4(0,0,0,1)); float4 planet_pos = mul(_PosRotation, origin); float3 normalized = _NoiseScale.z*(planet_pos.xyz); float3 hashVect = .5*(float3(snoise(normalized), snoise(_NoiseScale.x*normalized), snoise(_NoiseScale.y*normalized))+1); float4 localOrigin; localOrigin.xyz = (2*hashVect-1)*_MaxTrans; localOrigin.w = 1; float localScale = (hashVect.x*(_MaxScale - 1)) + 1; origin = mul(unity_ObjectToWorld, localOrigin); planet_pos = mul(_MainRotation, origin); float3 detail_pos = mul(_DetailRotation, planet_pos).xyz; o.planetPos = planet_pos.xyz; o.color = VERT_GET_NO_LOD_CUBE_MAP_1(_MainTex, planet_pos.xyz); o.color.rgba *= GetCubeDetailMapNoLOD(_DetailTex, detail_pos, _DetailScale); o.viewDir.w = GetDistanceFade(distance(origin, _WorldSpaceCameraPos), _DistFade, _DistFadeVert); o.color.a *= o.viewDir.w; float4x4 M = rand_rotation( (float3(frac(_Rotation),0,0))+hashVect, localScale, localOrigin.xyz); float4x4 mvMatrix = mul(mul(UNITY_MATRIX_V, unity_ObjectToWorld), M); float3 viewDir = normalize(mvMatrix[2].xyz); o.viewDir.xyz = abs(viewDir).xyz; float4 mvCenter = mul(UNITY_MATRIX_MV, localOrigin); o.pos = mul(UNITY_MATRIX_P,mvCenter+float4(v.vertex.xyz*localScale,v.vertex.w)); o.pos = o.color.a > (1.0/255.0) ? o.pos : float4(2.0, 2.0, 2.0, 1.0); //outside clip space => cull vertex float2 texcoodOffsetxy = ((2*v.texcoord)- 1); float4 texcoordOffset = float4(texcoodOffsetxy.x, texcoodOffsetxy.y, 0, v.vertex.w); float4 ZYv = texcoordOffset.zyxw; float4 XZv = texcoordOffset.xzyw; float4 XYv = texcoordOffset.xyzw; ZYv.z*=sign(-viewDir.x); XZv.x*=sign(-viewDir.y); XYv.x*=sign(viewDir.z); ZYv.x += sign(-viewDir.x)*sign(ZYv.z)*(viewDir.z); XZv.y += sign(-viewDir.y)*sign(XZv.x)*(viewDir.x); XYv.z += sign(-viewDir.z)*sign(XYv.x)*(viewDir.x); ZYv.x += sign(-viewDir.x)*sign(ZYv.y)*(viewDir.y); XZv.y += sign(-viewDir.y)*sign(XZv.z)*(viewDir.z); XYv.z += sign(-viewDir.z)*sign(XYv.y)*(viewDir.y); float2 ZY = mul(mvMatrix, ZYv).xy - mvCenter.xy; float2 XZ = mul(mvMatrix, XZv).xy - mvCenter.xy; float2 XY = mul(mvMatrix, XYv).xy - mvCenter.xy; // o.texcoordZY = half2(.5 ,.5) + .6*(ZY); // o.texcoordXZ = half2(.5 ,.5) + .6*(XZ); // o.texcoordXY = half2(.5 ,.5) + .6*(XY); //later store together in a float4 to free up 2 interpolators float2 texcoordZY = half2(.5 ,.5) + .6*(ZY); float2 texcoordXZ = half2(.5 ,.5) + .6*(XZ); float2 texcoordXY = half2(.5 ,.5) + .6*(XY); float3 worldNormal = normalize(mul( unity_ObjectToWorld, float4( v.normal, 0.0 ) ).xyz); viewDir = normalize(origin - _WorldSpaceCameraPos); //o.color.rgb *= MultiBodyShadow(origin, _SunRadius, _SunPos, _ShadowBodies); //o.color.rgb *= Terminator(_WorldSpaceLightPos0, worldNormal); #ifdef SCATTERER_ON //float3 worldPos = mul(unity_ObjectToWorld, localOrigin); float3 worldPos = origin; float3 extinction = float3(0, 0, 0); float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space // float3 worigin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz; float3 worigin = _PlanetWorldPos; float3 relWorldPos=worldPos-worigin; float3 relCameraPos=WCP-worigin; //relWorldPos=lerp(Rg*normalize(relWorldPos),relWorldPos,cloudExtinctionHeightMultiplier); //extinction of light from sun to cloud float3 sunExtinction = getSkyExtinction(relWorldPos,_Sun_WorldSunDir); //extinction from cloud to observer extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction; // //skyLight // float3 skyE = SimpleSkyirradiance(relWorldPos, viewDir.xyz, _Sun_WorldSunDir); // // o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction + skyE*cloudSkyIrradianceMultiplier; // o.relWorldPos = relWorldPos; // //inScattering from cloud to observer // float3 inscatter = InScattering2(relCameraPos, relWorldPos, extinction, _Sun_WorldSunDir, 1.0, 1.0, 1.0); // o.inScattering = inscatter * cloudScatteringMultiplier; // // //extinction from cloud to observer // extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); // // o.color.rgb *= cloudColorMultiplier * extinction; #endif #ifdef SOFT_DEPTH_ON o.projPos = ComputeScreenPos (o.pos); COMPUTE_EYEDEPTH(o.projPos.z); #endif //WorldSpaceViewDir(origin).xyz half3 normal = normalize(-viewDir); float3 tangent = UNITY_MATRIX_V[0].xyz; float3 binormal = -cross(normal, normalize(tangent)); float3x3 rotation = float3x3(tangent.xyz, binormal, normal); o.lightDirT = normalize(mul(rotation, _WorldSpaceLightPos0.xyz)); o.viewDirT = normalize(mul(rotation, viewDir)); // // o.uv = v.texcoord; float2 uv = v.texcoord; //store together in a float4 to free up 2 interpolators o.texcoordZYXZ=float4(texcoordZY,texcoordXZ); o.texcoordXYuv=float4(texcoordXY,uv); return o; } fixed4 frag (v2f IN) : COLOR { half4 tex; //extract from float4 interpolator float2 texcoordZY = IN.texcoordZYXZ.xy; float2 texcoordXZ = IN.texcoordZYXZ.zw; float2 texcoordXY = IN.texcoordXYuv.xy; float2 uv = IN.texcoordXYuv.zw; // tex.r = tex2D(_Tex, IN.texcoordZY).r; // tex.g = tex2D(_Tex, IN.texcoordXZ).g; // tex.b = tex2D(_Tex, IN.texcoordXY).b; tex.r = tex2D(_Tex, texcoordZY).r; tex.g = tex2D(_Tex, texcoordXZ).g; tex.b = tex2D(_Tex, texcoordXY).b; tex.a = 0; tex.rgb *= IN.viewDir.rgb; half4 vect = half4( IN.viewDir.rgb, 0); tex /= vectorSum(vect); tex = half4(1, 1, 1, vectorSum(tex)); half4 color = FRAG_GET_NO_LOD_CUBE_MAP_1(_MainTex, IN.planetPos); color = ALPHA_COLOR_1(color); color *= _Color * IN.color; //half3 normT = UnpackNormal(tex2D(_BumpMap, IN.uv)); half3 normT; // normT.xy = ((2*IN.uv)-1); normT.xy = ((2*uv)-1); normT.z = sqrt(1 - saturate(dot(normT.xy, normT.xy))); //normT.xy = 2 * INV_PI*asin((2 * IN.uv) - 1) ; //normT.xy = sin(PI*(IN.uv-.5)); //normT.z = 1; //color.rg = IN.uv; color.a *= tex.a; tex.a = IN.viewDir.w*tex.a; #if (defined(SCATTERER_ON) && defined(SCATTERER_USE_ORIG_DIR_COLOR_ON)) _LightColor0.rgb = scattererOrigDirectionalColor; #endif color.rgb *= ScatterColorLight(IN.lightDirT, IN.viewDirT, normT, tex, _MinScatter, _Opacity, 1).rgb; //#ifdef SCATTERER_ON // // // //extinction of light from sun to cloud // float3 sunExtinction = getSkyExtinction(IN.relWorldPos,_Sun_WorldSunDir); // // //skyLight // float3 skyE = SimpleSkyirradiance(IN.relWorldPos, IN.viewDir.xyz, _Sun_WorldSunDir); // // color.rgb = hdrNoExposure(sunExtinction*color.rgb+IN.inScattering+skyE*cloudSkyIrradianceMultiplier); //color.rgb already has extinction to viewer and colorMultiplier pre-applied //#endif #ifdef SOFT_DEPTH_ON float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos))); depth = LinearEyeDepth (depth); float partZ = IN.projPos.z; float fade = saturate (_InvFade * (depth-partZ)); color.a *= fade; #endif // color.rgb = color.rgb + IN.inScattering * (1-color.rgb); //soft additive blending //maybe do if no hdr? return color; } ENDCG } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/CloudVolumeParticle.shader.meta ================================================ fileFormatVersion: 2 guid: a331c23f613bfba4294059442ab01d4e timeCreated: 1470912280 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/EVEUtils.cginc ================================================ #ifndef EVE_UTILS_CG_INCLUDED #define EVE_UTILS_CG_INCLUDED #include "UnityCG.cginc" #include "AutoLight.cginc" #include "Lighting.cginc" #define PI 3.1415926535897932384626 #define INV_PI (1.0/PI) #define TWOPI (2.0*PI) #define INV_2PI (1.0/TWOPI) #define SQRT_2 (1.41421356237) #pragma fragmentoption ARB_precision_hint_fastest #ifdef DIRLIGHT_ONLY #define DIRECTIONAL 1 #define SHADOWS_OFF 1 #define LIGHTMAP_OFF 1 #define DIRLIGHTMAP_OFF 1 #endif #pragma skip_variants DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE DYNAMICLIGHTMAP_ON LIGHTMAP_ON VERTEXLIGHT_ON uniform float4x4 _MainRotation; uniform float4x4 _DetailRotation; uniform float4x4 _ShadowBodies = float4x4 ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); float _SunRadius = 1; float3 _SunPos; float4 _UniversalTime; /*=========================================================================* * R A N D _ R O T A T I O N Author: Jim Arvo, 1991 * * * * This routine maps three values (x[0], x[1], x[2]) in the range [0,1] * * into a 3x3 rotation matrix, M. Uniformly distributed random variables * * x0, x1, and x2 create uniformly distributed random rotation matrices. * * To create small uniformly distributed "perturbations", supply * * samples in the following ranges * * * * x[0] in [ 0, d ] * * x[1] in [ 0, 1 ] * * x[2] in [ 0, d ] * * * * where 0 < d < 1 controls the size of the perturbation. Any of the * * random variables may be stratified (or "jittered") for a slightly more * * even distribution. * * * *=========================================================================*/ float4x4 rand_rotation(float3 x, float scale, float3 trans) { float theta = x[0] * TWOPI; /* Rotation about the pole (Z). */ float phi = x[1] * TWOPI; /* For direction of pole deflection. */ float z = x[2] * 2.0; /* For magnitude of pole deflection. */ /* Compute a vector V used for distributing points over the sphere */ /* via the reflection I - V Transpose(V). This formulation of V */ /* will guarantee that if x[1] and x[2] are uniformly distributed, */ /* the reflected points will be uniform on the sphere. Note that V */ /* has length sqrt(2) to eliminate the 2 in the Householder matrix. */ float r = sqrt(z); float Vx = sin(phi) * r; float Vy = cos(phi) * r; float Vz = sqrt(2.0 - z); /* Compute the row vector S = Transpose(V) * R, where R is a simple */ /* rotation by theta about the z-axis. No need to compute Sz since */ /* it's just Vz. */ float st = sin(theta); float ct = cos(theta); float Sx = Vx * ct - Vy * st; float Sy = Vx * st + Vy * ct; /* Construct the rotation matrix ( V Transpose(V) - I ) R, which */ /* is equivalent to V S - R. */ float4x4 M = float4x4( scale*(Vx * Sx - ct), Vy * Sx + st, Vz * Sx, trans.x, Vx * Sy - st, scale*(Vy * Sy - ct), Vz * Sy, trans.y, Vx * Vz, Vy * Vz, scale*(1.0 - z), trans.z, 0, 0, 0, 1); return M; } inline float3 hash( float3 val ) { return frac(sin(val)*1232.53); } inline float GetDistanceFade( float dist, float fade, float fadeVert ) { float fadeDist = fade*dist; float distVert = 1-(fadeVert*dist); return saturate(fadeDist) * saturate(distVert); } inline half4 GetLighting(half3 worldNorm, half3 lightDir, fixed atten, fixed ambient) { half3 ambientLighting = ambient * UNITY_LIGHTMODEL_AMBIENT; half NdotL = dot (worldNorm, lightDir); half lightIntensity = saturate(_LightColor0.a * NdotL * 2 * atten); half4 light; light.rgb = max(ambientLighting + (_LightColor0.rgb * lightIntensity), 0); light.a = max(ambientLighting + lightIntensity, 0); return light; } // Calculates Blinn-Phong (specular) lighting model inline half4 SpecularColorLight( half3 lightDir, half3 viewDir, half3 normal, half4 color, half4 specColor, float specK, half atten ) { lightDir = normalize(lightDir); viewDir = normalize(viewDir); normal = normalize(normal); half3 h = normalize( lightDir + viewDir ); half diffuse = dot( normal, lightDir ); float nh = saturate( dot( h, normal ) ); float spec = pow( nh, specK ) * specColor.a; half4 c; c.rgb = _LightColor0.rgb*((color.rgb * diffuse )+ (specColor.rgb * spec)) * (atten * 2); c.a = diffuse*(atten * 2);//_LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright return c; } inline half4 ScatterColorLight(half3 lightDir, half3 viewDir, half3 normal, half4 color, float min, float opacity, half atten) { lightDir = normalize(lightDir); viewDir = normalize(viewDir); normal = normalize(normal); half diffuse = max( dot(normal, lightDir),0); float h = .5+(.5*dot(viewDir, lightDir)); float scatter = (min-(opacity*color.a))*(1-(dot(normal,viewDir)))*h; scatter = saturate(scatter); half4 c; c.rgb = _LightColor0*((color.rgb * diffuse) + scatter) * (atten * 2); c.a = diffuse*(atten * 2);//_LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright return c; } inline half Terminator(half3 lightDir, half3 normal) { half NdotL = dot( normal, lightDir ); half termlerp = saturate(10*-NdotL); half terminator = lerp(1,saturate(floor(1.01+NdotL)), termlerp); return terminator; } inline half BodyShadow(float3 v, float R, float r, float3 P, float3 p) { float3 D = P - v; float a = PI*(r*r); float3 d = p - v; float tc = dot(d, normalize(D)); float tc2 = (tc*tc); float L = sqrt(dot(d, d) - tc2); float scale = tc / length(D); //Scaled Sun Area to match plane of intersecting body float Rs = R * scale; float A = PI*(Rs*Rs); float s = saturate((r + Rs - L) / (2 * min(r, Rs))); s = (INV_PI*asin((2 * s) - 1)) + .5; return lerp(1, saturate((A - (s*a)) / A), step(r, tc)*saturate(a)); } inline half MultiBodyShadow(float3 v, float R, float3 P, float4x4 m) { half a = BodyShadow(v, R, m[0].w, P, m[0].xyz); half b = BodyShadow(v, R, m[1].w, P, m[1].xyz); half c = BodyShadow(v, R, m[2].w, P, m[2].xyz); half d = BodyShadow(v, R, m[3].w, P, m[3].xyz); return min(min(a, b), min(c, d)); } #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/EVEUtils.cginc.meta ================================================ fileFormatVersion: 2 guid: e2392d942829c3b439a231d514e10321 timeCreated: 1470912310 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticle.shader ================================================ Shader "Scatterer-EVE/GeometryCloudVolumeParticle" { Properties { _Tex("Particle Texture", 2D) = "white" {} _MainTex("Main (RGB)", 2D) = "white" {} _PerlinTex("Perlin (RGB)", 2D) = "white" {} _BumpMap("Normalmap", 2D) = "bump" {} _DetailTex("Detail (RGB)", 2D) = "white" {} _DetailScale("Detail Scale", Range(0,1000)) = 100 _DistFade("Distance Fade Near", Float) = 1.0 _DistFadeVert("Distance Fade Vertical", Float) = 0.0004 _MinScatter("Min Scatter", Float) = 1.05 _Opacity("Opacity", Float) = 1.05 _Color("Color Tint", Color) = (1,1,1,1) _InvFade("Soft Particles Factor", Range(0,1.0)) = .008 _Rotation("Rotation", Float) = 0 _MaxScale("Max Scale", Float) = 1 _MaxTrans("Max Translation", Vector) = (0,0,0) _NoiseScale("Noise Scale", Vector) = (1,2,.0005,100) _SunPos("_SunPos", Vector) = (0,0,0) _SunRadius("_SunRadius", Float) = 1 } Category { Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True" } Blend SrcAlpha OneMinusSrcAlpha Fog { Mode Global} AlphaTest Greater 0 ColorMask RGB //Cull Back Cull Off Lighting On ZWrite Off SubShader { Pass { Lighting On Tags { "LightMode"="ForwardBase"} CGPROGRAM #include "EVEUtils.cginc" #pragma vertex vert #pragma fragment frag #pragma geometry geom #define MAG_ONE 1.4142135623730950488016887242097 #pragma fragmentoption ARB_precision_hint_fastest //#pragma multi_compile_fwdbase #pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON #pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1 #ifndef MAP_TYPE_CUBE2_1 #pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1 #endif #include "noiseSimplex.cginc" #include "alphaMap.cginc" #include "cubeMap.cginc" #pragma multi_compile SCATTERER_OFF SCATTERER_ON #pragma multi_compile SCATTERER_USE_ORIG_DIR_COLOR_OFF SCATTERER_USE_ORIG_DIR_COLOR_ON #ifdef SCATTERER_ON #include "../CommonAtmosphere.cginc" #endif CUBEMAP_DEF_1(_MainTex) sampler2D _Tex; sampler2D _DetailTex; sampler2D _BumpMap; float4x4 _PosRotation; float _DetailScale; fixed4 _Color; float _DistFade; float _DistFadeVert; float _MinScatter; float _Opacity; float _InvFade; float _Rotation; float _QuadSize; float _MaxScale; float4 _NoiseScale; float3 _MaxTrans; sampler2D _CameraDepthTexture; #ifdef SCATTERER_ON uniform float cloudColorMultiplier; uniform float cloudScatteringMultiplier; uniform float cloudSkyIrradianceMultiplier; uniform float3 _Sun_WorldSunDir; uniform float3 _PlanetWorldPos; uniform float3 scattererOrigDirectionalColor; #endif struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; struct v2g { float4 pos : SV_POSITION; fixed4 color : COLOR; float3 hashVect : TEXCOORD0; float4 localOrigin : TEXCOORD1; float4 origin : TEXCOORD2; float viewDirFade : TEXCOORD3; float3 planetPos : TEXCOORD4; float particleFade: TEXCOORD5; }; //vertex function, called for every point on our hexSeg, each vertex corresponding to the origin of a particle/quad v2g vert (appdata_t v) { v2g o; UNITY_INITIALIZE_OUTPUT(v2g, o); v.vertex.xyz/=v.vertex.w; float4 origin = mul(unity_ObjectToWorld, v.vertex); //origin of the quad in worldSpace float4 planet_pos = mul(_PosRotation, origin); float3 normalized = _NoiseScale.z*(planet_pos.xyz); float3 hashVect = .5*(float3(snoise(normalized), snoise(_NoiseScale.x*normalized), snoise(_NoiseScale.y*normalized))+1); //unique hash of the particle based on planet pos o.hashVect = hashVect; float4 localOrigin; localOrigin.xyz = (2*hashVect-1)*_MaxTrans; //offset to localOrigin based on hash above localOrigin.w = 1; //localOrigin.xyz+=v.vertex.xyz; //here this is wrong, in the original shader, local origin is added to the quad in it's space and gets transformed with it'w own M matrix with no issues //here as we add this to the space of the hex, transforming later with M matrix can cause additional rotation, we can add this in worldSpace instead origin.xyz+=localOrigin; //the particle transforms are originally oriented same as in world space, therefore we can do this offset directly in worldSpace in our case o.origin = origin; localOrigin = mul (unity_WorldToObject, origin); //transform back to find the new localOrigin o.localOrigin = localOrigin; planet_pos = mul(_MainRotation, origin); //new planet pos based on offset origin o.planetPos = planet_pos.xyz; float3 detail_pos = mul(_DetailRotation, planet_pos).xyz; o.color = VERT_GET_NO_LOD_CUBE_MAP_1(_MainTex, planet_pos.xyz); o.color.rgba *= GetCubeDetailMapNoLOD(_DetailTex, detail_pos, _DetailScale); o.viewDirFade = GetDistanceFade(distance(origin, _WorldSpaceCameraPos), _DistFade, _DistFadeVert); o.color.a *= o.viewDirFade; float4 mvCenter = mul(UNITY_MATRIX_MV, float4(localOrigin.xyz,1.0)); //offset quad origin in viewspace o.pos=mvCenter; o.pos = o.color.a > (1.0/255.0) ? o.pos : float4(2.0, 2.0, 2.0, 1.0); //cull vertex if low alpha, pos outside clipspace float fadeOut = (-mvCenter.z/mvCenter.w) * 0.004; o.particleFade = smoothstep(0.0,1.0,fadeOut); #ifdef SCATTERER_ON float3 worldPos = origin; float3 extinction = float3(0, 0, 0); float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space // float3 worigin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz; float3 worigin = _PlanetWorldPos; float3 relWorldPos=worldPos-worigin; float3 relCameraPos=WCP-worigin; //relWorldPos=lerp(Rg*normalize(relWorldPos),relWorldPos,cloudExtinctionHeightMultiplier); //extinction of light from sun to cloud float3 sunExtinction = getSkyExtinction(relWorldPos,_Sun_WorldSunDir); //extinction from cloud to observer extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction; // //skyLight // float3 skyE = SimpleSkyirradiance(relWorldPos, viewDir.xyz, _Sun_WorldSunDir); // // o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction + skyE*cloudSkyIrradianceMultiplier; // o.relWorldPos = relWorldPos; // //inScattering from cloud to observer // float3 inscatter = InScattering2(relCameraPos, relWorldPos, extinction, _Sun_WorldSunDir, 1.0, 1.0, 1.0); // o.inScattering = inscatter * cloudScatteringMultiplier; // // //extinction from cloud to observer // extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); // // o.color.rgb *= cloudColorMultiplier * extinction; #endif return o; } struct g2f { float4 pos : SV_POSITION; fixed4 color : COLOR; half4 viewDir : TEXCOORD0; float2 texcoordZY : TEXCOORD1; float2 texcoordXZ : TEXCOORD2; float2 texcoordXY : TEXCOORD3; float3 uv : TEXCOORD4; //x and y UVs, z is particleFade float4 projPos : TEXCOORD5; float3 planetPos : TEXCOORD6; float3 viewDirT : TEXCOORD7; float3 lightDirT : TEXCOORD8; float4 localOrigin : TEXCOORD9; }; //this function builds a quad corner vertex from the data passed to it, it will be called by the geometry shader g2f buildQuadVertex(v2g originPoint, float3 vertexPosition, float2 vertexUV, float3 viewDir, float4x4 mvMatrix, float localScale) { g2f tri; UNITY_INITIALIZE_OUTPUT(g2f, tri); float3 mvCenter = originPoint.pos.xyz/originPoint.pos.w; tri.pos = float4(mvCenter + _QuadSize * localScale * vertexPosition,1.0); //position in view space of quad corner #ifdef SOFT_DEPTH_ON float eyedepth = -tri.pos.z; #endif tri.pos = mul (UNITY_MATRIX_P, tri.pos); #ifdef SOFT_DEPTH_ON tri.projPos = ComputeScreenPos (tri.pos); //COMPUTE_EYEDEPTH(tri.projPos.z); //we replace COMPUTE_EYEDEPTH with it's definition as it's only designed for the vertex shader input //tri.projPos.z = -UnityObjectToViewPos( v.vertex ).z tri.projPos.z = eyedepth; #endif //pass these values we need for the fragment shader tri.viewDir.xyz = abs(viewDir).xyz; tri.viewDir.w = originPoint.viewDirFade; tri.planetPos = originPoint.planetPos; tri.color = originPoint.color; float2 texcoodOffsetxy = ((2*vertexUV)- 1); float4 texcoordOffset = float4(texcoodOffsetxy.x, texcoodOffsetxy.y, 0, 1.0); //would 1.0 work here???? let's find out float4 ZYv = texcoordOffset.zyxw; float4 XZv = texcoordOffset.xzyw; float4 XYv = texcoordOffset.xyzw; ZYv.z*=sign(-viewDir.x); XZv.x*=sign(-viewDir.y); XYv.x*=sign(viewDir.z); ZYv.x += sign(-viewDir.x)*sign(ZYv.z)*(viewDir.z); XZv.y += sign(-viewDir.y)*sign(XZv.x)*(viewDir.x); XYv.z += sign(-viewDir.z)*sign(XYv.x)*(viewDir.x); ZYv.x += sign(-viewDir.x)*sign(ZYv.y)*(viewDir.y); XZv.y += sign(-viewDir.y)*sign(XZv.z)*(viewDir.z); XYv.z += sign(-viewDir.z)*sign(XYv.y)*(viewDir.y); float2 ZY = mul(mvMatrix, ZYv).xy - mvCenter.xy; float2 XZ = mul(mvMatrix, XZv).xy - mvCenter.xy; float2 XY = mul(mvMatrix, XYv).xy - mvCenter.xy; tri.texcoordZY = half2(.5 ,.5) + .6*(ZY); tri.texcoordXZ = half2(.5 ,.5) + .6*(XZ); tri.texcoordXY = half2(.5 ,.5) + .6*(XY); viewDir = normalize(originPoint.origin - _WorldSpaceCameraPos); //worldSpaceView dir to center of quad not to fragment, why? maybe to frag would be better? half3 normal = normalize(-viewDir); float3 tangent = UNITY_MATRIX_V[0].xyz; float3 binormal = -cross(normal, normalize(tangent)); float3x3 rotation = float3x3(tangent.xyz, binormal, normal); tri.lightDirT = normalize(mul(rotation, _WorldSpaceLightPos0.xyz)); tri.viewDirT = normalize(mul(rotation, viewDir)); tri.uv = float3(vertexUV, originPoint.particleFade); //x and y quad UV, z particleFade tri.localOrigin = originPoint.localOrigin; return tri; } //geometry shader //for every vertex from the vertex shader it will create a particle quad of 4 vertexes and 2 triangles [maxvertexcount(4)] void geom(point v2g input[1], inout TriangleStream outStream) { g2f tri; //common values for all the quad float localScale = (input[0].hashVect.x*(_MaxScale - 1)) + 1; float4x4 M = rand_rotation( (float3(frac(_Rotation),0,0))+input[0].hashVect, localScale, input[0].localOrigin.xyz/input[0].localOrigin.w); float4x4 mvMatrix = mul(mul(UNITY_MATRIX_V, unity_ObjectToWorld), M); float3 viewDir = normalize(mvMatrix[2].xyz); //cameraSpace viewDir I think //build our quad tri = buildQuadVertex(input[0],float3(-0.5,-0.5,0.0),float2(0.0,0.0),viewDir,mvMatrix,localScale); outStream.Append(tri); tri = buildQuadVertex(input[0],float3(-0.5,0.5,0.0),float2(0.0,1.0),viewDir,mvMatrix,localScale); outStream.Append(tri); tri = buildQuadVertex(input[0],float3(0.5,-0.5,0.0),float2(1.0,0.0),viewDir,mvMatrix,localScale); outStream.Append(tri); tri = buildQuadVertex(input[0],float3(0.5,0.5,0.0),float2(1.0,1.0),viewDir,mvMatrix,localScale); outStream.Append(tri); outStream.RestartStrip(); } float4 frag (g2f IN) : COLOR { half4 tex; tex.r = tex2D(_Tex, IN.texcoordZY).r; tex.g = tex2D(_Tex, IN.texcoordXZ).g; tex.b = tex2D(_Tex, IN.texcoordXY).b; tex.a = 0; tex.rgb *= IN.viewDir.rgb; half4 vect = half4( IN.viewDir.rgb, 0); tex /= vectorSum(vect); tex = half4(1, 1, 1, vectorSum(tex)); half4 color = FRAG_GET_NO_LOD_CUBE_MAP_1(_MainTex, IN.planetPos); color = ALPHA_COLOR_1(color); color *= _Color * IN.color; //half3 normT = UnpackNormal(tex2D(_BumpMap, IN.uv)); half3 normT; normT.xy = ((2*IN.uv.xy)-1); normT.z = sqrt(1 - saturate(dot(normT.xy, normT.xy))); //normT.xy = 2 * INV_PI*asin((2 * IN.uv) - 1) ; //normT.xy = sin(PI*(IN.uv-.5)); //normT.z = 1; //color.rg = IN.uv; color.a *= tex.a; tex.a = IN.viewDir.w*tex.a; #if (defined(SCATTERER_ON) && defined(SCATTERER_USE_ORIG_DIR_COLOR_ON)) _LightColor0.rgb = scattererOrigDirectionalColor; #endif color.rgb *= ScatterColorLight(IN.lightDirT, IN.viewDirT, normT, tex, _MinScatter, _Opacity, 1).rgb; #ifdef SOFT_DEPTH_ON float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos))); depth = LinearEyeDepth (depth); float partZ = IN.projPos.z; float fade = depth >= (0.99 * _ProjectionParams.z) ? 1.0 : saturate (_InvFade * (depth-partZ)); //fade near objects but don't fade on far plane (max depth value) color.a *= fade; #endif color.a *= IN.uv.z; //particle fade as they approach camera return color; } ENDCG } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticle.shader.meta ================================================ fileFormatVersion: 2 guid: 99744ed686e28004180091658ee4f5ae ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticleToTexture.shader ================================================ Shader "Scatterer-EVE/GeometryCloudVolumeParticleToTexture" { Properties { _Tex("Particle Texture", 2D) = "white" {} _MainTex("Main (RGB)", 2D) = "white" {} _PerlinTex("Perlin (RGB)", 2D) = "white" {} _BumpMap("Normalmap", 2D) = "bump" {} _DetailTex("Detail (RGB)", 2D) = "white" {} _DetailScale("Detail Scale", Range(0,1000)) = 100 _DistFade("Distance Fade Near", Float) = 1.0 _DistFadeVert("Distance Fade Vertical", Float) = 0.0004 _MinScatter("Min Scatter", Float) = 1.05 _Opacity("Opacity", Float) = 1.05 _Color("Color Tint", Color) = (1,1,1,1) _InvFade("Soft Particles Factor", Range(0,1.0)) = .008 _Rotation("Rotation", Float) = 0 _MaxScale("Max Scale", Float) = 1 _MaxTrans("Max Translation", Vector) = (0,0,0) _NoiseScale("Noise Scale", Vector) = (1,2,.0005,100) _SunPos("_SunPos", Vector) = (0,0,0) _SunRadius("_SunRadius", Float) = 1 } Category { Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True" } Blend SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha //traditional alpha blending for colors, multiply by (1-alpha) for alpha to store in texture Fog { Mode Global} AlphaTest Greater 0 ColorMask RGBA //Cull Back Cull Off Lighting On ZWrite Off SubShader { Pass { Lighting On Tags { "LightMode"="ForwardBase"} CGPROGRAM #include "EVEUtils.cginc" #pragma vertex vert #pragma fragment frag #pragma geometry geom #define MAG_ONE 1.4142135623730950488016887242097 #pragma fragmentoption ARB_precision_hint_fastest //#pragma multi_compile_fwdbase #pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON #pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1 #ifndef MAP_TYPE_CUBE2_1 #pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1 #endif #include "noiseSimplex.cginc" #include "alphaMap.cginc" #include "cubeMap.cginc" #pragma multi_compile SCATTERER_OFF SCATTERER_ON #pragma multi_compile SCATTERER_USE_ORIG_DIR_COLOR_OFF SCATTERER_USE_ORIG_DIR_COLOR_ON #ifdef SCATTERER_ON #include "../CommonAtmosphere.cginc" #endif CUBEMAP_DEF_1(_MainTex) sampler2D _Tex; sampler2D _DetailTex; sampler2D _BumpMap; float4x4 _PosRotation; float _DetailScale; fixed4 _Color; float _DistFade; float _DistFadeVert; float _MinScatter; float _Opacity; float _InvFade; float _Rotation; float _QuadSize; float _MaxScale; float4 _NoiseScale; float3 _MaxTrans; sampler2D EVEDownscaledDepth; #ifdef SCATTERER_ON uniform float cloudColorMultiplier; uniform float cloudScatteringMultiplier; uniform float cloudSkyIrradianceMultiplier; uniform float3 _Sun_WorldSunDir; uniform float3 _PlanetWorldPos; uniform float3 scattererOrigDirectionalColor; #endif struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; struct v2g { float4 pos : SV_POSITION; fixed4 color : COLOR; float3 hashVect : TEXCOORD0; float4 localOrigin : TEXCOORD1; float4 origin : TEXCOORD2; float viewDirFade : TEXCOORD3; float3 planetPos : TEXCOORD4; float particleFade: TEXCOORD5; }; //vertex function, called for every point on our hexSeg, each vertex corresponding to the origin of a particle/quad v2g vert (appdata_t v) { v2g o; UNITY_INITIALIZE_OUTPUT(v2g, o); v.vertex.xyz/=v.vertex.w; float4 origin = mul(unity_ObjectToWorld, v.vertex); //origin of the quad in worldSpace float4 planet_pos = mul(_PosRotation, origin); float3 normalized = _NoiseScale.z*(planet_pos.xyz); float3 hashVect = .5*(float3(snoise(normalized), snoise(_NoiseScale.x*normalized), snoise(_NoiseScale.y*normalized))+1); //unique hash of the particle based on planet pos o.hashVect = hashVect; float4 localOrigin; localOrigin.xyz = (2*hashVect-1)*_MaxTrans; //offset to localOrigin based on hash above localOrigin.w = 1; //localOrigin.xyz+=v.vertex.xyz; //here this is wrong, in the original shader, local origin is added to the quad in it's space and gets transformed with it'w own M matrix with no issues //here as we add this to the space of the hex, transforming later with M matrix can cause additional rotation, we can add this in worldSpace instead origin.xyz+=localOrigin; //the particle transforms are originally oriented same as in world space, therefore we can do this offset directly in worldSpace in our case o.origin = origin; localOrigin = mul (unity_WorldToObject, origin); //transform back to find the new localOrigin o.localOrigin = localOrigin; planet_pos = mul(_MainRotation, origin); //new planet pos based on offset origin o.planetPos = planet_pos.xyz; float3 detail_pos = mul(_DetailRotation, planet_pos).xyz; o.color = VERT_GET_NO_LOD_CUBE_MAP_1(_MainTex, planet_pos.xyz); o.color.rgba *= GetCubeDetailMapNoLOD(_DetailTex, detail_pos, _DetailScale); o.viewDirFade = GetDistanceFade(distance(origin, _WorldSpaceCameraPos), _DistFade, _DistFadeVert); o.color.a *= o.viewDirFade; float4 mvCenter = mul(UNITY_MATRIX_MV, float4(localOrigin.xyz,1.0)); //offset quad origin in viewspace o.pos=mvCenter; o.pos = o.color.a > (1.0/255.0) ? o.pos : float4(2.0, 2.0, 2.0, 1.0); //cull vertex if low alpha, pos outside clipspace float fadeOut = (-mvCenter.z/mvCenter.w) * 0.004; o.particleFade = smoothstep(0.0,1.0,fadeOut); #ifdef SCATTERER_ON float3 worldPos = origin; float3 extinction = float3(0, 0, 0); float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space // float3 worigin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz; float3 worigin = _PlanetWorldPos; float3 relWorldPos=worldPos-worigin; float3 relCameraPos=WCP-worigin; //relWorldPos=lerp(Rg*normalize(relWorldPos),relWorldPos,cloudExtinctionHeightMultiplier); //extinction of light from sun to cloud float3 sunExtinction = getSkyExtinction(relWorldPos,_Sun_WorldSunDir); //extinction from cloud to observer extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction; // //skyLight // float3 skyE = SimpleSkyirradiance(relWorldPos, viewDir.xyz, _Sun_WorldSunDir); // // o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction + skyE*cloudSkyIrradianceMultiplier; // o.relWorldPos = relWorldPos; // //inScattering from cloud to observer // float3 inscatter = InScattering2(relCameraPos, relWorldPos, extinction, _Sun_WorldSunDir, 1.0, 1.0, 1.0); // o.inScattering = inscatter * cloudScatteringMultiplier; // // //extinction from cloud to observer // extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); // // o.color.rgb *= cloudColorMultiplier * extinction; #endif return o; } struct g2f { float4 pos : SV_POSITION; fixed4 color : COLOR; half4 viewDir : TEXCOORD0; float2 texcoordZY : TEXCOORD1; float2 texcoordXZ : TEXCOORD2; float2 texcoordXY : TEXCOORD3; float3 uv : TEXCOORD4; //x and y UVs, z is particleFade float4 projPos : TEXCOORD5; float3 planetPos : TEXCOORD6; float3 viewDirT : TEXCOORD7; float3 lightDirT : TEXCOORD8; float4 localOrigin : TEXCOORD9; }; //this function builds a quad corner vertex from the data passed to it, it will be called by the geometry shader g2f buildQuadVertex(v2g originPoint, float3 vertexPosition, float2 vertexUV, float3 viewDir, float4x4 mvMatrix, float localScale) { g2f tri; UNITY_INITIALIZE_OUTPUT(g2f, tri); float3 mvCenter = originPoint.pos.xyz/originPoint.pos.w; tri.pos = float4(mvCenter + _QuadSize * localScale * vertexPosition,1.0); //position in view space of quad corner #ifdef SOFT_DEPTH_ON float eyedepth = -tri.pos.z; #endif tri.pos = mul (UNITY_MATRIX_P, tri.pos); #ifdef SOFT_DEPTH_ON tri.projPos = ComputeScreenPos (tri.pos); //COMPUTE_EYEDEPTH(tri.projPos.z); //we replace COMPUTE_EYEDEPTH with it's definition as it's only designed for the vertex shader input //tri.projPos.z = -UnityObjectToViewPos( v.vertex ).z tri.projPos.z = eyedepth; #endif //pass these values we need for the fragment shader tri.viewDir.xyz = abs(viewDir).xyz; tri.viewDir.w = originPoint.viewDirFade; tri.planetPos = originPoint.planetPos; tri.color = originPoint.color; float2 texcoodOffsetxy = ((2*vertexUV)- 1); float4 texcoordOffset = float4(texcoodOffsetxy.x, texcoodOffsetxy.y, 0, 1.0); //would 1.0 work here???? let's find out float4 ZYv = texcoordOffset.zyxw; float4 XZv = texcoordOffset.xzyw; float4 XYv = texcoordOffset.xyzw; ZYv.z*=sign(-viewDir.x); XZv.x*=sign(-viewDir.y); XYv.x*=sign(viewDir.z); ZYv.x += sign(-viewDir.x)*sign(ZYv.z)*(viewDir.z); XZv.y += sign(-viewDir.y)*sign(XZv.x)*(viewDir.x); XYv.z += sign(-viewDir.z)*sign(XYv.x)*(viewDir.x); ZYv.x += sign(-viewDir.x)*sign(ZYv.y)*(viewDir.y); XZv.y += sign(-viewDir.y)*sign(XZv.z)*(viewDir.z); XYv.z += sign(-viewDir.z)*sign(XYv.y)*(viewDir.y); float2 ZY = mul(mvMatrix, ZYv).xy - mvCenter.xy; float2 XZ = mul(mvMatrix, XZv).xy - mvCenter.xy; float2 XY = mul(mvMatrix, XYv).xy - mvCenter.xy; tri.texcoordZY = half2(.5 ,.5) + .6*(ZY); tri.texcoordXZ = half2(.5 ,.5) + .6*(XZ); tri.texcoordXY = half2(.5 ,.5) + .6*(XY); viewDir = normalize(originPoint.origin - _WorldSpaceCameraPos); //worldSpaceView dir to center of quad not to fragment, why? maybe to frag would be better? half3 normal = normalize(-viewDir); float3 tangent = UNITY_MATRIX_V[0].xyz; float3 binormal = -cross(normal, normalize(tangent)); float3x3 rotation = float3x3(tangent.xyz, binormal, normal); tri.lightDirT = normalize(mul(rotation, _WorldSpaceLightPos0.xyz)); tri.viewDirT = normalize(mul(rotation, viewDir)); tri.uv = float3(vertexUV, originPoint.particleFade); //x and y quad UV, z particleFade tri.localOrigin = originPoint.localOrigin; return tri; } //geometry shader //for every vertex from the vertex shader it will create a particle quad of 4 vertexes and 2 triangles [maxvertexcount(4)] void geom(point v2g input[1], inout TriangleStream outStream) { g2f tri; //common values for all the quad float localScale = (input[0].hashVect.x*(_MaxScale - 1)) + 1; float4x4 M = rand_rotation( (float3(frac(_Rotation),0,0))+input[0].hashVect, localScale, input[0].localOrigin.xyz/input[0].localOrigin.w); float4x4 mvMatrix = mul(mul(UNITY_MATRIX_V, unity_ObjectToWorld), M); float3 viewDir = normalize(mvMatrix[2].xyz); //cameraSpace viewDir I think //build our quad tri = buildQuadVertex(input[0],float3(-0.5,-0.5,0.0),float2(0.0,0.0),viewDir,mvMatrix,localScale); outStream.Append(tri); tri = buildQuadVertex(input[0],float3(-0.5,0.5,0.0),float2(0.0,1.0),viewDir,mvMatrix,localScale); outStream.Append(tri); tri = buildQuadVertex(input[0],float3(0.5,-0.5,0.0),float2(1.0,0.0),viewDir,mvMatrix,localScale); outStream.Append(tri); tri = buildQuadVertex(input[0],float3(0.5,0.5,0.0),float2(1.0,1.0),viewDir,mvMatrix,localScale); outStream.Append(tri); outStream.RestartStrip(); } float4 frag (g2f IN) : COLOR { half4 tex; tex.r = tex2D(_Tex, IN.texcoordZY).r; tex.g = tex2D(_Tex, IN.texcoordXZ).g; tex.b = tex2D(_Tex, IN.texcoordXY).b; tex.a = 0; tex.rgb *= IN.viewDir.rgb; half4 vect = half4( IN.viewDir.rgb, 0); tex /= vectorSum(vect); tex = half4(1, 1, 1, vectorSum(tex)); half4 color = FRAG_GET_NO_LOD_CUBE_MAP_1(_MainTex, IN.planetPos); color = ALPHA_COLOR_1(color); color *= _Color * IN.color; color.a *= tex.a; tex.a = IN.viewDir.w*tex.a; //half3 normT = UnpackNormal(tex2D(_BumpMap, IN.uv)); half3 normT; normT.xy = ((2*IN.uv.xy)-1); normT.z = sqrt(1 - saturate(dot(normT.xy, normT.xy))); //normT.xy = 2 * INV_PI*asin((2 * IN.uv) - 1) ; //normT.xy = sin(PI*(IN.uv-.5)); //normT.z = 1; //color.rg = IN.uv; #if (defined(SCATTERER_ON) && defined(SCATTERER_USE_ORIG_DIR_COLOR_ON)) _LightColor0.rgb = scattererOrigDirectionalColor; #endif color.rgb *= ScatterColorLight(IN.lightDirT, IN.viewDirT, normT, tex, _MinScatter, _Opacity, 1).rgb; #ifdef SOFT_DEPTH_ON float depth = UNITY_SAMPLE_DEPTH(tex2Dlod(EVEDownscaledDepth, float4(IN.projPos.xy/IN.projPos.w,0.0,0.0))); //to be sure we are reading a single point/using point filtering depth = LinearEyeDepth (depth); float partZ = IN.projPos.z; float fade = depth >= (0.99 * _ProjectionParams.z) ? 1.0 : saturate (_InvFade * (depth-partZ)); //fade near objects but don't fade on far plane (max depth value) color.a *= fade; #endif color.a *= IN.uv.z; //particle fade as they approach camera return color; } ENDCG } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticleToTexture.shader.meta ================================================ fileFormatVersion: 2 guid: 1bbfba4363c8e1e4b8214b4004316ce5 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloud.shader ================================================ Shader "Scatterer-EVE/Cloud" { Properties{ _Color("Color Tint", Color) = (1,1,1,1) _MainTex("Main (RGB)", 2D) = "white" {} _DetailTex("Detail (RGB)", 2D) = "white" {} _UVNoiseTex("UV Noise (RG)", 2D) = "black" {} _FalloffPow("Falloff Power", Range(0,3)) = 2 _FalloffScale("Falloff Scale", Range(0,20)) = 3 _DetailScale("Detail Scale", Range(0,100)) = 100 _DetailDist("Detail Distance", Range(0,1)) = 0.00875 _UVNoiseScale("UV Noise Scale", Range(0,0.1)) = 0.01 _UVNoiseStrength("UV Noise Strength", Range(0,0.1)) = 0.002 _UVNoiseAnimation("UV Noise Animation", Vector) = (0.002,0.001,0) _UniversalTime("Universal Time", Vector) = (0,0,0,0) _MinLight("Minimum Light", Range(0,1)) = 0 _DistFade("Fade Distance", Range(0,100)) = 10 _DistFadeVert("Fade Scale", Range(0,1)) = .002 _RimDist("Rim Distance", Range(0,1)) = 1 _RimDistSub("Rim Distance Sub", Range(0,2)) = 1.01 _InvFade("Soft Particles Factor", Range(0.01,3.0)) = .01 _OceanRadius("Ocean Radius", Float) = 63000 _PlanetOrigin("Sphere Center", Vector) = (0,0,0,1) _DepthPull("Depth Augment", Float) = .99 _SunPos("_SunPos", Vector) = (0,0,0) _SunRadius("_SunRadius", Float) = 1 } Category{ Tags { "Queue" = "Transparent-2" "IgnoreProjector" = "True" "RenderType" = "Transparent" } Blend SrcAlpha OneMinusSrcAlpha //Fog { Mode Global} //AlphaTest Greater 0 //ColorMask RGB Cull Off ZWrite Off Lighting On SubShader { Pass { Lighting On Tags { "LightMode" = "ForwardBase"} CGPROGRAM #include "EVEUtils.cginc" #pragma target 3.0 #pragma glsl #pragma vertex vert #pragma fragment frag #define MAG_ONE 1.4142135623730950488016887242097 #pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON #pragma multi_compile WORLD_SPACE_OFF WORLD_SPACE_ON #pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1 #pragma multi_compile SCATTERER_OFF SCATTERER_ON #ifdef SCATTERER_ON #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON #pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON #pragma multi_compile PRESERVECLOUDCOLORS_OFF PRESERVECLOUDCOLORS_ON //#pragma multi_compile GODRAYS_OFF GODRAYS_ON #define GODRAYS_OFF #endif #ifndef MAP_TYPE_CUBE2_1 #pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1 #endif #include "alphaMap.cginc" #include "cubeMap.cginc" #ifdef SCATTERER_ON #include "../CommonAtmosphere.cginc" #include "../EclipseCommon.cginc" #include "../Atmo/Godrays/GodraysCommon.cginc" #include "../RingCommon.cginc" #endif CUBEMAP_DEF_1(_MainTex) sampler2D _DetailTex; sampler2D _UVNoiseTex; fixed4 _Color; float _FalloffPow; float _FalloffScale; float _DetailScale; float _DetailDist; float _UVNoiseScale; float _UVNoiseStrength; float2 _UVNoiseAnimation; float _MinLight; float _DistFade; float _DistFadeVert; float _RimDist; float _RimDistSub; float _OceanRadius; float _InvFade; float3 _PlanetOrigin; sampler2D _CameraDepthTexture; float _DepthPull; #if defined (SCATTERER_ON) uniform float cloudColorMultiplier; uniform float cloudScatteringMultiplier; uniform float cloudSkyIrradianceMultiplier; uniform float3 _Sun_WorldSunDir; uniform float extinctionThickness; float _Radius; #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif #endif struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; float3 worldVert : TEXCOORD0; float3 L : TEXCOORD1; float4 objDetail : TEXCOORD2; float4 objMain : TEXCOORD3; float3 worldNormal : TEXCOORD4; float3 viewDir : TEXCOORD5; LIGHTING_COORDS(6,7) float4 projPos : TEXCOORD8; #if defined (SCATTERER_ON) float3 worldOrigin: TEXCOORD9; #endif }; v2f vert(appdata_t v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); o.pos = UnityObjectToClipPos(v.vertex); float4 vertexPos = mul(unity_ObjectToWorld, v.vertex); float3 origin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz; o.worldVert = vertexPos; o.worldNormal = normalize(vertexPos - origin); o.objMain = mul(_MainRotation, v.vertex); o.objDetail = mul(_DetailRotation, o.objMain); o.viewDir = normalize(WorldSpaceViewDir(v.vertex)); o.projPos = ComputeScreenPos(o.pos); COMPUTE_EYEDEPTH(o.projPos.z); TRANSFER_VERTEX_TO_FRAGMENT(o); o.L = _PlanetOrigin - _WorldSpaceCameraPos.xyz; #if defined (SCATTERER_ON) o.worldOrigin = origin; #endif return o; } struct fout { float4 color : COLOR; #if !(SHADER_API_D3D11 && WORLD_SPACE_ON) float depth : DEPTH; #endif }; fout frag(v2f IN) { fout OUT; float4 color; float4 main; main = GET_CUBE_MAP_P(_MainTex, IN.objMain.xyz, _UVNoiseTex, _UVNoiseScale, _UVNoiseStrength, _UVNoiseAnimation); main = ALPHA_COLOR_1(main); float4 detail = GetCubeDetailMap(_DetailTex, IN.objDetail, _DetailScale); float viewDist = distance(IN.worldVert,_WorldSpaceCameraPos); half detailLevel = saturate(2 * _DetailDist*viewDist); color = _Color * main.rgba * lerp(detail.rgba, 1, detailLevel); float rim = saturate(abs(dot(IN.viewDir, IN.worldNormal))); rim = saturate(pow(_FalloffScale*rim,_FalloffPow)); float dist = distance(IN.worldVert,_WorldSpaceCameraPos); float distLerp = saturate(_RimDist*(distance(_PlanetOrigin,_WorldSpaceCameraPos) - _RimDistSub*distance(IN.worldVert,_PlanetOrigin))); float distFade = 1 - GetDistanceFade(dist, _DistFade, _DistFadeVert); float distAlpha = lerp(distFade, rim, distLerp); color.a = lerp(0, color.a, distAlpha); #ifdef WORLD_SPACE_ON float3 worldDir = normalize(IN.worldVert - _WorldSpaceCameraPos.xyz); float tc = dot(IN.L, worldDir); float d = sqrt(dot(IN.L,IN.L) - (tc*tc)); float3 norm = normalize(-IN.L); float d2 = pow(d,2); float td = sqrt(dot(IN.L,IN.L) - d2); float tlc = sqrt((_OceanRadius*_OceanRadius) - d2); half sphereCheck = saturate(step(d, _OceanRadius)*step(0.0, tc) + step(length(IN.L), _OceanRadius)); float sphereDist = lerp(tlc - td, tc - tlc, step(0.0, tc)); sphereCheck *= step(sphereDist, dist); color.a *= 1 - sphereCheck; #endif ////////////////////////////SCATTERER OFF #if !defined (SCATTERER_ON) //lighting half transparency = color.a; float4 scolor = SpecularColorLight(_WorldSpaceLightPos0, IN.viewDir, IN.worldNormal, color, 0, 0, LIGHT_ATTENUATION(IN)); scolor *= Terminator(normalize(_WorldSpaceLightPos0), IN.worldNormal); scolor.a = transparency; #ifdef SOFT_DEPTH_ON float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos))); depth = LinearEyeDepth(depth); float partZ = IN.projPos.z; float fade = saturate(_InvFade * (depth - partZ)); scolor.a *= fade; #endif //scolor.rgb *= MultiBodyShadow(IN.worldVert, _SunRadius, _SunPos, _ShadowBodies); //causes artifacts idk why OUT.color = lerp(scolor, color, _MinLight); ////////////////////////////SCATTERER ON #else float4 texColor = color; float3 extinction = float3(0, 0, 0); #ifdef WORLD_SPACE_ON float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space float3 worldPos = IN.worldVert; float3 worldOrigin = IN.worldOrigin; #else float3 WCP = _WorldSpaceCameraPos * 6000; //unity supplied, converted from ScaledSpace to localSpace coords float3 worldPos = IN.worldVert * 6000; float3 worldOrigin = IN.worldOrigin * 6000; #endif float3 relWorldPos=worldPos-worldOrigin; relWorldPos = _Radius * normalize(relWorldPos); float alt = length(relWorldPos); float threshold = Rg * 1.00333333; relWorldPos = (alt < threshold) ? normalize(relWorldPos) * (threshold) : relWorldPos; //artifacts fix (black scattering and overbright skyirradiance) when cloud altitude < Rg *( 1 + 2000/600000) float3 relCameraPos=WCP-worldOrigin; float3 scatteringPos = relWorldPos; #if defined (GODRAYS_ON) && defined(WORLD_SPACE_ON) float2 depthUV = IN.projPos.xy/IN.projPos.w; float godrayDepth = sampleGodrayDepth(_godrayDepthTexture, depthUV, _godrayStrength); godrayDepth = min(godrayDepth, _godrayStrength * length(scatteringPos - relCameraPos)); scatteringPos -= godrayDepth * IN.viewDir; //this works but it looks suuuper wrong when outside the cloud layer, to be revised I guess #endif //inScattering from cloud to observer float3 inscatter = InScattering2(relCameraPos, scatteringPos, _Sun_WorldSunDir,extinction); //extinction from cloud to observer extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0); //extinction of light from sun to cloud extinction *= getSkyExtinction(relWorldPos,_Sun_WorldSunDir); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); extinction*= getEclipseShadow(relWorldPos, 20.0 * _Sun_WorldSunDir * Rg, 0.0, Rg, Rg); //just the terminator, extinction ignores ground intersection //skyLight float3 skyE = SimpleSkyirradiance(relWorldPos, IN.viewDir, _Sun_WorldSunDir); #if defined (PRESERVECLOUDCOLORS_OFF) color = float4(hdrNoExposure(color.rgb*cloudColorMultiplier*extinction+ inscatter*cloudScatteringMultiplier+skyE*cloudSkyIrradianceMultiplier), color.a); //not bad #else float3 cloudColor = color.rgb*cloudColorMultiplier*(extinction+hdrNoExposure(skyE * cloudSkyIrradianceMultiplier)); inscatter = hdrNoExposure(inscatter * cloudScatteringMultiplier); color = float4(cloudColor + (float3(1.0,1.0,1.0)-cloudColor)*inscatter, color.a); //basically soft blend #endif #if defined (ECLIPSES_ON) color.rgb*=getEclipseShadows(worldPos); #endif #if defined (RINGSHADOW_ON) color.rgb *= getLinearRingColor(relWorldPos, _Sun_WorldSunDir, 0.0).a; #endif OUT.color = lerp(color, texColor, _MinLight); #endif //endif SCATTERER_ON float depthWithOffset = IN.projPos.z; #ifndef WORLD_SPACE_ON depthWithOffset *= _DepthPull; OUT.color.a *= step(0, dot(IN.viewDir, IN.worldNormal)); #endif #if !(SHADER_API_D3D11 && WORLD_SPACE_ON) //fixes clouds fading into the planet when zooming out OUT.depth = (1.0 - depthWithOffset * _ZBufferParams.w) / (depthWithOffset * _ZBufferParams.z); #endif return OUT; } ENDCG } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloud.shader.meta ================================================ fileFormatVersion: 2 guid: 7071adaea60f6124d9ab426b002d5afa timeCreated: 1470912280 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloudShadowMap.shader ================================================ Shader "Scatterer-EVE/CloudShadowMap" { Properties { _Color("Color Tint", Color) = (1,1,1,1) _MainTex("Main (RGB)", 2D) = "white" {} _DetailTex("Detail (RGB)", 2D) = "white" {} _UVNoiseTex("UV Noise (RG)", 2D) = "black" {} _FalloffPow("Falloff Power", Range(0,3)) = 2 _FalloffScale("Falloff Scale", Range(0,20)) = 3 _DetailScale("Detail Scale", Range(0,100)) = 100 _DetailDist("Detail Distance", Range(0,1)) = 0.00875 _UVNoiseScale("UV Noise Scale", Range(0,0.1)) = 0.01 _UVNoiseStrength("UV Noise Strength", Range(0,0.1)) = 0.002 _UVNoiseAnimation("UV Noise Animation", Vector) = (0.002,0.001,0) _UniversalTime("Universal Time", Vector) = (0,0,0,0) _MinLight("Minimum Light", Range(0,1)) = 0 _DistFade("Fade Distance", Range(0,100)) = 10 _DistFadeVert("Fade Scale", Range(0,1)) = .002 _RimDist("Rim Distance", Range(0,1)) = 1 _RimDistSub("Rim Distance Sub", Range(0,2)) = 1.01 _InvFade("Soft Particles Factor", Range(0.01,3.0)) = .01 _OceanRadius("Ocean Radius", Float) = 63000 _PlanetOrigin("Sphere Center", Vector) = (0,0,0,1) _DepthPull("Depth Augment", Float) = .99 _SunPos("_SunPos", Vector) = (0,0,0) _SunRadius("_SunRadius", Float) = 1 } SubShader { Pass { Tags { "LightMode" = "ShadowCaster"} BlendOp Max Blend One One CGPROGRAM #include "EVEUtils.cginc" #pragma target 3.0 #pragma glsl #pragma vertex vert #pragma fragment frag #define MAG_ONE 1.4142135623730950488016887242097 #pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1 #ifndef MAP_TYPE_CUBE2_1 #pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1 #endif #include "alphaMap.cginc" #include "cubeMap.cginc" CUBEMAP_DEF_1(_MainTex) fixed4 _Color; uniform sampler2D _DetailTex; uniform sampler2D _UVNoiseTex; fixed4 _DetailOffset; float _DetailScale; float _DetailDist; float _UVNoiseScale; float _UVNoiseStrength; float2 _UVNoiseAnimation; float4 _SunDir; float _Radius; float _PlanetRadius; float3 _PlanetOrigin; float _godrayCloudThreshold; struct appdata_t { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; //float4 objMain : TEXCOORD0; float4 worldPos : TEXCOORD0; }; v2f vert(appdata_t v) { v2f o; o.worldPos = float4(_PlanetOrigin + _Radius * normalize(v.vertex.xyz),1.0); o.pos = UnityWorldToClipPos(o.worldPos); // o.worldPos = float4(_PlanetOrigin + v.vertex.xyz/v.vertex.w * _Radius, 1.0); // o.pos = UnityWorldToClipPos(o.worldPos); //#if defined(UNITY_REVERSED_Z) float clamped = min(o.pos.z, o.pos.w*UNITY_NEAR_CLIP_VALUE); //#else // float clamped = max(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE); //#endif o.pos.z = lerp(o.pos.z, clamped, unity_LightShadowBias.y); // TRANSFER_SHADOW_CASTER_NORMALOFFSET(o); // UnityApplyLinearShadowBias(o.pos); return o; } float4 frag(v2f IN) : SV_Target { float4 worldPos = float4(IN.worldPos.xyz/IN.worldPos.w,1.0); float4 mainPos = mul(_MainRotation, worldPos); float4 color; float4 main; main = GET_CUBE_MAP_P(_MainTex, mainPos.xyz/mainPos.w, _UVNoiseTex, _UVNoiseScale, _UVNoiseStrength, _UVNoiseAnimation); main = ALPHA_COLOR_1(main); color = _Color * main.rgba; if (color.a < _godrayCloudThreshold) discard; return float4(IN.pos.z/IN.pos.w,0.0,0.0,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloudShadowMap.shader.meta ================================================ fileFormatVersion: 2 guid: 1389c6be1c6e80b4eb8604aabdda8255 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/alphaMap.cginc ================================================ #ifndef ALPHA_MAP_CG_INC #define ALPHA_MAP_CG_INC inline half vectorSum(half4 v) { return (v.x + v.y + v.z + v.w); } half4 alphaMask1; #define ALPHA_VALUE_1(color) \ vectorSum( color * alphaMask1 ) #ifdef ALPHAMAP_1 #define ALPHA_COLOR_1(color) half4(1, 1, 1, ALPHA_VALUE_1(color)) #else #define ALPHA_COLOR_1(color) color #endif #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/alphaMap.cginc.meta ================================================ fileFormatVersion: 2 guid: 1852920dca83b454c8e49493d9ead74c timeCreated: 1470912310 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/cubeMap.cginc ================================================ #ifndef CUBE_MAP_CG_INC #define CUBE_MAP_CG_INC #ifdef MAP_TYPE_CUBE_1 #define GET_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name, vect) #define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(cube ## name, vect, n, nsc, nst, na) #define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name, vect) #define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1) #define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name, vect) #define CUBEMAP_DEF_1(name) \ uniform samplerCUBE cube ## name; #elif defined (MAP_TYPE_CUBE6_1) #define GET_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name ## xn, cube ## name ## xp, \ cube ## name ## yn, cube ## name ## yp, \ cube ## name ## zn, cube ## name ## zp, vect) #define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(cube ## name ## xn, cube ## name ## xp, \ cube ## name ## yn, cube ## name ## yp, \ cube ## name ## zn, cube ## name ## zp, vect, n, nsc, nst, na) #define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name ## xn, cube ## name ## xp, \ cube ## name ## yn, cube ## name ## yp, \ cube ## name ## zn, cube ## name ## zp, vect) #define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name ## xn, cube ## name ## xp, \ cube ## name ## yn, cube ## name ## yp, \ cube ## name ## zn, cube ## name ## zp, vect) #define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1) #define CUBEMAP_DEF_1(name) \ sampler2D cube ## name ## xn, cube ## name ## xp; \ sampler2D cube ## name ## yn, cube ## name ## yp; \ sampler2D cube ## name ## zn, cube ## name ## zp; #elif defined (MAP_TYPE_CUBE2_1) #define GET_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name ## POS, cube ## name ## NEG, vect) #define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(cube ## name ## POS, cube ## name ## NEG, vect, n, nsc, nst, na) #define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name ## POS, cube ## name ## NEG, vect) #define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1) #define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name ## POS, cube ## name ## NEG, vect) #define CUBEMAP_DEF_1(name) \ sampler2D cube ## name ## POS; \ sampler2D cube ## name ## NEG; #else #define GET_CUBE_MAP_1(name, vect) GetCubeMap(name, vect) #define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(name, vect, n, nsc, nst, na) #define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(name, vect) #define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1) #define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(name, vect) #define CUBEMAP_DEF_1(name) \ sampler2D name; #endif inline float4 CubeDerivatives(float2 uv, float scale) { //Make the UV continuous. float2 uvS = abs(uv - (.5*scale)); float2 uvCont; uvCont.x = max(uvS.x, uvS.y); uvCont.y = min(uvS.x, uvS.y); return float4(ddx(uvCont), ddy(uvCont)); } inline float4 Derivatives(float2 uv) { float2 uvCont = uv; //Make the UV continuous. uvCont.x = abs(uvCont.x - .5); return float4(ddx(uvCont), ddy(uvCont)); } inline float2 GetCubeUV(float3 cubeVect, float2 uvOffset) { float2 uv; uv.x = .5 + (INV_2PI*atan2(cubeVect.x, cubeVect.z)); uv.y = INV_PI*acos(cubeVect.y); uv += uvOffset; return uv; } #define GetCubeCubeUV(cubeVect) \ float3 cubeVectNorm = normalize(cubeVect); \ float3 cubeVectNormAbs = abs(cubeVectNorm);\ half zxlerp = step(cubeVectNormAbs.x, cubeVectNormAbs.z);\ half nylerp = step(cubeVectNormAbs.y, max(cubeVectNormAbs.x, cubeVectNormAbs.z));\ half s = lerp(cubeVectNorm.x, cubeVectNorm.z, zxlerp);\ s = sign(lerp(cubeVectNorm.y, s, nylerp));\ half3 detailCoords = lerp(half3(1, -s, -1)*cubeVectNorm.xzy, half3(1, s, -1)*cubeVectNorm.zxy, zxlerp);\ detailCoords = lerp(half3(1, 1, s)*cubeVectNorm.yxz, detailCoords, nylerp);\ half2 uv = ((.5*detailCoords.yz) / abs(detailCoords.x)) + .5; inline half4 GetCubeMapNoLOD(sampler2D texSampler, float3 cubeVect) { float4 uv; float3 cubeVectNorm = normalize(cubeVect); uv.xy = GetCubeUV(cubeVectNorm, float2(0, 0)); uv.zw = float2(0, 0); half4 tex = tex2Dlod(texSampler, uv); return tex; } inline half4 GetCubeMap(sampler2D texSampler, float3 cubeVect) { float3 cubeVectNorm = normalize(cubeVect); float2 uv = GetCubeUV(cubeVectNorm, float2(0, 0)); float4 uvdd = Derivatives(uv); half4 tex = tex2D(texSampler, uv, uvdd.xy, uvdd.zw); return tex; } inline half4 GetCubeMapPerturbed(sampler2D texSampler, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation) { float3 cubeVectNorm = normalize(cubeVect); float2 uv = GetCubeUV(cubeVectNorm, float2(0, 0)); float2 uvd = fmod(uv, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x); uv += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength; float4 uvdd = Derivatives(uv); half4 tex = tex2D(texSampler, uv, uvdd.xy, uvdd.zw); return tex; } inline half4 GetCubeMapNoLOD(samplerCUBE texSampler, float3 cubeVect) { half4 uv; uv.xyz = normalize(cubeVect); uv.w = 0; half4 tex = texCUBElod(texSampler, uv); return tex; } inline half4 GetCubeMap(samplerCUBE texSampler, float3 cubeVect) { half4 tex = texCUBE(texSampler, normalize(cubeVect)); return tex; } inline half4 GetCubeMapPerturbed(samplerCUBE texSampler, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation) { cubeVect = normalize(cubeVect); float2 uv; uv.x = .5 + (INV_2PI*atan2(cubeVect.x, cubeVect.z)); uv.y = INV_PI*acos(cubeVect.y); float2 uvd = fmod(cubeVect, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x); cubeVect.xy += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength; half4 tex = texCUBE(texSampler, cubeVect); return tex; } inline half4 GetCubeMapNoLOD(sampler2D texXn, sampler2D texXp, sampler2D texYn, sampler2D texYp, sampler2D texZn, sampler2D texZp, float3 cubeVect) { float4 uv4; uv4.zw = float2(0, 0); GetCubeCubeUV(cubeVect); uv4.xy = uv; half4 sampxn = tex2Dlod(texXn, uv4); half4 sampxp = tex2Dlod(texXp, uv4); half4 sampyn = tex2Dlod(texYn, uv4); half4 sampyp = tex2Dlod(texYp, uv4); half4 sampzn = tex2Dlod(texZn, uv4); half4 sampzp = tex2Dlod(texZp, uv4); half4 sampx = lerp(sampxn, sampxp, step(0, s)); half4 sampy = lerp(sampyn, sampyp, step(0, s)); half4 sampz = lerp(sampzn, sampzp, step(0, s)); half4 samp = lerp(sampx, sampz, zxlerp); samp = lerp(sampy, samp, nylerp); return samp; } inline half4 GetCubeMap(sampler2D texXn, sampler2D texXp, sampler2D texYn, sampler2D texYp, sampler2D texZn, sampler2D texZp, float3 cubeVect) { GetCubeCubeUV(cubeVect); //this fixes UV discontinuity on Y-X seam by swapping uv coords in derivative calcs when in the X quadrants. float4 uvdd = CubeDerivatives(uv, 1); half4 sampxn = tex2D(texXn, uv, uvdd.xy, uvdd.zw); half4 sampxp = tex2D(texXp, uv, uvdd.xy, uvdd.zw); half4 sampyn = tex2D(texYn, uv, uvdd.xy, uvdd.zw); half4 sampyp = tex2D(texYp, uv, uvdd.xy, uvdd.zw); half4 sampzn = tex2D(texZn, uv, uvdd.xy, uvdd.zw); half4 sampzp = tex2D(texZp, uv, uvdd.xy, uvdd.zw); half4 sampx = lerp(sampxn, sampxp, step(0, s)); half4 sampy = lerp(sampyn, sampyp, step(0, s)); half4 sampz = lerp(sampzn, sampzp, step(0, s)); half4 samp = lerp(sampx, sampz, zxlerp); samp = lerp(sampy, samp, nylerp); return samp; } inline half4 GetCubeMapPerturbed(sampler2D texXn, sampler2D texXp, sampler2D texYn, sampler2D texYp, sampler2D texZn, sampler2D texZp, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation) { GetCubeCubeUV(cubeVect); float2 uvd = fmod(uv, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x); uv += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength; //this fixes UV discontinuity on Y-X seam by swapping uv coords in derivative calcs when in the X quadrants. float4 uvdd = CubeDerivatives(uv, 1); half4 sampxn = tex2D(texXn, uv, uvdd.xy, uvdd.zw); half4 sampxp = tex2D(texXp, uv, uvdd.xy, uvdd.zw); half4 sampyn = tex2D(texYn, uv, uvdd.xy, uvdd.zw); half4 sampyp = tex2D(texYp, uv, uvdd.xy, uvdd.zw); half4 sampzn = tex2D(texZn, uv, uvdd.xy, uvdd.zw); half4 sampzp = tex2D(texZp, uv, uvdd.xy, uvdd.zw); half4 sampx = lerp(sampxn, sampxp, step(0, s)); half4 sampy = lerp(sampyn, sampyp, step(0, s)); half4 sampz = lerp(sampzn, sampzp, step(0, s)); half4 samp = lerp(sampx, sampz, zxlerp); samp = lerp(sampy, samp, nylerp); return samp; } inline half4 GetCubeMapNoLOD(sampler2D texSamplerPos, sampler2D texSamplerNeg, float3 cubeVect) { float4 uv4; uv4.zw = float2(0, 0); GetCubeCubeUV(cubeVect); uv4.xy = uv; half4 texPos = tex2Dlod(texSamplerPos, uv4); half4 texNeg = tex2Dlod(texSamplerNeg, uv4); half4 tex = lerp(texNeg, texPos, step(0, s)); half alpha = lerp(tex.x, tex.z, zxlerp); alpha = lerp(tex.y, alpha, nylerp); return half4(tex.a, tex.a, tex.a, alpha); } inline half4 GetCubeMap(sampler2D texSamplerPos, sampler2D texSamplerNeg, float3 cubeVect) { GetCubeCubeUV(cubeVect); float4 uvdd = CubeDerivatives(uv, 1); half4 texPos = tex2D(texSamplerPos, uv, uvdd.xy, uvdd.zw); half4 texNeg = tex2D(texSamplerNeg, uv, uvdd.xy, uvdd.zw); half4 tex = lerp(texNeg, texPos, step(0, s)); half alpha = lerp(tex.x, tex.z, zxlerp); alpha = lerp(tex.y, alpha, nylerp); return half4(tex.a, tex.a, tex.a, alpha); } inline half4 GetCubeMapPerturbed(sampler2D texSamplerPos, sampler2D texSamplerNeg, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation) { GetCubeCubeUV(cubeVect); float2 uvd = fmod(uv, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x); uv += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength; float4 uvdd = CubeDerivatives(uv, 1); half4 texPos = tex2D(texSamplerPos, uv, uvdd.xy, uvdd.zw); half4 texNeg = tex2D(texSamplerNeg, uv, uvdd.xy, uvdd.zw); half4 tex = lerp(texNeg, texPos, step(0, s)); half alpha = lerp(tex.x, tex.z, zxlerp); alpha = lerp(tex.y, alpha, nylerp); return half4(tex.a, tex.a, tex.a, alpha); } inline half4 GetCubeDetailMapNoLOD(sampler2D texSampler, float3 cubeVect, float detailScale) { float4 uv4; uv4.zw = float2(0, 0); GetCubeCubeUV(cubeVect); uv4.xy = uv; half4 tex = tex2Dlod(texSampler, uv4); return tex; } inline half4 GetCubeDetailMap(sampler2D texSampler, float3 cubeVect, float detailScale) { GetCubeCubeUV(cubeVect); uv*=detailScale; float4 uvdd = CubeDerivatives(uv, detailScale); half4 tex = tex2D(texSampler, uv, uvdd.xy, uvdd.zw); return tex; } #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/cubeMap.cginc.meta ================================================ fileFormatVersion: 2 guid: 6a022d21eb285c143ae29fc2aca21e11 timeCreated: 1470912310 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/noiseSimplex.cginc ================================================ #ifndef NOISE_SIMPLEX_FUNC #define NOISE_SIMPLEX_FUNC /* Description: Array- and textureless CgFx/HLSL 2D, 3D and 4D simplex noise functions. a.k.a. simplified and optimized Perlin noise. The functions have very good performance and no dependencies on external data. 2D - Very fast, very compact code. 3D - Fast, compact code. 4D - Reasonably fast, reasonably compact code. ------------------------------------------------------------------ Ported by: Lex-DRL I've ported the code from GLSL to CgFx/HLSL for Unity, added a couple more optimisations (to speed it up even further) and slightly reformatted the code to make it more readable. Original GLSL functions: https://github.com/ashima/webgl-noise Credits from original glsl file are at the end of this cginc. ------------------------------------------------------------------ Usage: float ns = snoise(v); // v is any of: float2, float3, float4 Return type is float. To generate 2 or more components of noise (colorful noise), call these functions several times with different constant offsets for the arguments. E.g.: float3 colorNs = float3( snoise(v), snoise(v + 17.0), snoise(v - 43.0), ); Remark about those offsets from the original author: People have different opinions on whether these offsets should be integers for the classic noise functions to match the spacing of the zeroes, so we have left that for you to decide for yourself. For most applications, the exact offsets don't really matter as long as they are not too small or too close to the noise lattice period (289 in this implementation). */ // 1 / 289 #define NOISE_SIMPLEX_1_DIV_289 0.00346020761245674740484429065744f // ( x*34.0 + 1.0 )*x = // x*x*34.0 + x float permute(float x) { return fmod( x*x*34.0 + x, 289.0 ); } float3 permute(float3 x) { return fmod( x*x*34.0 + x, 289.0 ); } float4 permute(float4 x) { return fmod( x*x*34.0 + x, 289.0 ); } float taylorInvSqrt(float r) { return 1.79284291400159 - 0.85373472095314 * r; } float4 taylorInvSqrt(float4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float4 grad4(float j, float4 ip) { const float4 ones = float4(1.0, 1.0, 1.0, -1.0); float4 p, s; p.xyz = floor(frac(j * ip.xyz) * 7.0) * ip.z - 1.0; p.w = 1.5 - dot(abs(p.xyz), ones.xyz); // GLSL: lessThan(x, y) = x < y // HLSL: 1 - step(y, x) = x < y //s = float4( // 1 - step(0.0, p) //); //p.xyz = p.xyz + (s.xyz * 2 - 1) * s.www; p.xyz -= sign(p.xyz) * (p.w < 0); return p; } // ----------------------------------- 2D ------------------------------------- float snoise(float2 v) { const float4 C = float4( 0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439 // 1.0 / 41.0 ); // First corner float2 i = floor(v + dot(v, C.yy)); float2 x0 = v - i + dot(i, C.xx); // Other corners // float2 i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0); // Lex-DRL: afaik, step() in GPU is faster than if(), so: // step(x, y) = x <= y //int xLessEqual = step(x0.x, x0.y); // x <= y ? //int2 i1 = // int2(1, 0) * (1 - xLessEqual) // x > y // + int2(0, 1) * xLessEqual // x <= y //; //float4 x12 = x0.xyxy + C.xxzz; //x12.xy -= i1; float4 x12 = x0.xyxy + C.xxzz; int2 i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0); x12.xy -= i1; // Permutations i = fmod(i, 289.0); // Avoid truncation effects in permutation float3 p = permute( permute( i.y + float3(0.0, i1.y, 1.0) ) + i.x + float3(0.0, i1.x, 1.0) ); float3 m = max( 0.5 - float3( dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw) ), 0.0 ); m = m*m; m = m*m; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) float3 x = 2.0 * frac(p * C.www) - 1.0; float3 h = abs(x) - 0.5; float3 ox = floor(x + 0.5); float3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h); // Compute final noise value at P float3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } // ----------------------------------- 3D ------------------------------------- float snoise(float3 v) { const float2 C = float2( 0.166666666666666667, // 1/6 0.333333333333333333 // 1/3 ); const float4 D = float4(0.0, 0.5, 1.0, 2.0); // First corner float3 i = floor(v + dot(v, C.yyy)); float3 x0 = v - i + dot(i, C.xxx); // Other corners float3 g = step(x0.yzx, x0.xyz); float3 l = 1 - g; float3 i1 = min(g.xyz, l.zxy); float3 i2 = max(g.xyz, l.zxy); float3 x1 = x0 - i1 + C.xxx; float3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y float3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = fmod(i, 289.0); float4 p = permute( permute( permute( i.z + float4(0.0, i1.z, i2.z, 1.0) ) + i.y + float4(0.0, i1.y, i2.y, 1.0) ) + i.x + float4(0.0, i1.x, i2.x, 1.0) ); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1/7 float3 ns = n_ * D.wyz - D.xzx; float4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) float4 x_ = floor(j * ns.z); float4 y_ = floor(j - 7.0 * x_); // mod(j,N) float4 x = x_ *ns.x + ns.yyyy; float4 y = y_ *ns.x + ns.yyyy; float4 h = 1.0 - abs(x) - abs(y); float4 b0 = float4(x.xy, y.xy); float4 b1 = float4(x.zw, y.zw); //float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0; //float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0; float4 s0 = floor(b0)*2.0 + 1.0; float4 s1 = floor(b1)*2.0 + 1.0; float4 sh = -step(h, 0.0); float4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; float4 a1 = b1.xzyw + s1.xzyw*sh.zzww; float3 p0 = float3(a0.xy, h.x); float3 p1 = float3(a0.zw, h.y); float3 p2 = float3(a1.xy, h.z); float3 p3 = float3(a1.zw, h.w); //Normalise gradients float4 norm = taylorInvSqrt(float4( dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3) )); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value float4 m = max( 0.6 - float4( dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3) ), 0.0 ); m = m * m; return 42.0 * dot( m*m, float4( dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3) ) ); } // ----------------------------------- 4D ------------------------------------- float snoise(float4 v) { const float4 C = float4( 0.138196601125011, // (5 - sqrt(5))/20 G4 0.276393202250021, // 2 * G4 0.414589803375032, // 3 * G4 -0.447213595499958 // -1 + 4 * G4 ); // First corner float4 i = floor( v + dot( v, 0.309016994374947451 // (sqrt(5) - 1) / 4 ) ); float4 x0 = v - i + dot(i, C.xxxx); // Other corners // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) float4 i0; float3 isX = step(x0.yzw, x0.xxx); float3 isYZ = step(x0.zww, x0.yyz); i0.x = isX.x + isX.y + isX.z; i0.yzw = 1.0 - isX; i0.y += isYZ.x + isYZ.y; i0.zw += 1.0 - isYZ.xy; i0.z += isYZ.z; i0.w += 1.0 - isYZ.z; // i0 now contains the unique values 0,1,2,3 in each channel float4 i3 = saturate(i0); float4 i2 = saturate(i0 - 1.0); float4 i1 = saturate(i0 - 2.0); // x0 = x0 - 0.0 + 0.0 * C.xxxx // x1 = x0 - i1 + 1.0 * C.xxxx // x2 = x0 - i2 + 2.0 * C.xxxx // x3 = x0 - i3 + 3.0 * C.xxxx // x4 = x0 - 1.0 + 4.0 * C.xxxx float4 x1 = x0 - i1 + C.xxxx; float4 x2 = x0 - i2 + C.yyyy; float4 x3 = x0 - i3 + C.zzzz; float4 x4 = x0 + C.wwww; // Permutations i = fmod(i, 289.0); float j0 = permute( permute( permute( permute(i.w) + i.z ) + i.y ) + i.x ); float4 j1 = permute( permute( permute( permute( i.w + float4(i1.w, i2.w, i3.w, 1.0) ) + i.z + float4(i1.z, i2.z, i3.z, 1.0) ) + i.y + float4(i1.y, i2.y, i3.y, 1.0) ) + i.x + float4(i1.x, i2.x, i3.x, 1.0) ); // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope // 7*7*6 = 294, which is close to the ring size 17*17 = 289. const float4 ip = float4( 0.003401360544217687075, // 1/294 0.020408163265306122449, // 1/49 0.142857142857142857143, // 1/7 0.0 ); float4 p0 = grad4(j0, ip); float4 p1 = grad4(j1.x, ip); float4 p2 = grad4(j1.y, ip); float4 p3 = grad4(j1.z, ip); float4 p4 = grad4(j1.w, ip); // Normalise gradients float4 norm = taylorInvSqrt(float4( dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3) )); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; p4 *= taylorInvSqrt(dot(p4, p4)); // Mix contributions from the five corners float3 m0 = max( 0.6 - float3( dot(x0, x0), dot(x1, x1), dot(x2, x2) ), 0.0 ); float2 m1 = max( 0.6 - float2( dot(x3, x3), dot(x4, x4) ), 0.0 ); m0 = m0 * m0; m1 = m1 * m1; return 49.0 * ( dot( m0*m0, float3( dot(p0, x0), dot(p1, x1), dot(p2, x2) ) ) + dot( m1*m1, float2( dot(p3, x3), dot(p4, x4) ) ) ); } // Credits from source glsl file: // // Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : ijm // Lastmod : 20110822 (ijm) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // // // The text from LICENSE file: // // // Copyright (C) 2011 by Ashima Arts (Simplex noise) // Copyright (C) 2011 by Stefan Gustavson (Classic noise) // // 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: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // 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. #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/noiseSimplex.cginc.meta ================================================ fileFormatVersion: 2 guid: 9ce3cf11b8f74594bb7b1e1dba03122d timeCreated: 1470912310 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE.meta ================================================ fileFormatVersion: 2 guid: 47d9eecc3df4a854eaabab84609abb27 folderAsset: yes timeCreated: 1460382633 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EclipseCommon.cginc ================================================ uniform float4 sunPosAndRadius; //xyz sun pos w radius uniform float4x4 lightOccluders1; //array of light occluders uniform float4x4 lightOccluders2; //for each float4 xyz pos w radius //Source: wikibooks.org/wiki/GLSL_Programming/Unity/Soft_Shadows_of_Spheres //I believe space engine also uses the same approach because the eclipses look the same ;) float getEclipseShadow(float3 worldPos, float3 worldLightPos,float3 occluderSpherePosition, float3 occluderSphereRadius, float3 lightSourceRadius) { float3 lightDirection = float3(worldLightPos - worldPos); float3 lightDistance = length(lightDirection); lightDirection = lightDirection / lightDistance; // computation of level of shadowing w float3 sphereDirection = float3(occluderSpherePosition - worldPos); //occluder planet float sphereDistance = length(sphereDirection); sphereDirection = sphereDirection / sphereDistance; float dd = lightDistance * (asin(min(1.0, length(cross(lightDirection, sphereDirection)))) - asin(min(1.0, occluderSphereRadius / sphereDistance))); float w = smoothstep(-1.0, 1.0, -dd / lightSourceRadius); w = w * smoothstep(0.0, 0.2, dot(lightDirection, sphereDirection)); return (1-w); } inline float getEclipseShadows(float3 worldPos, float4x4 lightOccludersmatrix) { float eclipseShadow = 1.0; for (int i=0; i<4; ++i) { UNITY_BRANCH if (lightOccludersmatrix[i].w > 0) { eclipseShadow*= getEclipseShadow(worldPos, sunPosAndRadius.xyz,lightOccludersmatrix[i].xyz,lightOccludersmatrix[i].w, sunPosAndRadius.w); } else { break; } } return eclipseShadow; } inline float getEclipseShadows(float3 worldPos) { return (getEclipseShadows(worldPos, lightOccluders1) * getEclipseShadows(worldPos, lightOccluders2)); } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EclipseCommon.cginc.meta ================================================ fileFormatVersion: 2 guid: 97f2c862ef7ea1d4fa3423506b5cf0ff timeCreated: 1552766346 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/IntersectCommon.cginc ================================================ #pragma once float3 LinePlaneIntersection(float3 linePoint, float3 lineVec, float3 planeNormal, float3 planePoint, out float parallel) { float tlength; float dotNumerator; float dotDenominator; float3 intersectVector; float3 intersection = 0.0; //calculate the distance between the linePoint and the line-plane intersection point dotNumerator = dot((planePoint - linePoint), planeNormal); dotDenominator = dot(lineVec, planeNormal); //line and plane are not parallel if(dotDenominator != 0.0f) { tlength = dotNumerator / dotDenominator; intersection= (tlength > 0.0) ? linePoint + normalize(lineVec) * (tlength) : linePoint; parallel = 0.0; } else { parallel = 1.0; } return intersection; } //works from outside only //p1 starting point, d look direction, p3 is the sphere center float intersectSphereOutside(float3 p1, float3 d, float3 p3, float r) { float a = dot(d, d); float b = 2.0 * dot(d, p1 - p3); float c = dot(p3, p3) + dot(p1, p1) - 2.0 * dot(p3, p1) - r * r; float test = b * b - 4.0 * a * c; float u = (test < 0) ? -1.0 : (-b - sqrt(test)) / (2.0 * a); return u; } //works from inside and outside //p1 starting point, d look direction, p3 is the sphere center float intersectSphereInside(float3 p1, float3 d, float3 p3, float r) { float a = dot(d, d); float b = 2.0 * dot(d, p1 - p3); float c = dot(p3, p3) + dot(p1, p1) - 2.0 * dot(p3, p1) - r*r; float test = b*b - 4.0*a*c; if (test<0) { return -1.0; } float u = (-b - sqrt(test)) / (2.0 * a); u = (u < 0) ? (-b + sqrt(test)) / (2.0 * a) : u; return u; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/IntersectCommon.cginc.meta ================================================ fileFormatVersion: 2 guid: b4c60b58ddb35c749ad94bd8b5b83168 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Misc.meta ================================================ fileFormatVersion: 2 guid: 24f430bcb0b5b8046adfc8065bffc5c9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/0042-underwater-beach-sand-texture-seamless.jpg.meta ================================================ fileFormatVersion: 2 guid: a9126848c43c4dd499da39a90664dd73 TextureImporter: internalIDToNameTable: [] externalObjects: {} serializedVersion: 10 mipmaps: mipMapMode: 0 enableMipMap: 1 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 borderMipMap: 0 mipMapsPreserveCoverage: 0 alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: 1 maxTextureSize: 2048 textureSettings: serializedVersion: 2 filterMode: -1 aniso: -1 mipBias: -100 wrapU: -1 wrapV: -1 wrapW: -1 nPOTScale: 1 lightmap: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 0 spriteTessellationDetail: -1 textureType: 0 textureShape: 1 singleChannelComponent: 0 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] physicsShape: [] bones: [] spriteID: internalID: 0 vertices: [] indices: edges: [] weights: [] secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsFinal.png.meta ================================================ fileFormatVersion: 2 guid: 3c731404613599947b4b4559797a5168 TextureImporter: internalIDToNameTable: [] externalObjects: {} serializedVersion: 10 mipmaps: mipMapMode: 0 enableMipMap: 1 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 borderMipMap: 0 mipMapsPreserveCoverage: 0 alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: 1 maxTextureSize: 2048 textureSettings: serializedVersion: 2 filterMode: -1 aniso: -1 mipBias: -100 wrapU: -1 wrapV: -1 wrapW: -1 nPOTScale: 1 lightmap: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 0 spriteTessellationDetail: -1 textureType: 0 textureShape: 1 singleChannelComponent: 0 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] physicsShape: [] bones: [] spriteID: internalID: 0 vertices: [] indices: edges: [] weights: [] secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsGodrays.mat.meta ================================================ fileFormatVersion: 2 guid: 89e0061781af2da4d938cac6c7381fdc NativeFormatImporter: externalObjects: {} mainObjectFileID: 0 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsGodraysRaymarch.shader ================================================ Shader "Scatterer/CausticsGodraysRaymarch" { Properties { _CausticsTexture ("_CausticsTexture", 2D) = "" {} layer1Scale ("Layer 1 scale", Vector) = (1.0101,1.0101,0) layer1Speed ("Layer 1 speed", Vector) = (0.05123,0.05123,0) layer2Scale ("Layer 2 scale", Vector) = (1.235487,1.235487,0) layer2Speed ("Layer 2 speed", Vector) = (0.074872,0.074872,0) } SubShader { Pass { ZTest On ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #pragma multi_compile SPHERE_PLANET FLAT_PLANET #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" #include "../OceanShadows.cginc" #include "../../CommonAtmosphere.cginc" float4x4 CameraToWorld; float4x4 WorldToLight; float3 LightDir; float3 PlanetOrigin; float oceanRadius; float transparencyDepth; float lightRaysStrength; sampler2D _CausticsTexture; float2 layer1Scale; float2 layer1Speed; float2 layer2Scale; float2 layer2Speed; float causticsBlurDepth; float warpTime; sampler2D ScattererDownscaledDepth; float4 ScattererDownscaledDepth_TexelSize; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float4 screenPos : TEXCOORD1; }; v2f vert (appdata_base v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = ComputeNonStereoScreenPos(o.pos); o.screenPos = ComputeScreenPos(o.pos); return o; } sampler2D _MainTex; float4 frag (v2f IN) : SV_Target { // blur caustics the farther we are from surface float blurFactor = 0.0; float time = _Time.y; time = (warpTime == 0.0) ? time : warpTime; float totalCaustics = 0; float currentDistance = 0; float3 worldPosition = _WorldSpaceCameraPos; float2 uv = IN.screenPos.xy/IN.screenPos.w; float zdepth = tex2Dlod(ScattererDownscaledDepth, float4(uv,0.0,0.0)); #ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(uv, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); float4 fragWorldPos = mul(CameraToWorld,camPos); fragWorldPos/=fragWorldPos.w; float3 viewDir = normalize(fragWorldPos.xyz - worldPosition); float maxDistance = intersectSphereInside (worldPosition, viewDir, PlanetOrigin, oceanRadius); maxDistance = min(maxDistance, length(camPos.xyz / camPos.w)); maxDistance = min(maxDistance, transparencyDepth * 2.0); float dotLight = dot(viewDir,-LightDir); dotLight=pow(abs(dotLight),40) * sign(dotLight); float boostFactor = (dotLight<0.0) ? -0.0085 : 0.005 ; float GRID_SIZE = 8; float GRID_SIZE_SQR_RCP = (1.0/(GRID_SIZE*GRID_SIZE)); float stepSize = 0.2; //maybe change this to 0.007? // Calculate the offsets on the ray according to the interleaved sampling pattern float2 interleavedPos = fmod( float2(IN.pos.x, ScattererDownscaledDepth_TexelSize.w - IN.pos.y), GRID_SIZE ); float rayStartOffset = ( interleavedPos.y * GRID_SIZE + interleavedPos.x ) * ( stepSize * GRID_SIZE_SQR_RCP ) ; worldPosition+=(0.1+rayStartOffset)*viewDir; float fadeOut = 1.0; #ifdef SPHERE_PLANET float underwaterDepth = max(oceanRadius - length(worldPosition - PlanetOrigin), 0.0); blurFactor = lerp(0.0,5.0,underwaterDepth/causticsBlurDepth); fadeOut = smoothstep(0.0,0.4,1.0-(underwaterDepth/causticsBlurDepth)); //fade them out starting from last 40% of causticsBlurDepth #else blurFactor = lerp(0.0,5.0,worldPosition.y/30.0); #endif float2 layer1Offset = layer1Speed * float2(time,time); float2 layer2Offset = layer2Speed * float2(time,time); for (int i=0;i<150;i++) { float2 uvCookie = mul(WorldToLight, float4(worldPosition, 1)).xy; float2 uvSample1 = layer1Scale * uvCookie + layer1Offset; float2 uvSample2 = layer2Scale * uvCookie + layer2Offset; float causticsSample1 = tex2Dlod(_CausticsTexture,float4(uvSample1,0.0,blurFactor)).r; float causticsSample2 = tex2Dlod(_CausticsTexture,float4(uvSample2,0.0,blurFactor)).r; float caustics = 0.01*lightRaysStrength*min(causticsSample1,causticsSample2); float4 clipPos = mul(UNITY_MATRIX_VP,float4(worldPosition,1.0)); float4 screenPos = ComputeScreenPos(clipPos); float shadowTerm = getOceanHardShadow(float4(worldPosition,1.0),-screenPos.z); totalCaustics+=(1.0-totalCaustics)*caustics*shadowTerm; float increment = 0.2 + boostFactor*i*dotLight; //variable step size, boost when looking towards light source or direction to make it look like it's properly coming from infinity currentDistance+=increment; worldPosition+=viewDir*increment; // if (currentDistance > maxDistance) { break; } } totalCaustics*=fadeOut; return float4(totalCaustics,totalCaustics,totalCaustics,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsGodraysRaymarch.shader.meta ================================================ fileFormatVersion: 2 guid: 44df73535c7a760458518e95391dbfdc ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsOcclusion.shader ================================================ // Upgrade NOTE: replaced '_LightMatrix0' with 'unity_WorldToLight' Shader "Scatterer/CausticsOcclusion" { Properties { _CausticsTexture ("_CausticsTexture", 2D) = "" {} layer1Scale ("Layer 1 scale", Vector) = (1.0101,1.0101,0) layer1Speed ("Layer 1 speed", Vector) = (0.05123,0.05123,0) layer2Scale ("Layer 2 scale", Vector) = (1.235487,1.235487,0) layer2Speed ("Layer 2 speed", Vector) = (0.074872,0.074872,0) causticsMultiply ("causticsMultiply", Float) = 1 causticsMinBrightness ("causticsMinBrightness", Float) = 0.1 } SubShader { Pass { Cull Back ZWrite Off ZTest Off BlendOp Min //take the minimum so existing shadows that are not completely at zero are respected CGPROGRAM #include "UnityCG.cginc" #include "Lighting.cginc" #include "../../DepthCommon.cginc" #pragma vertex vert #pragma fragment frag #pragma target 3.0 #pragma multi_compile SPHERE_PLANET FLAT_PLANET float4x4 CameraToWorld; float4x4 WorldToLight; float3 PlanetOrigin; float oceanRadius; sampler2D _CausticsTexture; float2 layer1Scale; float2 layer1Speed; float2 layer2Scale; float2 layer2Speed; float causticsMultiply; float causticsMinBrightness; float causticsBlurDepth; float warpTime; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = ComputeScreenPos(OUT.pos); return OUT; } fixed4 frag (v2f i) : SV_Target { float zdepth = tex2Dlod(_CameraDepthTexture, float4(i.uv,0,0)); #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (zdepth == 0.0) {discard;} #else if (zdepth == 1.0) {discard;} #endif float3 worldPos = getPreciseWorldPosFromDepth(i.uv, zdepth, CameraToWorld); // blur caustics the farther we are from texture float blurFactor = 0.0; float time = _Time.y; #ifdef SPHERE_PLANET float underwaterDepth = max(oceanRadius - length(worldPos - PlanetOrigin), 0.0); blurFactor = lerp(0.0,5.0,underwaterDepth/causticsBlurDepth); time = (warpTime == 0.0) ? time : warpTime; #else blurFactor = lerp(0.0,5.0,-worldPos.y/30.0); #endif float2 uvCookie = mul(WorldToLight, float4(worldPos.xyz, 1)).xy; float2 uvSample1 = layer1Scale * uvCookie + layer1Speed * float2(time,time); float2 uvSample2 = layer2Scale * uvCookie + layer2Speed * float2(time,time); float causticsSample1 = tex2Dbias(_CausticsTexture,float4(uvSample1,0.0,blurFactor)).r; float causticsSample2 = tex2Dbias(_CausticsTexture,float4(uvSample2,0.0,blurFactor)).r; float caustics = causticsMultiply*min(causticsSample1,causticsSample2)+causticsMinBrightness; #ifdef SPHERE_PLANET caustics = lerp (1.0, caustics, clamp(underwaterDepth/1.5f, 0.0, 1.0)); //fade caustics in over the first meter and half of depth #endif return float4(caustics,caustics,caustics,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsOcclusion.shader.meta ================================================ fileFormatVersion: 2 guid: 9c9e5198af35eb74d8c5d84a5194b184 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsScene.unity.meta ================================================ fileFormatVersion: 2 guid: a4cac3a64ff3a4540bbabd58e2d7c8b2 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsShadowMask.mat.meta ================================================ fileFormatVersion: 2 guid: 43ad7f10b8cb01a4ca1b57eff53b024c NativeFormatImporter: externalObjects: {} mainObjectFileID: 0 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CompositeCausticsGodrays.shader ================================================ Shader "Scatterer/CompositeCausticsGodrays" { Properties{ } SubShader{ Tags { "Queue"="Transparent+2" "IgnoreProjector"="True" "RenderType"="Transparent"} Pass { Blend OneMinusDstColor One //softAdditive CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment frag #include"UnityCG.cginc" uniform sampler2D LightRaysTexture; uniform sampler2D _CameraDepthTexture; float4 _CameraDepthTexture_TexelSize; uniform sampler2D ScattererDownscaledDepth; float4 ScattererDownscaledDepth_TexelSize; uniform float3 _sunColor; //already calculated sun extinction or color uniform float3 _Underwater_Color; struct appdata_t { float4 vertex : POSITION; float2 uv: TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_t v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } float4 frag(v2f i) : COLOR { float color = tex2D(LightRaysTexture, i.uv).r; return float4(_Underwater_Color * _sunColor * color,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CompositeCausticsGodrays.shader.meta ================================================ fileFormatVersion: 2 guid: c91c0b6ea03975b419e4cb285a69a10d ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/ModulateShadowMask.cs ================================================ using UnityEngine; using UnityEngine.Rendering; using System.Collections.Generic; using System; public class ModulateShadowMask : MonoBehaviour { private CommandBuffer m_Buffer; private Light m_Light; private Camera fakeCamera; [SerializeField] private Material m_ShadowMaskModulateMaterial; public ModulateShadowMask () { } public void Awake() { m_ShadowMaskModulateMaterial.DisableKeyword ("SPHERE_PLANET"); m_ShadowMaskModulateMaterial.EnableKeyword ("FLAT_PLANET"); m_Buffer = new CommandBuffer(); m_Buffer.name = "ScreenspaceShadowMaskmodulate"; m_Buffer.Blit (null, BuiltinRenderTextureType.CurrentActive, m_ShadowMaskModulateMaterial); m_Light = GetComponent(); m_Light.AddCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer); } public void Update() { m_ShadowMaskModulateMaterial.SetMatrix ("CameraToWorld", Camera.main.cameraToWorldMatrix); m_ShadowMaskModulateMaterial.SetMatrix ("WorldToLight", m_Light.gameObject.transform.worldToLocalMatrix); //may look like it doesn't work in the editor, ie using the editor Camera } public void OnDestroy () { m_Light.RemoveCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/ModulateShadowMask.cs.meta ================================================ fileFormatVersion: 2 guid: eb1eda9941f181549a0b626e36a4dd26 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/SeaFloor.mat.meta ================================================ fileFormatVersion: 2 guid: 8cc83bff6b39f3d44af0de8320999144 NativeFormatImporter: externalObjects: {} mainObjectFileID: 2100000 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/WhiteTexture.png.meta ================================================ fileFormatVersion: 2 guid: 6b152d671c864bf41bbcc096f5a7567c TextureImporter: internalIDToNameTable: [] externalObjects: {} serializedVersion: 10 mipmaps: mipMapMode: 0 enableMipMap: 1 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 borderMipMap: 0 mipMapsPreserveCoverage: 0 alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: 1 maxTextureSize: 2048 textureSettings: serializedVersion: 2 filterMode: -1 aniso: -1 mipBias: -100 wrapU: -1 wrapV: -1 wrapW: -1 nPOTScale: 1 lightmap: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 0 spriteTessellationDetail: -1 textureType: 0 textureShape: 1 singleChannelComponent: 0 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] physicsShape: [] bones: [] spriteID: internalID: 0 vertices: [] indices: edges: [] weights: [] secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics.meta ================================================ fileFormatVersion: 2 guid: 94412382cf909c843b9a46a8f6b364f4 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/FindHeights.compute ================================================ #pragma kernel CSMain float4 _Ocean_Choppyness; float4 _Ocean_GridSizes; sampler2D _Ocean_Map0; sampler2D _Ocean_Map3; sampler2D _Ocean_Map4; RWStructuredBuffer positions; RWStructuredBuffer result; float SampleHeight(float2 oceanPos) { float height = 0; height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.x,0.0, 0.0) ).x; height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.y,0.0, 0.0) ).y; height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.z,0.0, 0.0) ).z; height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.w,0.0, 0.0) ).w; return height; } float2 SampleDisplacement(float2 oceanPos) { float2 displacement = 0; displacement += _Ocean_Choppyness.x * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.x,0.0, 0.0) ).xy; displacement += _Ocean_Choppyness.y * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.y,0.0, 0.0) ).zw; displacement += _Ocean_Choppyness.z * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.z,0.0, 0.0) ).xy; displacement += _Ocean_Choppyness.w * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.w,0.0, 0.0) ).zw; return displacement; } //Essentially a search method to find which point on the ocean is displaced sideways to end up at our part's position, so we can sample the correct height //Thanks to Scrawk (Justin Hawkins) for the tip //Original source: Water technology of uncharted p.126 https://www.gdcvault.com/play/1015309/Water-Technology-of [numthreads(1,1,1)] void CSMain (uint id : SV_DispatchThreadID) { float precisionRequired = 0.02; float2 currentPosition = positions[id]; float2 displacement = SampleDisplacement (currentPosition); float2 resultingPosition = currentPosition + displacement; for (int i = 0; i < 40; i++) { if (length(resultingPosition - positions[id]) <= precisionRequired) break; float2 newPosition = currentPosition - (resultingPosition - positions[id]); float2 newDisplacement = SampleDisplacement (newPosition); float2 newResultingPosition = newPosition + newDisplacement; currentPosition = newPosition; resultingPosition = newResultingPosition; } result[id] = SampleHeight(currentPosition); } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/FindHeights.compute.meta ================================================ fileFormatVersion: 2 guid: 45322b284be6baf43a273a61abba527d ComputeShaderImporter: externalObjects: {} currentAPIMask: 4 userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Fourier.shader ================================================ // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Scatterer/Fourier" { CGINCLUDE #include "UnityCG.cginc" uniform sampler2D _ReadBuffer0, _ReadBuffer1, _ReadBuffer2; uniform sampler2D _ButterFlyLookUp; uniform float _Size; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; struct f2a_1 { float4 col0 : COLOR0; }; struct f2a_2 { float4 col0 : COLOR0; float4 col1 : COLOR1; }; struct f2a_3 { float4 col0 : COLOR0; float4 col1 : COLOR1; float4 col2 : COLOR2; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } //Performs two FFTs on two complex numbers packed in a vector4 float4 FFT(float2 w, float4 input1, float4 input2) { float rx = w.x * input2.x - w.y * input2.y; float ry = w.y * input2.x + w.x * input2.y; float rz = w.x * input2.z - w.y * input2.w; float rw = w.y * input2.z + w.x * input2.w; return input1 + float4(rx,ry,rz,rw); } f2a_1 fragX_1(v2f IN) { float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.x, 0)); lookUp.xyz *= 255.0; lookUp.xy /= _Size-1.0; float PI = 3.1415926; float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size)); if(lookUp.w > 0.5) w *= -1.0; f2a_1 OUT; float2 uv1 = float2(lookUp.x, IN.uv.y); float2 uv2 = float2(lookUp.y, IN.uv.y); OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2)); return OUT; } f2a_1 fragY_1(v2f IN) { float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.y, 0)); lookUp.xyz *= 255.0; lookUp.xy /= _Size-1.0; float PI = 3.1415926; float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size)); if(lookUp.w > 0.5) w *= -1.0; f2a_1 OUT; float2 uv1 = float2(IN.uv.x, lookUp.x); float2 uv2 = float2(IN.uv.x, lookUp.y); OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2)); return OUT; } f2a_2 fragX_2(v2f IN) { float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.x, 0)); lookUp.xyz *= 255.0; lookUp.xy /= _Size-1.0; float PI = 3.1415926; float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size)); if(lookUp.w > 0.5) w *= -1.0; f2a_2 OUT; float2 uv1 = float2(lookUp.x, IN.uv.y); float2 uv2 = float2(lookUp.y, IN.uv.y); OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2)); OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2)); return OUT; } f2a_2 fragY_2(v2f IN) { float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.y, 0)); lookUp.xyz *= 255.0; lookUp.xy /= _Size-1.0; float PI = 3.1415926; float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size)); if(lookUp.w > 0.5) w *= -1.0; f2a_2 OUT; float2 uv1 = float2(IN.uv.x, lookUp.x); float2 uv2 = float2(IN.uv.x, lookUp.y); OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2)); OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2)); return OUT; } f2a_3 fragX_3(v2f IN) { float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.x, 0)); lookUp.xyz *= 255.0; lookUp.xy /= _Size-1.0; float PI = 3.1415926; float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size)); if(lookUp.w > 0.5) w *= -1.0; f2a_3 OUT; float2 uv1 = float2(lookUp.x, IN.uv.y); float2 uv2 = float2(lookUp.y, IN.uv.y); OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2)); OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2)); OUT.col2 = FFT(w, tex2D(_ReadBuffer2, uv1), tex2D(_ReadBuffer2, uv2)); return OUT; } f2a_3 fragY_3(v2f IN) { float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.y, 0)); lookUp.xyz *= 255.0; lookUp.xy /= _Size-1.0; float PI = 3.1415926; float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size)); if(lookUp.w > 0.5) w *= -1.0; f2a_3 OUT; float2 uv1 = float2(IN.uv.x, lookUp.x); float2 uv2 = float2(IN.uv.x, lookUp.y); OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2)); OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2)); OUT.col2 = FFT(w, tex2D(_ReadBuffer2, uv1), tex2D(_ReadBuffer2, uv2)); return OUT; } ENDCG SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment fragX_1 ENDCG } Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment fragY_1 ENDCG } Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment fragX_2 ENDCG } Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment fragY_2 ENDCG } Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment fragX_3 ENDCG } Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment fragY_3 ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Fourier.shader.meta ================================================ fileFormatVersion: 2 guid: 6a44d0f20e3f6cd45881a44134574169 timeCreated: 1459689856 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitDisplacement.shader ================================================ // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Proland/Ocean/InitDisplacement" { SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _Buffer1; uniform sampler2D _Buffer2; uniform float4 _InverseGridSizes; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; struct f2a { float4 col0 : COLOR0; float4 col1 : COLOR1; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } f2a frag(v2f IN) { float2 uv = IN.uv.xy; float2 st; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; float2 k1 = st * _InverseGridSizes.x; float2 k2 = st * _InverseGridSizes.y; float2 k3 = st * _InverseGridSizes.z; float2 k4 = st * _InverseGridSizes.w; float K1 = length(k1); float K2 = length(k2); float K3 = length(k3); float K4 = length(k4); float IK1 = K1 == 0.0 ? 0.0 : 1.0 / K1; float IK2 = K2 == 0.0 ? 0.0 : 1.0 / K2; float IK3 = K3 == 0.0 ? 0.0 : 1.0 / K3; float IK4 = K4 == 0.0 ? 0.0 : 1.0 / K4; f2a OUT; OUT.col0 = tex2D(_Buffer1, IN.uv) * float4(IK1, IK1, IK2, IK2); OUT.col1 = tex2D(_Buffer2, IN.uv) * float4(IK3, IK3, IK4, IK4); return OUT; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitDisplacement.shader.meta ================================================ fileFormatVersion: 2 guid: 4f809c227a3cfde4bbb9482dc1814105 timeCreated: 1459689457 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitJacobians.shader ================================================ // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Proland/Ocean/InitJacobians" { SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _Spectrum01; uniform sampler2D _Spectrum23; uniform sampler2D _WTable; uniform float4 _Offset; uniform float4 _InverseGridSizes; uniform float _T; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; struct f2a { float4 col0 : COLOR0; float4 col1 : COLOR1; float4 col2 : COLOR2; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } float2 GetSpectrum(float w, float2 s0, float2 s0c) { float c = cos(w*_T); float s = sin(w*_T); return float2((s0.x + s0c.x) * c - (s0.y + s0c.y) * s, (s0.x - s0c.x) * s + (s0.y - s0c.y) * c); } float2 COMPLEX(float2 z) { return float2(-z.y, z.x); // returns i times z (complex number) } f2a frag(v2f IN) { float2 uv = IN.uv.xy; float2 st; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; float4 s12 = tex2D(_Spectrum01, uv); float4 s12c = tex2D(_Spectrum01, _Offset.xy-uv); float4 s34 = tex2D(_Spectrum23, uv); float4 s34c = tex2D(_Spectrum23, _Offset.xy-uv); float2 k1 = st * _InverseGridSizes.x; float2 k2 = st * _InverseGridSizes.y; float2 k3 = st * _InverseGridSizes.z; float2 k4 = st * _InverseGridSizes.w; float K1 = length(k1); float K2 = length(k2); float K3 = length(k3); float K4 = length(k4); float IK1 = K1 == 0.0 ? 0.0 : 1.0 / K1; float IK2 = K2 == 0.0 ? 0.0 : 1.0 / K2; float IK3 = K3 == 0.0 ? 0.0 : 1.0 / K3; float IK4 = K4 == 0.0 ? 0.0 : 1.0 / K4; float4 w = tex2D(_WTable, uv); float2 h1 = GetSpectrum(w.x, s12.xy, s12c.xy); float2 h2 = GetSpectrum(w.y, s12.zw, s12c.zw); float2 h3 = GetSpectrum(w.z, s34.xy, s34c.xy); float2 h4 = GetSpectrum(w.w, s34.zw, s34c.zw); /// Jacobians float4 IK = float4(IK1,IK2,IK3,IK4); float2 k1Squared = k1*k1; float2 k2Squared = k2*k2; float2 k3Squared = k3*k3; float2 k4Squared = k4*k4; // 5: d(Dx(X,t))/dx Tes01 eq30 // 6: d(Dy(X,t))/dy Tes01 eq30 // 7: d(Dx(X,t))/dy Tes01 eq30 float4 tmp = float4(h1.x, h2.x, h3.x, h4.x); f2a OUT; OUT.col0 = -tmp * (float4(k1Squared.x, k2Squared.x, k3Squared.x, k4Squared.x) * IK); OUT.col1 = -tmp * (float4(k1Squared.y, k2Squared.y, k3Squared.y, k4Squared.y) * IK); OUT.col2 = -tmp * (float4(k1.x*k1.y, k2.x*k2.y, k3.x*k3.y, k4.x*k4.y) * IK); return OUT; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitJacobians.shader.meta ================================================ fileFormatVersion: 2 guid: f8f889eee05c15349bc81eeb0883357d timeCreated: 1459689457 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitSpectrum.shader ================================================ // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Proland/Ocean/InitSpectrum" { SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _Spectrum01; uniform sampler2D _Spectrum23; uniform sampler2D _WTable; uniform float4 _Offset; uniform float4 _InverseGridSizes; uniform float _T; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; struct f2a { float4 col0 : COLOR0; float4 col1 : COLOR1; float4 col2 : COLOR2; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } float2 GetSpectrum(float w, float2 s0, float2 s0c) { float c = cos(w*_T); float s = sin(w*_T); return float2((s0.x + s0c.x) * c - (s0.y + s0c.y) * s, (s0.x - s0c.x) * s + (s0.y - s0c.y) * c); } float2 COMPLEX(float2 z) { return float2(-z.y, z.x); // returns i times z (complex number) } f2a frag(v2f IN) { float2 uv = IN.uv.xy; float2 st; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; float4 s12 = tex2D(_Spectrum01, uv); float4 s12c = tex2D(_Spectrum01, _Offset.xy-uv); float4 s34 = tex2D(_Spectrum23, uv); float4 s34c = tex2D(_Spectrum23, _Offset.xy-uv); float2 k1 = st * _InverseGridSizes.x; float2 k2 = st * _InverseGridSizes.y; float2 k3 = st * _InverseGridSizes.z; float2 k4 = st * _InverseGridSizes.w; float4 w = tex2D(_WTable, uv); float2 h1 = GetSpectrum(w.x, s12.xy, s12c.xy); float2 h2 = GetSpectrum(w.y, s12.zw, s12c.zw); float2 h3 = GetSpectrum(w.z, s34.xy, s34c.xy); float2 h4 = GetSpectrum(w.w, s34.zw, s34c.zw); float2 h12 = h1 + COMPLEX(h2); float2 h34 = h3 + COMPLEX(h4); float2 n1 = COMPLEX(k1.x * h1) - k1.y * h1; float2 n2 = COMPLEX(k2.x * h2) - k2.y * h2; float2 n3 = COMPLEX(k3.x * h3) - k3.y * h3; float2 n4 = COMPLEX(k4.x * h4) - k4.y * h4; f2a OUT; OUT.col0 = float4(h12, h34); OUT.col1 = float4(n1, n2); OUT.col2 = float4(n3, n4); return OUT; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitSpectrum.shader.meta ================================================ fileFormatVersion: 2 guid: 212a65848ed53294788b2731538c9d66 timeCreated: 1459689457 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InvisibleOcean.shader ================================================ Shader "Scatterer/invisible" { SubShader { Tags {"Queue" = "Transparent" "IgnoreProjector"="True" "RenderType"="InvOcean"} Pass { ZWrite Off ZTest on Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag #pragma glsl struct v2f { float4 pos : SV_POSITION; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = float4(2.0, 2.0, 2.0, 1.0); //outside clip space => cull vertex return OUT; } float4 frag(v2f IN) : COLOR { return float4(0.0,0.0,0.0,0.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InvisibleOcean.shader.meta ================================================ fileFormatVersion: 2 guid: f32e959de7955be41a4af6dac2f75b09 timeCreated: 1499371576 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanBRDF.cginc ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. */ /* * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. * Modified and ported to Unity by Justin Hawkins 2014 */ #if !defined (M_PI) #define M_PI 3.141592657 #endif float MeanFresnel(float cosThetaV, float sigmaV) { return pow(1.0 - cosThetaV, 5.0 * exp(-2.69 * sigmaV)) / (1.0 + 22.7 * pow(sigmaV, 1.5)); } float MeanFresnel(float3 V, float3 N, float sigmaSq) { return MeanFresnel(dot(V, N), sqrt(sigmaSq)); } // L, V, N in world space float ReflectedSunRadiance(float3 L, float3 V, float3 N, float sigmaSq) { float3 H = normalize(L + V); float hn = dot(H, N); float p = exp(-2.0 * ((1.0 - hn * hn) / sigmaSq) / (1.0 + hn)) / (4.0 * M_PI * sigmaSq); float c = 1.0 - dot(V, H); float c2 = c * c; float fresnel = 0.02 + 0.98 * c2 * c2 * c; float zL = dot(L, N); float zV = dot(V, N); zL = max(zL,0.01); zV = max(zV,0.01); // brdf times cos(thetaL) return zL <= 0.0 ? 0.0 : max(fresnel * p * sqrt(abs(zL / zV)), 0.0); } float2 U(float2 zeta, float3 V) { float3 F = normalize(float3(-zeta, 1.0)); float3 R = 2.0 * dot(F, V) * F - V; return -R.xy / (1.0 + R.z); } // V, N, sunDir in world space float3 ReflectedSkyRadiance(sampler2D skymap, float3 V, float3 N, float sigmaSq, float3 sunDir) { float3 result = float3(0,0,0); float2 zeta0 = -N.xy / N.z; float2 tau0 = U(zeta0, V); const float n = 1.0 / 1.1; float2 JX = (U(zeta0 + float2(0.01, 0.0), V) - tau0) / 0.01 * n * sqrt(sigmaSq); float2 JY = (U(zeta0 + float2(0.0, 0.01), V) - tau0) / 0.01 * n * sqrt(sigmaSq); result = tex2D(skymap, (tau0 * 0.5 / 1.1 + 0.5), JX, JY).rgb; result *= 0.02 + 0.98 * MeanFresnel(V, N, sigmaSq); return result; } float RefractedSeaRadiance(float3 V, float3 N, float sigmaSq) { return 0.98 * (1.0 - MeanFresnel(V, N, sigmaSq)); } float erf(float x) { float a = 0.140012; float x2 = x*x; float ax2 = a*x2; return sign(x) * sqrt( 1.0 - exp(-x2*(4.0/M_PI + ax2)/(1.0 + ax2)) ); } float WhitecapCoverage(float epsilon, float mu, float sigma2) { return 0.5*erf((0.5*sqrt(2.0)*(epsilon-mu)*(1.0/sqrt(sigma2)))) + 0.5; } float3 OceanRadiance(float3 L, float3 V, float3 N, float sigmaSq, float3 sunL, float3 skyE, float3 seaColor) { float F = MeanFresnel(V, N, sigmaSq); float3 Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * sunL; float3 Lsky = skyE * F / M_PI; float3 Lsea = (1.0 - F) * seaColor * skyE / M_PI; return Lsun + Lsky + Lsea; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanBRDF.cginc.meta ================================================ fileFormatVersion: 2 guid: 907dff89ca8c76745b031725757e5f8b ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanDisplacement3.cginc ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. */ /* * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. * Modified and ported to Unity by Justin Hawkins 2014 */ uniform float _Ocean_Radius; //uniform float3 _Ocean_Horizon1; //uniform float3 _Ocean_Horizon2; uniform float _Ocean_HeightOffset; uniform float3 _Ocean_CameraPos; uniform float4x4 _Ocean_OceanToCamera; uniform float4x4 _Ocean_CameraToOcean; uniform float3 sphereDir; uniform float cosTheta; uniform float sinTheta; // A glorified sphere intersect, with some code to snap above the horizon back to the horizon // Returns Position in ocean space float2 OceanPos(float4 vert, float4x4 stoc, out float t, out float3 cameraDir, out float3 oceanDir) { float h = _Ocean_CameraPos.z; float4 v = float4(vert.x, vert.y, 0.0, 1.0); cameraDir = normalize(mul(stoc, v).xyz); //Dir in camera space float3 n1= cross (sphereDir, cameraDir); //Normal to plane containing dir to planet and vertex viewdir float3 n2= normalize(cross (n1, sphereDir)); //upwards vector in plane space, plane containing CamO and cameraDir float3 hor=cosTheta*sphereDir+sinTheta*n2; cameraDir= ( (dot(n1,cross(hor,cameraDir)) >=0) && (h>=0)) ? hor : cameraDir ; //checking if viewdir is above horizon //This could probably be optimized oceanDir = mul(_Ocean_CameraToOcean, float4(cameraDir, 0.0)).xyz; float cz = _Ocean_CameraPos.z; float dz = oceanDir.z; float radius = _Ocean_Radius; float b = dz * (cz + radius); float c = cz * (cz + 2.0 * radius); #if !defined (UNDERWATER_ON) float tSphere = - b - sqrt(max(b * b - c, 0.02)); #else float tSphere = - b + sqrt(max(b * b - c, 0.02)); #endif float tApprox = - cz / dz * (1.0 + cz / (2.0 * radius) * (1.0 - dz * dz)); t = abs((tApprox - tSphere) * dz) < 1.0 ? tApprox : tSphere; return _Ocean_CameraPos.xy + t * oceanDir.xy; } float2 OceanPos(float4 vert, float4x4 stoc) { float t; float3 cameraDir; float3 oceanDir; return OceanPos(vert, stoc, t, cameraDir, oceanDir); } float4 Tex2DGrad(sampler2D tex, float2 uv, float2 dx, float2 dy, float2 texSize) { //Sampling a texture by derivatives in unsupported in vert shaders in Unity but if you //can manually calculate the derivates you can reproduce its effect using tex2Dlod float2 px = texSize.x * dx; float2 py = texSize.y * dy; float lod = 0.5 * log2(max(dot(px, px), dot(py, py))); return tex2Dlod(tex, float4(uv, 0, lod)); } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanDisplacement3.cginc.meta ================================================ fileFormatVersion: 2 guid: 2ac6db96cd5bff048a79be0215503e16 ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanLight.cginc ================================================ // Modified Light helpers for the ocean // unlike in autolight.cginc, object2world can't be used in the case of the ocean // the projection is instead done via other means // the world position is passed instead of doing a mul(_Object2World, v.vertex) which gives the wrong result here #ifdef POINT //#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2) #define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos).xyz; TRANSFER_SHADOW(a) //#define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * SHADOW_ATTENUATION(a)) #endif #ifdef SPOT //#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord4 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2) #define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos); TRANSFER_SHADOW(a) //#define LIGHT_ATTENUATION(a) ( (a._LightCoord.z > 0) * UnitySpotCookie(a._LightCoord) * UnitySpotAttenuate(a._LightCoord.xyz) * SHADOW_ATTENUATION(a) ) #endif #ifdef DIRECTIONAL // #define LIGHTING_COORDS(idx1,idx2) SHADOW_COORDS(idx1) #define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) TRANSFER_SHADOW(a) // #define LIGHT_ATTENUATION(a) SHADOW_ATTENUATION(a) #endif #ifdef POINT_COOKIE //#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2) #define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos).xyz; TRANSFER_SHADOW(a) //#define LIGHT_ATTENUATION(a) (tex2D(_LightTextureB0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * texCUBE(_LightTexture0, a._LightCoord).w * SHADOW_ATTENUATION(a)) #endif #ifdef DIRECTIONAL_COOKIE //#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord2 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2) #define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos).xy; TRANSFER_SHADOW(a) //#define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, a._LightCoord).w * SHADOW_ATTENUATION(a)) #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanLight.cginc.meta ================================================ fileFormatVersion: 2 guid: eafae18265a10964e97bb7c9c1601ef6 timeCreated: 1460511161 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanShadows.cginc ================================================ UNITY_DECLARE_SHADOWMAP(_ShadowMapTextureScatterer); float4 _ShadowMapTextureScatterer_TexelSize; #if SHADER_API_D3D11 #define SHADOWS_SPLIT_SPHERES #endif #include "../ShadowsCommon.cginc" /** * PCF tent shadowmap filtering based on a 7x7 kernel (optimized with 16 taps) * Same as unity's but modified to use a different shadowmap identifier */ half ScattererSampleShadowmap_PCF7x7(float4 coord, float3 receiverPlaneDepthBias) { half shadow = 1; #ifndef SHADOWS_NATIVE // when we don't have hardware PCF sampling, fallback to a simple 3x3 sampling with averaged results. return UnitySampleShadowmap_PCF3x3NoHardwareSupport(coord, receiverPlaneDepthBias); #endif // tent base is 7x7 base thus covering from 49 to 64 texels, thus we need 16 bilinear PCF fetches float2 tentCenterInTexelSpace = coord.xy * _ShadowMapTextureScatterer_TexelSize.zw; float2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5); float2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace; // find the weight of each texel based on the area of a 45 degree slop tent above each of them. float4 texelsWeightsU_A, texelsWeightsU_B; float4 texelsWeightsV_A, texelsWeightsV_B; _UnityInternalGetWeightPerTexel_7TexelsWideTriangleFilter(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsU_A, texelsWeightsU_B); _UnityInternalGetWeightPerTexel_7TexelsWideTriangleFilter(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsV_A, texelsWeightsV_B); // each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels float4 fetchesWeightsU = float4(texelsWeightsU_A.xz, texelsWeightsU_B.xz) + float4(texelsWeightsU_A.yw, texelsWeightsU_B.yw); float4 fetchesWeightsV = float4(texelsWeightsV_A.xz, texelsWeightsV_B.xz) + float4(texelsWeightsV_A.yw, texelsWeightsV_B.yw); // move the PCF bilinear fetches to respect texels weights float4 fetchesOffsetsU = float4(texelsWeightsU_A.yw, texelsWeightsU_B.yw) / fetchesWeightsU.xyzw + float4(-3.5,-1.5,0.5,2.5); float4 fetchesOffsetsV = float4(texelsWeightsV_A.yw, texelsWeightsV_B.yw) / fetchesWeightsV.xyzw + float4(-3.5,-1.5,0.5,2.5); fetchesOffsetsU *= _ShadowMapTextureScatterer_TexelSize.xxxx; fetchesOffsetsV *= _ShadowMapTextureScatterer_TexelSize.yyyy; // fetch ! float2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * _ShadowMapTextureScatterer_TexelSize.xy; shadow = fetchesWeightsU.x * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.y * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.z * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.w * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.x * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.y * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.z * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.w * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.x * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.y * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.z * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.w * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.x * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.y * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.z * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias)); shadow += fetchesWeightsU.w * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias)); return shadow; } /** * Hard shadow * Same as unity's, with the min strength/intensity removed */ half getOceanHardShadow(float4 worldPos, float viewPosZ) { fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (worldPos, viewPosZ); float4 shadowCoord = GET_SHADOW_COORDINATES(worldPos, cascadeWeights); //1 tap hard shadow fixed shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, shadowCoord); //shadow = lerp(_LightShadowData.r, 1.0, shadow); //min strength/intensity, not used for ocean fixed4 res = shadow; return res; } /** * Soft Shadow (SM 3.0) * Same as unity's, but using a different shadowMap identifier * And with the min strength/intensity removed */ half getOceanSoftShadow(float4 worldPos, float viewPosZ) { fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (worldPos, viewPosZ); float4 coord = GET_SHADOW_COORDINATES(worldPos, cascadeWeights); #if SHADER_API_D3D11 float3 receiverPlaneDepthBias = float3(0.001,0.001,0.001); //custom bias to fix issue with jittering shadows on d3d11 in 1.9, probably not necessary for ocean though #else float3 receiverPlaneDepthBias = 0.0; #endif //why is this slower than the ragular shadow? maybe change this to 3x3? half shadow = ScattererSampleShadowmap_PCF7x7(coord, receiverPlaneDepthBias); //shadow = lerp(_LightShadowData.r, 1.0f, shadow); //min strength/intensity, not used for ocean // Blend between shadow cascades if enabled // // Not working yet with split spheres, and no need when 1 cascade #if UNITY_USE_CASCADE_BLENDING && !defined(SHADOWS_SPLIT_SPHERES) && !defined(SHADOWS_SINGLE_CASCADE) half4 z4 = (float4(viewPosZ,viewPosZ,viewPosZ,viewPosZ) - _LightSplitsNear) / (_LightSplitsFar - _LightSplitsNear); half alpha = dot(z4 * cascadeWeights, half4(1,1,1,1)); //why is it slow? maybe remove this? UNITY_BRANCH if (alpha > 1 - UNITY_CASCADE_BLEND_DISTANCE) { // get alpha to 0..1 range over the blend distance alpha = (alpha - (1 - UNITY_CASCADE_BLEND_DISTANCE)) / UNITY_CASCADE_BLEND_DISTANCE; // sample next cascade cascadeWeights = fixed4(0, cascadeWeights.xyz); coord = GET_SHADOW_COORDINATES(worldPos, cascadeWeights); half shadowNextCascade = UnitySampleShadowmap_PCF3x3(coord, receiverPlaneDepthBias); //shadowNextCascade = lerp(_LightShadowData.r, 1.0f, shadowNextCascade); //min strength/intensity, not used for ocean shadow = lerp(shadow, shadowNextCascade, alpha); } #endif return shadow; } half getOceanShadow(float4 worldPos, float viewPosZ) { //fade value float zDist = dot(_WorldSpaceCameraPos - worldPos, UNITY_MATRIX_V[2].xyz); float fadeDist = UnityComputeShadowFadeDistance(worldPos, zDist); half shadowFade = UnityComputeShadowFade(fadeDist); #if defined (OCEAN_SHADOWS_SOFT) return lerp(getOceanSoftShadow(worldPos, viewPosZ),1.0,shadowFade); #elif defined (OCEAN_SHADOWS_HARD) return lerp(getOceanHardShadow(worldPos, viewPosZ),1.0,shadowFade); #endif } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanShadows.cginc.meta ================================================ fileFormatVersion: 2 guid: e0cb37a014cdcb142af891772a27189c timeCreated: 1545852000 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanUtils.cginc ================================================ uniform float refractionIndex; uniform float3 _Underwater_Color; uniform float3 _Ocean_Color; uniform float transparencyDepth; uniform float skyReflectionStrength; float3 ReflectedSky(float3 V, float3 N, float3 sunDir, float3 earthP) { float3 result = float3(0,0,0); float3 reflectedAngle=reflect(-V,N); reflectedAngle.z=max(reflectedAngle.z,0.0); //hack to avoid unsightly black pixels from downwards reflections result = SkyRadiance3(earthP,reflectedAngle, sunDir); return result; } //TODO: check if can optimize/simplify float3 refractVector(float3 I, float3 N, float ior) { float cosi = dot(I, N); float3 n = N; cosi = -cosi; float eta = 1.0 / ior; float k = 1 - eta * eta * (1 - cosi * cosi); return k < 0 ? 0 : eta * I + (eta * cosi - sqrt(k)) * n; } float3 RefractedSky(float3 V, float3 N, float3 sunDir, float3 earthP) { float3 result = float3(0,0,0); float3 refractedAngle = refractVector(-V, -N, 1/refractionIndex); result = SkyRadiance3(earthP,refractedAngle, sunDir); return result; } //TODO: check if can optimize/simplify float fresnel_dielectric(float3 I, float3 N, float eta) { //compute fresnel reflectance without explicitly computing the refracted direction float c = abs(dot(I, N)); float g = eta * eta - 1.0 + c * c; float result; float g2 =g; g = sqrt(g); float A =(g - c)/(g + c); float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0); result = 0.5 * A * A *(1.0 + B * B); result = (g2>0) ? result : 1.0; // TIR (no refracted component) return result; } //underwater ocean color float3 oceanColor(float3 viewDir, float3 lightDir, float3 surfaceDir) { float angleToLightDir = (dot(viewDir, surfaceDir) + 1 )* 0.5; float3 waterColor = pow(_Underwater_Color, 4.0 *(-1.0 * angleToLightDir + 1.0)); return waterColor; } float getFresnel(float3 V, float3 N, float sigmaSq) { #if defined (UNDERWATER_ON) float fresnel = 1.0 - fresnel_dielectric(V, N, 1/refractionIndex); #else float fresnel = MeanFresnel(V, N, sigmaSq); #endif fresnel = clamp(fresnel,0.0,1.0); return fresnel; } float3 getSkyColor(float fresnel, float3 V, float3 N, float3 L, float3 earthP, float3 skyE, float shadowTerm, float radius) { #if defined (UNDERWATER_ON) return (fresnel * RefractedSky(V, N, L, earthP)); #else #if defined (SKY_REFLECTIONS_ON) float3 skyColor = lerp(skyE / M_PI, ReflectedSky(V, N, L, earthP), skyReflectionStrength); //mix accurate sky reflection and sky irradiance return (fresnel * (skyColor * lerp(0.5,1.0,shadowTerm) + (UNITY_LIGHTMODEL_AMBIENT.rgb*0.07))); #else return (fresnel * (skyE / M_PI * lerp(0.5,1.0,shadowTerm) + (UNITY_LIGHTMODEL_AMBIENT.rgb*0.07))); //sky irradiance only #endif #endif } float3 getOceanColor(float fresnel, float3 V, float3 N, float3 L, float3 earthP, float3 skyE, float shadowTerm) { #if defined (UNDERWATER_ON) float3 ocColor = _sunColor * oceanColor(reflect(-V,N),L,float3(0.0,0.0,1.0)); //reflected ocean color from underwater float waterLightExtinction = length(getSkyExtinction(earthP, L)); return(hdrNoExposure(waterLightExtinction * ocColor) * lerp(0.8,1.0,shadowTerm)); #else return(0.98 * (1.0 - fresnel) * _Ocean_Color * (skyE / M_PI) * lerp(0.3,1.0,shadowTerm)); #endif } float2 getPerturbedUVsAndDepth(float2 depthUV, float3 N, float oceanDistance, out float fragDistance, out float depth) { float2 uv; #if defined (UNDERWATER_ON) uv = depthUV.xy + (N.xy)*0.025 * float2(1.0,10.0); #else uv = depthUV.xy + N.xy*0.025; #endif fragDistance = getScattererFragDistance(uv); depth= fragDistance - oceanDistance; //water depth, ie viewing ray distance in water uv = (depth < 0) ? depthUV.xy : uv; //for refractions, use the normal fragment uv instead the perturbed one if the perturbed one is closer fragDistance = getScattererFragDistance(uv); depth= fragDistance - oceanDistance; #if !defined (UNDERWATER_ON) depth=lerp(depth,transparencyDepth,clamp((oceanDistance-1000.0)/5000.0,0.0,1.0)); //fade out refractions and transparency at distance, to hide swirly artifacts of low precision #endif return uv; } float getTransparencyAlpha(float depth) { float transparencyAlpha=lerp(0.0,1.0,depth/transparencyDepth); transparencyAlpha = (depth < -0.5) ? 1.0 : transparencyAlpha; //fix black edge around antialiased terrain in front of ocean return transparencyAlpha; } float adjustWhiteCapStrengthWithDepth(float _Ocean_WhiteCapStr, float shoreFoam, float depth) { _Ocean_WhiteCapStr = lerp(shoreFoam,_Ocean_WhiteCapStr, clamp(depth*0.2,0.0,1.0)); return ((depth <= 0.0) ? 0.0 : _Ocean_WhiteCapStr); //fixes white outline around objects in front of the ocean } float applyFarWhiteCapStrength(float oceanDistance, float alphaRadius, float _Ocean_WhiteCapStr, float farWhiteCapStr) { float clampFactor= clamp(oceanDistance/alphaRadius,0.0,1.0); //factor to clamp whitecaps return(lerp(_Ocean_WhiteCapStr,farWhiteCapStr,clampFactor)); } float3 getTotalWhiteCapRadiance(float outWhiteCapStr, float jmx, float jSigma2, float3 sunL, float3 N, float3 L, float3 skyE, float shadowTerm) { // get coverage float W = WhitecapCoverage(outWhiteCapStr,jmx,jSigma2); // compute and add whitecap radiance float3 l = (sunL * (max(dot(N, L), 0.0)) + skyE + UNITY_LIGHTMODEL_AMBIENT.rgb * 30) / M_PI; return (float3(W * l * 0.4)* lerp(0.5,1.0,shadowTerm)); } void getPlanetShineContribution(out float3 LsunTotal, out float3 R_ftotTotal, out float3 LseaTotal, out float3 LskyTotal) { // for (int i=0; i<4; ++i) // { // if (planetShineRGB[i].w == 0) break; // // L=normalize(planetShineSources[i].xyz); // SunRadianceAndSkyIrradiance(earthP, N, L, sunL, skyE); // // #if defined (SKY_REFLECTIONS_ON) // Lsky = fresnel * ReflectedSky(V, N, L, earthP); //planet, accurate sky reflections // #else // Lsky = fresnel * skyE / M_PI; //planet, sky irradiance only // #endif // // Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * sunL; // Lsea = RefractedSeaRadiance(V, N, sigmaSq) * _Ocean_Color * skyE / M_PI; // l = (sunL * (max(dot(N, L), 0.0)) + skyE) / M_PI; // R_ftot = float3(W * l * 0.4); // // //if source is not a sun compute intensity of light from angle to light source // float intensity=1; // if (planetShineSources[i].w != 1.0f) // { // intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[i].xyz - earthP),_Ocean_SunDir)),0); // } // // surfaceColor+= abs((Lsun + Lsky + Lsea + R_ftot)*planetShineRGB[i].xyz*planetShineRGB[i].w*intensity); // LsunTotal += Lsun; // R_ftotTotal += R_ftot; // LseaTotal += Lsea; // LskyTotal += Lsky; // } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanUtils.cginc.meta ================================================ fileFormatVersion: 2 guid: a2cc3e5914c2bb345a87c15d0b894ee8 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3.shader ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. */ /* * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. */ /** * Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF * Copyright (c) 2009 INRIA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** * Author: Eric Bruneton * Modified and ported to Unity by Justin Hawkins 2014 * Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2020 */ Shader "Scatterer/OceanWhiteCaps" { SubShader { Tags { "Queue" = "Geometry+100" "RenderType"="Transparent" "IgnoreProjector"="True"} Pass { Tags { "LightMode" = "MainPass" "Queue" = "Geometry+100" "RenderType"="Transparent" "IgnoreProjector"="True"} Blend SrcAlpha OneMinusSrcAlpha Offset 0.0, -0.14 Cull Back ZWrite [_ZwriteVariable] CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag //#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile SKY_REFLECTIONS_OFF SKY_REFLECTIONS_ON #pragma multi_compile UNDERWATER_OFF UNDERWATER_ON #pragma multi_compile OCEAN_SHADOWS_OFF OCEAN_SHADOWS_HARD OCEAN_SHADOWS_SOFT #pragma multi_compile REFRACTIONS_AND_TRANSPARENCY_OFF REFRACTIONS_AND_TRANSPARENCY_ON #pragma multi_compile SCATTERER_MERGED_DEPTH_ON SCATTERER_MERGED_DEPTH_OFF #pragma multi_compile DITHERING_OFF DITHERING_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON #pragma multi_compile DEPTH_BUFFER_MODE_OFF DEPTH_BUFFER_MODE_ON #pragma multi_compile FOAM_OFF FOAM_ON //#pragma multi_compile SCATTERING_ON SCATTERING_OFF #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" #if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT) #include "OceanShadows.cginc" #endif #include "OceanBRDF.cginc" #include "OceanDisplacement3.cginc" #include "OceanUtils.cginc" #include "../ClippingUtils.cginc" #include "../Atmo/Godrays/GodraysCommon.cginc" uniform float offScreenVertexStretch; uniform float4x4 _Globals_ScreenToCamera; uniform float4x4 _Globals_CameraToWorld; uniform float4x4 _Globals_WorldToScreen; uniform float4x4 _Globals_CameraToScreen; uniform float3 _Globals_WorldCameraPos; uniform float4x4 _Globals_WorldToOcean; uniform float4x4 _Globals_OceanToWorld; uniform float3 _Sun_WorldSunDir; uniform float2 _Ocean_MapSize; uniform float4 _Ocean_Choppyness; uniform float3 _Ocean_SunDir; uniform float4 _Ocean_GridSizes; uniform float2 _Ocean_ScreenGridSize; uniform float _Ocean_WhiteCapStr; uniform float farWhiteCapStr; uniform float shoreFoam; uniform sampler3D _Ocean_Variance; uniform sampler2D _Ocean_Map0; uniform sampler2D _Ocean_Map1; uniform sampler2D _Ocean_Map2; uniform sampler2D _Ocean_Map3; uniform sampler2D _Ocean_Map4; uniform sampler2D _Ocean_Foam0; uniform sampler2D _Ocean_Foam1; uniform float alphaRadius; uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out uniform float _ScatteringExposure; uniform float _Alpha_Global; uniform float _SkyExposure; uniform float2 _VarianceMax; uniform float darknessDepth; uniform float3 _planetPos; uniform float _openglThreshold; uniform float _global_depth; uniform float _global_alpha; uniform float _Post_Extinction_Tint; uniform float extinctionThickness; #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) uniform sampler2D ScattererScreenCopyBeforeOcean; //background texture used for refraction #endif #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { float4 pos : SV_POSITION; float2 oceanU : TEXCOORD0; float3 oceanP : TEXCOORD1; float4 screenPos: TEXCOORD2; float4 worldPos : TEXCOORD3; float4 viewPos : TEXCOORD4; float3 sunL : TEXCOORD5; float3 skyE : TEXCOORD6; }; v2f vert(appdata_base v) { float t; float3 cameraDir, oceanDir; float4 vert = v.vertex; vert.xy *= offScreenVertexStretch; float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u; float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u; float3 dP = float3(0, 0, _Ocean_HeightOffset); if(duy.x != 0.0 || duy.y != 0.0) { dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w; // dP.xy += _Ocean_Choppyness.x * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).xy; dP.xy += _Ocean_Choppyness.y * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).zw; dP.xy += _Ocean_Choppyness.z * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).xy; dP.xy += _Ocean_Choppyness.w * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).zw; } v2f OUT; float3x3 otoc = _Ocean_OceanToCamera; float tClamped = clamp(t*0.25, 0.0, 1.0); #if defined (UNDERWATER_ON) dP = lerp(float3(0.0,0.0,0.1),dP,tClamped); //prevents projected grid intersecting near plane #else dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane #endif float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z); OUT.pos = mul(UNITY_MATRIX_P, screenP); OUT.oceanU = u; OUT.oceanP = oceanP; OUT.screenPos = ComputeScreenPos(OUT.pos); OUT.worldPos=mul(_Globals_CameraToWorld , screenP); OUT.viewPos = screenP; #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 OUT.pos = (_PlanetOpacity == 0.0) ? float4(2.0, 2.0, 2.0, 1.0) : OUT.pos; //cull when completely transparent #else OUT.pos = lerp(float4(2.0, 2.0, 2.0, 1.0), OUT.pos, step(0.001,_PlanetOpacity)); //stupid opengl #endif float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0); float3 sunL, skyE; SunRadianceAndSkyIrradiance(earthP, float3(0.0,0.0,1.0), _Ocean_SunDir, sunL, skyE); OUT.sunL = sunL; OUT.skyE = skyE; return OUT; } float4 frag(v2f IN) : SV_Target { float2 u = IN.oceanU; float3 oceanP = IN.oceanP; float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z); float3 V = normalize(oceanCamera - oceanP); float2 slopes = float2(0,0); slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy; slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw; slopes -= oceanP.xy / (_Ocean_Radius + oceanP.z); float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0)); float Jxx = ddx(u.x); float Jxy = ddy(u.x); float Jyx = ddx(u.y); float Jyy = ddy(u.y); float A = Jxx * Jxx + Jyx * Jyx; float B = Jxx * Jxy + Jyx * Jyy; float C = Jxy * Jxy + Jyy * Jyy; const float SCALE = 10.0; float ua = pow(A / SCALE, 0.25); float ub = 0.5 + 0.5 * B / sqrt(A * C); float uc = pow(C / SCALE, 0.25); float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x * _VarianceMax.x; sigmaSq = max(sigmaSq, 2e-5); #if defined (FOAM_ON) // extract mean and variance of the jacobian matrix determinant float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy; float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw; float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy; float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw; float2 jm = jm1+jm2+jm3+jm4; float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0); #endif float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0); float3 sunL = IN.sunL; float3 skyE = IN.skyE; half shadowTerm = 1.0; #if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT) shadowTerm = getOceanShadow (IN.worldPos, -IN.viewPos.z); #endif float fresnel = getFresnel(V, N, sigmaSq); float3 Lsky = getSkyColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm, _Ocean_Radius); float3 Lsea = getOceanColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm); float oceanDistance = length(IN.viewPos); #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) float fragDistance, depth; float2 uv = IN.screenPos.xy / IN.screenPos.w; #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 uv.y = 1.0 - uv.y; #endif uv = getPerturbedUVsAndDepth(uv, N, oceanDistance, fragDistance, depth); _Ocean_WhiteCapStr = adjustWhiteCapStrengthWithDepth(_Ocean_WhiteCapStr, shoreFoam, depth); float transparencyAlpha = getTransparencyAlpha(depth); #else float transparencyAlpha=1.0; #endif float3 R_ftot = float3(0.0,0.0,0.0); #if defined (FOAM_ON) float outWhiteCapStr=applyFarWhiteCapStrength(oceanDistance, alphaRadius, _Ocean_WhiteCapStr, farWhiteCapStr); R_ftot = getTotalWhiteCapRadiance(outWhiteCapStr, jm.x, jSigma2, sunL, N, _Ocean_SunDir, skyE, shadowTerm); #endif float3 Lsun = ReflectedSunRadiance(_Ocean_SunDir, V, N, sigmaSq) * sunL * shadowTerm; #if defined (UNDERWATER_ON) float3 surfaceColor = hdr(abs(Lsea + R_ftot),_ScatteringExposure); #else float3 surfaceColor = hdr(abs(Lsun + Lsea + R_ftot),_ScatteringExposure); Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure); surfaceColor = surfaceColor + (1.0-surfaceColor) * Lsky; #endif float3 LsunTotal = Lsun; float3 R_ftotTotal = R_ftot; float3 LseaTotal = Lsea; float3 LskyTotal = Lsky; #if defined (PLANETSHINE_ON) getPlanetShineContribution(LsunTotal, R_ftotTotal, LseaTotal, LskyTotal); #endif #if SHADER_API_D3D11 bool insideClippingRange = true; #else bool insideClippingRange = oceanFragmentInsideOfClippingRange(-IN.viewPos.z/IN.viewPos.w); #endif #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) transparencyAlpha = max(hdr(LsunTotal + R_ftotTotal,_ScatteringExposure), fresnel+transparencyAlpha) ; //seems about perfect transparencyAlpha = min(transparencyAlpha, 1.0); float3 backGrnd = 0.0; #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 backGrnd = tex2D(ScattererScreenCopyBeforeOcean, (_ProjectionParams.x == 1.0) ? uv : float2(uv.x,1.0-uv.y) ); #else backGrnd = tex2D(ScattererScreenCopyBeforeOcean, uv ); #endif #endif #if defined (UNDERWATER_ON) Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure); float3 transmittance = hdr(R_ftot, _ScatteringExposure); transmittance = clamp(transmittance, float3(0.0,0.0,0.0), float3(1.0,1.0,1.0)); transmittance = transmittance + (1.0-transmittance) * Lsky; //consider not using transmittance but instead background texture, change the refraction angle to have something matching what you would see from underwater float3 finalColor = (1.0 - fresnel) * Lsea; finalColor+=clamp(transmittance * fresnel,float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)); //somehow doing lerp directly breaks opengl #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) backGrnd+=hdr(R_ftotTotal,_ScatteringExposure)*(1-backGrnd); //make foam visible from below as well finalColor = (fragDistance < 750000.0) ? backGrnd : finalColor; #endif float3 Vworld = mul ( _Globals_OceanToWorld, float4(V,0.0)); float3 Lworld = mul ( _Globals_OceanToWorld, float4(_Ocean_SunDir,0.0)); float3 earthCamPos = normalize(float3(_Ocean_CameraPos.xy,0.0) + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0); float underwaterDepth = lerp(1.0,0.0,-_Ocean_CameraPos.z / darknessDepth); float waterLightExtinction = length(getSkyExtinction(earthCamPos, _Ocean_SunDir)); float3 _camPos = _WorldSpaceCameraPos - _planetPos; float3 oceanCol = underwaterDepth * hdrNoExposure(waterLightExtinction * _sunColor * oceanColor(-Vworld,Lworld,normalize(_camPos))); //add planetshine loop here over Ls finalColor= clamp(finalColor, float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)); finalColor= lerp(finalColor, oceanCol, min(length(oceanCamera - oceanP)/transparencyDepth,1.0)); return float4(dither(finalColor, IN.pos),insideClippingRange); #else #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) float3 finalColor = lerp(backGrnd, surfaceColor, transparencyAlpha); //refraction on and not underwater #else float3 finalColor = surfaceColor; //refraction off and not underwater #endif #if defined (DEPTH_BUFFER_MODE_OFF) if (_PlanetOpacity == 1.0) { float3 worldPos= IN.worldPos - _planetPos; worldPos = (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix float3 _camPos = _WorldSpaceCameraPos - _planetPos; float minDistance = length(worldPos-_camPos); #if defined (GODRAYS_ON) float2 godrayUV = IN.screenPos.xy / IN.screenPos.w; float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, godrayUV, 1.0); //trying to find the optical depth from the terrain level float muTerrain = dot(normalize(worldPos), normalize(_camPos - worldPos)); godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance); worldPos = worldPos - godrayDepth * normalize(worldPos-_camPos); #endif float3 inscatter=0.0;float3 extinction=1.0; inscatter = InScattering2(_camPos, worldPos,SUN_DIR,extinction); inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha; float average=(extinction.r+extinction.g+extinction.b)/3; //lerped manually because of an issue with opengl or whatever extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); finalColor*= extinction; finalColor = inscatter*(1-finalColor) + finalColor; } #endif insideClippingRange = (transparencyAlpha == 1.0) ? 1.0 : insideClippingRange; //if no transparency -> render normally, if transparency play with the overlap to hide seams between cameras return float4(dither(finalColor,IN.pos), _PlanetOpacity*insideClippingRange); #endif } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3.shader.meta ================================================ fileFormatVersion: 2 guid: a0fba9bd62d2b5c4bb89c81f58569c58 ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3PixelLights.shader ================================================  /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. */ /* * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. */ /** * Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF * Copyright (c) 2009 INRIA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** * Author: Eric Bruneton * Modified and ported to Unity by Justin Hawkins 2014 * Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2020 */ Shader "Scatterer/OceanWhiteCapsPixelLights" { SubShader { Tags { "Queue" = "Geometry+100" "RenderType"="Transparent" "IgnoreProjector"="True"} Pass { Tags { "LightMode" = "MainPass" "Queue" = "Geometry+100" "RenderType"="Transparent" "IgnoreProjector"="True"} Blend SrcAlpha OneMinusSrcAlpha Offset 0.0, -0.14 Cull Back ZWrite [_ZwriteVariable] CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag //#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile SKY_REFLECTIONS_OFF SKY_REFLECTIONS_ON #pragma multi_compile UNDERWATER_OFF UNDERWATER_ON #pragma multi_compile OCEAN_SHADOWS_OFF OCEAN_SHADOWS_HARD OCEAN_SHADOWS_SOFT #pragma multi_compile REFRACTIONS_AND_TRANSPARENCY_OFF REFRACTIONS_AND_TRANSPARENCY_ON #pragma multi_compile SCATTERER_MERGED_DEPTH_ON SCATTERER_MERGED_DEPTH_OFF #pragma multi_compile DITHERING_OFF DITHERING_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON #pragma multi_compile DEPTH_BUFFER_MODE_OFF DEPTH_BUFFER_MODE_ON #pragma multi_compile FOAM_OFF FOAM_ON //#pragma multi_compile SCATTERING_ON SCATTERING_OFF #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" #if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT) #include "OceanShadows.cginc" #endif #include "OceanBRDF.cginc" #include "OceanDisplacement3.cginc" #include "OceanUtils.cginc" #include "../ClippingUtils.cginc" #include "../Atmo/Godrays/GodraysCommon.cginc" uniform float offScreenVertexStretch; uniform float4x4 _Globals_ScreenToCamera; uniform float4x4 _Globals_CameraToWorld; uniform float4x4 _Globals_WorldToScreen; uniform float4x4 _Globals_CameraToScreen; uniform float3 _Globals_WorldCameraPos; uniform float4x4 _Globals_WorldToOcean; uniform float4x4 _Globals_OceanToWorld; uniform float3 _Sun_WorldSunDir; uniform float2 _Ocean_MapSize; uniform float4 _Ocean_Choppyness; uniform float3 _Ocean_SunDir; uniform float4 _Ocean_GridSizes; uniform float2 _Ocean_ScreenGridSize; uniform float _Ocean_WhiteCapStr; uniform float farWhiteCapStr; uniform float shoreFoam; uniform sampler3D _Ocean_Variance; uniform sampler2D _Ocean_Map0; uniform sampler2D _Ocean_Map1; uniform sampler2D _Ocean_Map2; uniform sampler2D _Ocean_Map3; uniform sampler2D _Ocean_Map4; uniform sampler2D _Ocean_Foam0; uniform sampler2D _Ocean_Foam1; uniform float alphaRadius; uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out uniform float _ScatteringExposure; uniform float _Alpha_Global; uniform float _SkyExposure; uniform float2 _VarianceMax; uniform float darknessDepth; uniform float3 _planetPos; uniform float _openglThreshold; uniform float _global_depth; uniform float _global_alpha; uniform float _Post_Extinction_Tint; uniform float extinctionThickness; #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) uniform sampler2D ScattererScreenCopyBeforeOcean; //background texture used for refraction #endif #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { float4 pos : SV_POSITION; float2 oceanU : TEXCOORD0; float3 oceanP : TEXCOORD1; float4 screenPos: TEXCOORD2; float4 worldPos : TEXCOORD3; float4 viewPos : TEXCOORD4; float3 sunL : TEXCOORD5; float3 skyE : TEXCOORD6; }; v2f vert(appdata_base v) { float t; float3 cameraDir, oceanDir; float4 vert = v.vertex; vert.xy *= offScreenVertexStretch; float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u; float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u; float3 dP = float3(0, 0, _Ocean_HeightOffset); if(duy.x != 0.0 || duy.y != 0.0) { dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w; // dP.xy += _Ocean_Choppyness.x * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).xy; dP.xy += _Ocean_Choppyness.y * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).zw; dP.xy += _Ocean_Choppyness.z * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).xy; dP.xy += _Ocean_Choppyness.w * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).zw; } v2f OUT; float3x3 otoc = _Ocean_OceanToCamera; float tClamped = clamp(t*0.25, 0.0, 1.0); #if defined (UNDERWATER_ON) dP = lerp(float3(0.0,0.0,0.1),dP,tClamped); //prevents projected grid intersecting near plane #else dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane #endif float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z); OUT.pos = mul(UNITY_MATRIX_P, screenP); OUT.oceanU = u; OUT.oceanP = oceanP; OUT.screenPos = ComputeScreenPos(OUT.pos); OUT.worldPos=mul(_Globals_CameraToWorld , screenP); OUT.viewPos = screenP; #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 OUT.pos = (_PlanetOpacity == 0.0) ? float4(2.0, 2.0, 2.0, 1.0) : OUT.pos; //cull when completely transparent #else OUT.pos = lerp(float4(2.0, 2.0, 2.0, 1.0), OUT.pos, step(0.001,_PlanetOpacity)); //stupid opengl #endif float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0); float3 sunL, skyE; SunRadianceAndSkyIrradiance(earthP, float3(0.0,0.0,1.0), _Ocean_SunDir, sunL, skyE); OUT.sunL = sunL; OUT.skyE = skyE; return OUT; } float4 frag(v2f IN) : SV_Target { float2 u = IN.oceanU; float3 oceanP = IN.oceanP; float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z); float3 V = normalize(oceanCamera - oceanP); float2 slopes = float2(0,0); slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy; slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw; slopes -= oceanP.xy / (_Ocean_Radius + oceanP.z); float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0)); float Jxx = ddx(u.x); float Jxy = ddy(u.x); float Jyx = ddx(u.y); float Jyy = ddy(u.y); float A = Jxx * Jxx + Jyx * Jyx; float B = Jxx * Jxy + Jyx * Jyy; float C = Jxy * Jxy + Jyy * Jyy; const float SCALE = 10.0; float ua = pow(A / SCALE, 0.25); float ub = 0.5 + 0.5 * B / sqrt(A * C); float uc = pow(C / SCALE, 0.25); float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x * _VarianceMax.x; sigmaSq = max(sigmaSq, 2e-5); #if defined (FOAM_ON) // extract mean and variance of the jacobian matrix determinant float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy; float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw; float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy; float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw; float2 jm = jm1+jm2+jm3+jm4; float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0); #endif float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0); float3 sunL = IN.sunL; float3 skyE = IN.skyE; half shadowTerm = 1.0; #if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT) shadowTerm = getOceanShadow (IN.worldPos, -IN.viewPos.z); #endif float fresnel = getFresnel(V, N, sigmaSq); float3 Lsky = getSkyColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm, _Ocean_Radius); float3 Lsea = getOceanColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm); float oceanDistance = length(IN.viewPos); #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) float fragDistance, depth; float2 uv = IN.screenPos.xy / IN.screenPos.w; #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 uv.y = 1.0 - uv.y; #endif uv = getPerturbedUVsAndDepth(uv, N, oceanDistance, fragDistance, depth); _Ocean_WhiteCapStr = adjustWhiteCapStrengthWithDepth(_Ocean_WhiteCapStr, shoreFoam, depth); float transparencyAlpha = getTransparencyAlpha(depth); #else float transparencyAlpha=1.0; #endif float3 R_ftot = float3(0.0,0.0,0.0); #if defined (FOAM_ON) float outWhiteCapStr=applyFarWhiteCapStrength(oceanDistance, alphaRadius, _Ocean_WhiteCapStr, farWhiteCapStr); R_ftot = getTotalWhiteCapRadiance(outWhiteCapStr, jm.x, jSigma2, sunL, N, _Ocean_SunDir, skyE, shadowTerm); #endif float3 Lsun = ReflectedSunRadiance(_Ocean_SunDir, V, N, sigmaSq) * sunL * shadowTerm; #if defined (UNDERWATER_ON) float3 surfaceColor = hdr(abs(Lsea + R_ftot),_ScatteringExposure); #else float3 surfaceColor = hdr(abs(Lsun + Lsea + R_ftot),_ScatteringExposure); Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure); surfaceColor = surfaceColor + (1.0-surfaceColor) * Lsky; #endif float3 LsunTotal = Lsun; float3 R_ftotTotal = R_ftot; float3 LseaTotal = Lsea; float3 LskyTotal = Lsky; #if defined (PLANETSHINE_ON) getPlanetShineContribution(LsunTotal, R_ftotTotal, LseaTotal, LskyTotal); #endif #if SHADER_API_D3D11 bool insideClippingRange = true; #else bool insideClippingRange = oceanFragmentInsideOfClippingRange(-IN.viewPos.z/IN.viewPos.w); #endif #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) transparencyAlpha = max(hdr(LsunTotal + R_ftotTotal,_ScatteringExposure), fresnel+transparencyAlpha) ; //seems about perfect transparencyAlpha = min(transparencyAlpha, 1.0); float3 backGrnd = 0.0; // #if defined (DEPTH_BUFFER_MODE_ON) // backGrnd = tex2D(ScattererScreenCopyBeforeOcean, uv ); // #else #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 backGrnd = tex2D(ScattererScreenCopyBeforeOcean, (_ProjectionParams.x == 1.0) ? uv : float2(uv.x,1.0-uv.y) ); #else backGrnd = tex2D(ScattererScreenCopyBeforeOcean, uv ); #endif // #endif #endif #if defined (UNDERWATER_ON) Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure); float3 transmittance = hdr(R_ftot, _ScatteringExposure); transmittance = clamp(transmittance, float3(0.0,0.0,0.0), float3(1.0,1.0,1.0)); transmittance = transmittance + (1.0-transmittance) * Lsky; float3 finalColor = lerp(transmittance,Lsea, 1-fresnel); //consider not using transmittance but instead background texture, change the refraction angle to have something matching what you would see from underwater #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) backGrnd+=hdr(R_ftotTotal,_ScatteringExposure)*(1-backGrnd); //make foam visible from below as well finalColor = (fragDistance < 750000.0) ? backGrnd : finalColor; #endif float3 Vworld = mul ( _Globals_OceanToWorld, float4(V,0.0)); float3 Lworld = mul ( _Globals_OceanToWorld, float4(_Ocean_SunDir,0.0)); float3 earthCamPos = normalize(float3(_Ocean_CameraPos.xy,0.0) + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0); float underwaterDepth = lerp(1.0,0.0,-_Ocean_CameraPos.z / darknessDepth); float waterLightExtinction = length(getSkyExtinction(earthCamPos, _Ocean_SunDir)); float3 _camPos = _WorldSpaceCameraPos - _planetPos; float3 oceanCol = underwaterDepth * hdrNoExposure(waterLightExtinction * _sunColor * oceanColor(-Vworld,Lworld,normalize(_camPos))); //add planetshine loop here over Ls finalColor= clamp(finalColor, float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)); finalColor= lerp(finalColor, oceanCol, min(length(oceanCamera - oceanP)/transparencyDepth,1.0)); return float4(dither(finalColor, IN.pos),insideClippingRange); #else #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) float3 finalColor = lerp(backGrnd, surfaceColor, transparencyAlpha); //refraction on and not underwater #else float3 finalColor = surfaceColor; //refraction off and not underwater #endif #if defined (DEPTH_BUFFER_MODE_OFF) if (_PlanetOpacity == 1.0) { float3 worldPos= IN.worldPos - _planetPos; worldPos = (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix float3 _camPos = _WorldSpaceCameraPos - _planetPos; float minDistance = length(worldPos-_camPos); #if defined (GODRAYS_ON) float2 godrayUV = IN.screenPos.xy / IN.screenPos.w; float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, godrayUV, 1.0); //trying to find the optical depth from the terrain level float muTerrain = dot(normalize(worldPos), normalize(_camPos - worldPos)); godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance); worldPos = worldPos - godrayDepth * normalize(worldPos-_camPos); #endif float3 inscatter=0.0;float3 extinction=1.0; inscatter = InScattering2(_camPos, worldPos,SUN_DIR,extinction); inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha; float average=(extinction.r+extinction.g+extinction.b)/3; //lerped manually because of an issue with opengl or whatever extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); finalColor*= extinction; finalColor = inscatter*(1-finalColor) + finalColor; } #endif insideClippingRange = (transparencyAlpha == 1.0) ? 1.0 : insideClippingRange; //if no transparency -> render normally, if transparency play with the overlap to hide seams between cameras return float4(dither(finalColor,IN.pos), _PlanetOpacity*insideClippingRange); #endif } ENDCG } Pass //forward Add { Tags { "LightMode" = "ForwardAdd" } Blend One OneMinusSrcColor //"reverse" soft-additive Offset 0.0, -0.14 //give a superior depth offset to that of localScattering to prevent scattering that should be behind ocean from appearing in front CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdadd // #pragma multi_compile FOAM_OFF FOAM_ON #include "../Utility.cginc" //#include "AtmosphereNew.cginc" #include "OceanBRDF.cginc" #include "OceanDisplacement3.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" #include "OceanLight.cginc" uniform float offScreenVertexStretch; uniform float4x4 _Globals_ScreenToCamera; uniform float4x4 _Globals_CameraToWorld; uniform float4x4 _Globals_WorldToScreen; uniform float4x4 _Globals_CameraToScreen; uniform float4x4 _Globals_WorldToOcean; uniform float4x4 _Globals_OceanToWorld; uniform float3 _Globals_WorldCameraPos; uniform float2 _Ocean_MapSize; uniform float4 _Ocean_Choppyness; uniform float3 _Ocean_SunDir; uniform float3 _Ocean_Color; uniform float4 _Ocean_GridSizes; uniform float2 _Ocean_ScreenGridSize; uniform float _Ocean_WhiteCapStr; uniform float farWhiteCapStr; uniform sampler3D _Ocean_Variance; uniform sampler2D _Ocean_Map0; uniform sampler2D _Ocean_Map1; uniform sampler2D _Ocean_Map2; uniform sampler2D _Ocean_Map3; uniform sampler2D _Ocean_Map4; uniform sampler2D _Ocean_Foam0; uniform sampler2D _Ocean_Foam1; uniform float alphaRadius; uniform float _ScatteringExposure; uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out uniform float2 _VarianceMax; uniform sampler2D _Sky_Map; struct v2f { float4 pos : SV_POSITION; float2 oceanU : TEXCOORD0; float3 oceanP : TEXCOORD1; LIGHTING_COORDS(2,3) }; v2f vert(appdata_base v) { float t; float3 cameraDir, oceanDir; float4 vert = v.vertex; vert.xy *= offScreenVertexStretch; float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u; float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u; float3 dP = float3(0, 0, _Ocean_HeightOffset); if(duy.x != 0.0 || duy.y != 0.0) { float4 GRID_SIZES = _Ocean_GridSizes; float4 CHOPPYNESS = _Ocean_Choppyness; dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.x, dux / GRID_SIZES.x, duy / GRID_SIZES.x, _Ocean_MapSize).x; dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.y, dux / GRID_SIZES.y, duy / GRID_SIZES.y, _Ocean_MapSize).y; dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.z, dux / GRID_SIZES.z, duy / GRID_SIZES.z, _Ocean_MapSize).z; dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.w, dux / GRID_SIZES.w, duy / GRID_SIZES.w, _Ocean_MapSize).w; dP.xy += CHOPPYNESS.x * Tex2DGrad(_Ocean_Map3, u / GRID_SIZES.x, dux / GRID_SIZES.x, duy / GRID_SIZES.x, _Ocean_MapSize).xy; dP.xy += CHOPPYNESS.y * Tex2DGrad(_Ocean_Map3, u / GRID_SIZES.y, dux / GRID_SIZES.y, duy / GRID_SIZES.y, _Ocean_MapSize).zw; dP.xy += CHOPPYNESS.z * Tex2DGrad(_Ocean_Map4, u / GRID_SIZES.z, dux / GRID_SIZES.z, duy / GRID_SIZES.z, _Ocean_MapSize).xy; dP.xy += CHOPPYNESS.w * Tex2DGrad(_Ocean_Map4, u / GRID_SIZES.w, dux / GRID_SIZES.w, duy / GRID_SIZES.w, _Ocean_MapSize).zw; } v2f OUT; float3x3 otoc = _Ocean_OceanToCamera; float tClamped = clamp(t*0.25, 0.0, 1.0); dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space? float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z); OUT.pos = mul(_Globals_CameraToScreen, screenP); OUT.pos.y = OUT.pos.y *_ProjectionParams.x; OUT.oceanU = u; OUT.oceanP = oceanP; float4 worldPos=mul(_Globals_CameraToWorld , screenP); OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(OUT); OUT.pos = (_PlanetOpacity == 1.0) ? OUT.pos : float4(2.0, 2.0, 2.0, 1.0) ; //cull when planet starts fading out return OUT; } float4 frag(v2f IN) : COLOR { float radius = _Ocean_Radius; float2 u = IN.oceanU; float3 oceanP = IN.oceanP; float3 earthCamera = float3(0.0, 0.0, _Ocean_CameraPos.z + radius); float3 earthP = normalize(oceanP + float3(0.0, 0.0, radius)) * (radius + 10.0); float dist=length(earthP-earthCamera); float clampFactor= clamp(dist/alphaRadius,0.0,1.0); float outWhiteCapStr=lerp(_Ocean_WhiteCapStr,farWhiteCapStr,clampFactor); float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z); float3 V = normalize(oceanCamera - oceanP); float2 slopes = float2(0,0); slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy; slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw; slopes -= oceanP.xy / (radius + oceanP.z); float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0)); if (dot(V, N) < 0.0) { N = reflect(N, V); // reflects backfacing normals } float Jxx = ddx(u.x); float Jxy = ddy(u.x); float Jyx = ddx(u.y); float Jyy = ddy(u.y); float A = Jxx * Jxx + Jyx * Jyx; float B = Jxx * Jxy + Jyx * Jyy; float C = Jxy * Jxy + Jyy * Jyy; const float SCALE = 10.0; float ua = pow(A / SCALE, 0.25); float ub = 0.5 + 0.5 * B / sqrt(A * C); float uc = pow(C / SCALE, 0.25); // float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x; float2 sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).xy * _VarianceMax; sigmaSq = max(sigmaSq, 2e-5); float atten=LIGHT_ATTENUATION(IN)*15; float3 Lsky; Lsky = MeanFresnel(V, N, sigmaSq) * atten / M_PI; float3 oceanL= mul(_Globals_WorldToOcean, _WorldSpaceLightPos0); float3 L = normalize(oceanL - oceanP); //light dir in ocean space, find it float3 Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * atten; float3 Lsea = RefractedSeaRadiance(V, N, sigmaSq) * _Ocean_Color * atten; //#if defined (FOAM_ON) // // extract mean and variance of the jacobian matrix determinant // float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy; // float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw; // float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy; // float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw; // float2 jm = jm1+jm2+jm3+jm4; // float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0); // // // get coverage // float W = WhitecapCoverage(outWhiteCapStr,jm.x,jSigma2); // // // compute and add whitecap radiance // // float3 l = (atten * (max(dot(N, L), 0.0))) / M_PI; // // float3 R_ftot = float3(W * l * 0.4); //#endif //float3 surfaceColor = (Lsun + Lsky + Lsea + R_ftot) * _LightColor0.rgb; float3 surfaceColor = (Lsun + Lsky + Lsea) * _LightColor0.rgb; float3 finalColor= surfaceColor; return float4(hdr(finalColor,_ScatteringExposure), 1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3PixelLights.shader.meta ================================================ fileFormatVersion: 2 guid: 8a653817be39efa48bd2461f691b7249 timeCreated: 1474705423 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3VertexSearch.shader ================================================ /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. */ /* * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. */ /** * Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF * Copyright (c) 2009 INRIA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** * Author: Eric Bruneton * Modified and ported to Unity by Justin Hawkins 2014 * Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2020 */ Shader "Scatterer/OceanWhiteCapsVertexSearch" { SubShader { Tags { "Queue" = "Geometry+100" "RenderType"="Transparent" "IgnoreProjector"="True"} Pass { Tags { "Queue" = "Geometry+100" "RenderType"="Transparent" "IgnoreProjector"="True"} Blend SrcAlpha OneMinusSrcAlpha Offset 0.0, -0.14 Cull Back ZWrite [_ZwriteVariable] CGPROGRAM #include "UnityCG.cginc" #pragma glsl #pragma target 3.0 #pragma vertex vert #pragma fragment frag //#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON #pragma multi_compile SKY_REFLECTIONS_OFF SKY_REFLECTIONS_ON #pragma multi_compile UNDERWATER_OFF UNDERWATER_ON #pragma multi_compile OCEAN_SHADOWS_OFF OCEAN_SHADOWS_HARD OCEAN_SHADOWS_SOFT #pragma multi_compile REFRACTIONS_AND_TRANSPARENCY_OFF REFRACTIONS_AND_TRANSPARENCY_ON #pragma multi_compile SCATTERER_MERGED_DEPTH_ON SCATTERER_MERGED_DEPTH_OFF #pragma multi_compile DITHERING_OFF DITHERING_ON #pragma multi_compile GODRAYS_OFF GODRAYS_ON //#pragma multi_compile SCATTERING_ON SCATTERING_OFF #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" #if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT) #include "OceanShadows.cginc" #endif #include "OceanBRDF.cginc" #include "OceanDisplacement3.cginc" #include "OceanUtils.cginc" #include "../ClippingUtils.cginc" #include "../Atmo/Godrays/GodraysCommon.cginc" uniform float offScreenVertexStretch; uniform float4x4 _Globals_ScreenToCamera; uniform float4x4 _Globals_CameraToWorld; uniform float4x4 _Globals_WorldToScreen; uniform float4x4 _Globals_CameraToScreen; uniform float3 _Globals_WorldCameraPos; uniform float4x4 _Globals_WorldToOcean; uniform float4x4 _Globals_OceanToWorld; uniform float3 _Sun_WorldSunDir; uniform float2 _Ocean_MapSize; uniform float4 _Ocean_Choppyness; uniform float3 _Ocean_SunDir; uniform float4 _Ocean_GridSizes; uniform float2 _Ocean_ScreenGridSize; uniform float _Ocean_WhiteCapStr; uniform float farWhiteCapStr; uniform float shoreFoam; uniform sampler3D _Ocean_Variance; uniform sampler2D _Ocean_Map0; uniform sampler2D _Ocean_Map1; uniform sampler2D _Ocean_Map2; uniform sampler2D _Ocean_Map3; uniform sampler2D _Ocean_Map4; uniform sampler2D _Ocean_Foam0; uniform sampler2D _Ocean_Foam1; uniform float alphaRadius; uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out uniform float _ScatteringExposure; uniform float _Alpha_Global; uniform float _SkyExposure; uniform float2 _VarianceMax; uniform float darknessDepth; uniform float3 _planetPos; uniform float _openglThreshold; uniform float _global_depth; uniform float _global_alpha; uniform float _Post_Extinction_Tint; uniform float extinctionThickness; #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) uniform sampler2D ScattererScreenCopy; //background texture used for refraction #endif #if defined (GODRAYS_ON) uniform sampler2D _godrayDepthTexture; uniform float _godrayStrength; #endif #if defined (PLANETSHINE_ON) uniform float4x4 planetShineSources; uniform float4x4 planetShineRGB; #endif struct v2f { //float4 pos : SV_POSITION; float2 oceanU : TEXCOORD0; float3 oceanP : TEXCOORD1; float4 screenPos : TEXCOORD2; float4 worldPos : TEXCOORD3; float4 viewPos :TEXCOORD4; }; float2 SampleDisplacement(float2 oceanPos) { float2 displacement = 0; displacement += _Ocean_Choppyness.x * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.x,0.0, 0.0) ).xy; displacement += _Ocean_Choppyness.y * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.y,0.0, 0.0) ).zw; displacement += _Ocean_Choppyness.z * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.z,0.0, 0.0) ).xy; displacement += _Ocean_Choppyness.w * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.w,0.0, 0.0) ).zw; return displacement; } v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { float t; float3 cameraDir, oceanDir; float4 vert = v.vertex; vert.xy *= offScreenVertexStretch; float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u; float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u; //instead of using this u, t and oceanDir, need to do a search for the oceanPos that when displaced gives me this position, then apply no displacement here only up //knowing that you need dux and duy for every search step though is depressing float3 dP = float3(0, 0, _Ocean_HeightOffset); if(duy.x != 0.0 || duy.y != 0.0) //wtf is this condition even { //test all of these without tex2dgrad? I don't remember if they make a difference //yep they do, a lot more shimmering without them // dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x; // dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y; // dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z; // dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w; // // // dP.xy += _Ocean_Choppyness.x * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).xy; // dP.xy += _Ocean_Choppyness.y * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).zw; // dP.xy += _Ocean_Choppyness.z * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).xy; // dP.xy += _Ocean_Choppyness.w * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).zw; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.x, 0.0, 0.0)).x; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.y, 0.0, 0.0)).y; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.z, 0.0, 0.0)).z; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.w, 0.0, 0.0)).w; // // dP.xy += _Ocean_Choppyness.x * tex2Dlod(_Ocean_Map3, float4( u / _Ocean_GridSizes.x, 0.0, 0.0)).xy; // dP.xy += _Ocean_Choppyness.y * tex2Dlod(_Ocean_Map3, float4( u / _Ocean_GridSizes.y, 0.0, 0.0)).zw; // dP.xy += _Ocean_Choppyness.z * tex2Dlod(_Ocean_Map4, float4( u / _Ocean_GridSizes.z, 0.0, 0.0)).xy; // dP.xy += _Ocean_Choppyness.w * tex2Dlod(_Ocean_Map4, float4( u / _Ocean_GridSizes.w, 0.0, 0.0)).zw; } float precisionRequired = 0.00; float2 currentPosition = u; float2 displacement = SampleDisplacement (currentPosition); float2 resultingPosition = currentPosition + displacement; for (int i = 0; i < 50; i++) { if (length(resultingPosition - u) <= precisionRequired) break; float2 newPosition = currentPosition - (resultingPosition - u); float2 newDisplacement = SampleDisplacement (newPosition); float2 newResultingPosition = newPosition + newDisplacement; currentPosition = newPosition; resultingPosition = newResultingPosition; } u = currentPosition; //t, cameraDir and oceanDir need to be recalculated here // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.x, 0.0, 0.0)).x; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.y, 0.0, 0.0)).y; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.z, 0.0, 0.0)).z; // dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.w, 0.0, 0.0)).w; //HACK, dux and duy no longer match u but might end up looking ok still dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z; dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w; //still can see edges somehow? //even though only displacing up can still see edges, need the stuff that is behind the camera to be displaced up to come into view when tilted //need the projector to cover from the camera position to where it's far plane intersects the horizon (you know what I mean) //then combine that with my search method (though it seems buggy here somehow?) v2f OUT; float3x3 otoc = _Ocean_OceanToCamera; float tClamped = clamp(t*0.25, 0.0, 1.0); #if defined (UNDERWATER_ON) dP = lerp(float3(0.0,0.0,0.1),dP,tClamped); //prevents projected grid intersecting near plane #else dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane #endif // float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space // float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z); float3 oceanP = float3(u-_Ocean_CameraPos.xy, dP.z); float4 screenP = mul(_Ocean_OceanToCamera, float4(oceanP,1.0)); //position in camera space outpos = mul(UNITY_MATRIX_P, screenP); OUT.oceanU = u; OUT.oceanP = oceanP; OUT.screenPos = ComputeScreenPos(outpos); OUT.worldPos=mul(_Globals_CameraToWorld , screenP); OUT.viewPos = screenP; outpos = (_PlanetOpacity == 0.0) ? float4(2.0, 2.0, 2.0, 1.0) : outpos; //cull when completely transparent return OUT; } float4 frag(v2f IN, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target { float3 L = _Ocean_SunDir; float radius = _Ocean_Radius; float2 u = IN.oceanU; float3 oceanP = IN.oceanP; float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z); float3 V = normalize(oceanCamera - oceanP); float2 slopes = float2(0,0); slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy; slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy; slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw; slopes -= oceanP.xy / (radius + oceanP.z); float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0)); float Jxx = ddx(u.x); float Jxy = ddy(u.x); float Jyx = ddx(u.y); float Jyy = ddy(u.y); float A = Jxx * Jxx + Jyx * Jyx; float B = Jxx * Jxy + Jyx * Jyy; float C = Jxy * Jxy + Jyy * Jyy; const float SCALE = 10.0; float ua = pow(A / SCALE, 0.25); float ub = 0.5 + 0.5 * B / sqrt(A * C); float uc = pow(C / SCALE, 0.25); float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x * _VarianceMax.x; sigmaSq = max(sigmaSq, 2e-5); // extract mean and variance of the jacobian matrix determinant float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy; float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw; float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy; float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw; float2 jm = jm1+jm2+jm3+jm4; float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0); float3 earthP = normalize(oceanP + float3(0.0, 0.0, radius)) * (radius + 10.0); float3 sunL, skyE, Lsky; SunRadianceAndSkyIrradiance(earthP, N, L, _sunColor, sunL, skyE); //only thing I can think of that could potebtially be moved to vertex shader without a significant loss of quality? half shadowTerm = 1.0; #if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT) shadowTerm = getOceanShadow (IN.worldPos, -IN.viewPos.z); #endif float fresnel = getFresnel(V, N, sigmaSq); Lsky = getSkyColor(fresnel, V, N, L, earthP, skyE, shadowTerm, radius, _sunColor, 1.0); float3 Lsea = getOceanColor(fresnel, V, N, L, earthP, skyE, shadowTerm, _sunColor); float oceanDistance = length(IN.viewPos); #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) float fragDistance, depth; float2 uv = getPerturbedUVsAndDepth(IN.screenPos.xy / IN.screenPos.w, N, oceanDistance, fragDistance, depth); _Ocean_WhiteCapStr = adjustWhiteCapStrengthWithDepth(_Ocean_WhiteCapStr, shoreFoam, depth); float transparencyAlpha = getTransparencyAlpha(depth); #else float transparencyAlpha=1.0; #endif float outWhiteCapStr=applyFarWhiteCapStrength(oceanDistance, alphaRadius, _Ocean_WhiteCapStr, farWhiteCapStr); float3 R_ftot = getTotalWhiteCapRadiance(outWhiteCapStr, jm.x, jSigma2, sunL, N, L, skyE, shadowTerm, 1.0); float3 Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * sunL * shadowTerm; #if defined (UNDERWATER_ON) float3 surfaceColor = hdr(abs(Lsea + R_ftot),_ScatteringExposure); #else float3 surfaceColor = hdr(abs(Lsun + Lsea + R_ftot),_ScatteringExposure); Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure); surfaceColor = surfaceColor + (1.0-surfaceColor) * Lsky; #endif float3 LsunTotal = Lsun; float3 R_ftotTotal = R_ftot; float3 LseaTotal = Lsea; float3 LskyTotal = Lsky; // #if defined (PLANETSHINE_ON) // // getPlanetShineContribution(LsunTotal, R_ftotTotal, LseaTotal, LskyTotal); // #endif bool insideClippingRange = oceanFragmentInsideOfClippingRange(-IN.viewPos.z/IN.viewPos.w); #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) transparencyAlpha = max(hdr(LsunTotal + R_ftotTotal,_ScatteringExposure), fresnel+transparencyAlpha) ; //seems about perfect transparencyAlpha = min(transparencyAlpha, 1.0); #if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12 float3 backGrnd = tex2D(ScattererScreenCopy, (_ProjectionParams.x == 1.0) ? float2(uv.x,1.0-uv.y): uv ); #else float3 backGrnd = tex2D(ScattererScreenCopy, uv ); #endif #endif #if defined (UNDERWATER_ON) Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure); float3 transmittance = hdr(R_ftot, _ScatteringExposure); transmittance = clamp(transmittance, float3(0.0,0.0,0.0), float3(1.0,1.0,1.0)); transmittance = transmittance + (1.0-transmittance) * Lsky; float3 finalColor = lerp(transmittance,Lsea, 1-fresnel); //consider not using transmittance but instead background texture, change the refraction angle to have something matching what you would see from underwater #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) backGrnd+=hdr(R_ftotTotal,_ScatteringExposure)*(1-backGrnd); //make foam visible from below as well finalColor = (fragDistance < 750000.0) ? backGrnd : finalColor; #endif float3 Vworld = mul ( _Globals_OceanToWorld, float4(V,0.0)); float3 Lworld = mul ( _Globals_OceanToWorld, float4(L,0.0)); float3 earthCamPos = normalize(float3(_Ocean_CameraPos.xy,0.0) + float3(0.0, 0.0, radius)) * (radius + 10.0); float underwaterDepth = lerp(1.0,0.0,-_Ocean_CameraPos.z / darknessDepth); float waterLightExtinction = length(getSkyExtinction(earthCamPos, L)); float3 _camPos = _WorldSpaceCameraPos - _planetPos; float3 oceanCol = underwaterDepth * hdrNoExposure(waterLightExtinction * _sunColor * oceanColor(-Vworld,Lworld,normalize(_camPos))); //add planetshine loop here over Ls finalColor= clamp(finalColor, float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)); finalColor= lerp(finalColor, oceanCol, min(length(oceanCamera - oceanP)/transparencyDepth,1.0)); return float4(dither(finalColor, screenPos),insideClippingRange); #else #if defined (REFRACTIONS_AND_TRANSPARENCY_ON) float3 finalColor = lerp(backGrnd, surfaceColor, transparencyAlpha); //refraction on and not underwater #else float3 finalColor = surfaceColor; //refraction off and not underwater #endif if (_PlanetOpacity == 1.0) { float3 worldPos= IN.worldPos - _planetPos; worldPos = (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix float3 _camPos = _WorldSpaceCameraPos - _planetPos; float minDistance = length(worldPos-_camPos); #if defined (GODRAYS_ON) float2 godrayUV = IN.screenPos.xy / IN.screenPos.w; float godrayDepth = 0.0; godrayDepth = sampleGodrayDepth(_godrayDepthTexture, godrayUV, 1.0); //trying to find the optical depth from the terrain level float muTerrain = dot(normalize(worldPos), normalize(_camPos - worldPos)); godrayDepth = _godrayStrength * DistanceFromOpticalDepth((Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance); worldPos = worldPos - godrayDepth * normalize(worldPos-_camPos); #endif float3 inscatter=0.0;float3 extinction=1.0; inscatter = InScattering(_camPos, worldPos, SUN_DIR, _sunColor, extinction); inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha; float average=(extinction.r+extinction.g+extinction.b)/3; //lerped manually because of an issue with opengl or whatever extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average); extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) ); finalColor*= extinction; finalColor = inscatter*(1-finalColor) + finalColor; } insideClippingRange = (transparencyAlpha == 1.0) ? 1.0 : insideClippingRange; //if no transparency -> render normally, if transparency play with the overlap to hide seams between cameras return float4(dither(finalColor,screenPos), _PlanetOpacity*insideClippingRange); #endif } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3VertexSearch.shader.meta ================================================ fileFormatVersion: 2 guid: 1a7a541ac0259ac4e8570ac8c3510dfe ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/ReadData.compute ================================================  //NOTE - Not every kernel has been tested uint _Width; uint _Height; uint _Depth; uint _IdxX; uint _IdxY; uint _IdxZ; float4 _UV; Texture2D _Tex2D; Texture3D _Tex3D; SamplerState _LinearClamp; //-----------------------------------------------------------------------// //-- read from 1 channel 2D render texture --// #pragma kernel read2DC1 RWStructuredBuffer _Buffer2DC1; [numthreads(8,8,1)] void read2DC1(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width; if(id.x < _Width && id.y < _Height) _Buffer2DC1[idx] = _Tex2D[id.xy].x; } //-- read from 2 channel 2D render texture --// #pragma kernel read2DC2 RWStructuredBuffer _Buffer2DC2; [numthreads(8,8,1)] void read2DC2(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width; if(id.x < _Width && id.y < _Height) _Buffer2DC2[idx] = _Tex2D[id.xy].xy; } //-- read from 3 channel 2D render texture --// #pragma kernel read2DC3 RWStructuredBuffer _Buffer2DC3; [numthreads(8,8,1)] void read2DC3(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width; if(id.x < _Width && id.y < _Height) _Buffer2DC3[idx] = _Tex2D[id.xy].xyz; } //-- read from 4 channel 2D render texture --// #pragma kernel read2DC4 RWStructuredBuffer _Buffer2DC4; [numthreads(8,8,1)] void read2DC4(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width; if(id.x < _Width && id.y < _Height) _Buffer2DC4[idx] = _Tex2D[id.xy]; } //-- read single pixel from 2D render texure. Always reads all 4 channes --// #pragma kernel readSingle2D RWStructuredBuffer _BufferSingle2D; [numthreads(1,1,1)] void readSingle2D(uint3 id : SV_DispatchThreadID) { _BufferSingle2D[0] = _Tex2D[uint2(_IdxX,_IdxY)]; } //-- read single pixel from 2D render texure using bilinear filtering. Always reads all 4 channes --// #pragma kernel readSingleBilinear2D [numthreads(1,1,1)] void readSingleBilinear2D(uint3 id : SV_DispatchThreadID) { _BufferSingle2D[0] = _Tex2D.SampleLevel(_LinearClamp, _UV.xy, 0); } //-----------------------------------------------------------------------// //-- read from 1 channel 3D render texture --// #pragma kernel read3DC1 RWStructuredBuffer _Buffer3DC1; [numthreads(8,8,8)] void read3DC1(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width + id.z * _Width * _Height; if(id.x < _Width && id.y < _Height && id.z < _Depth) _Buffer3DC1[idx] = _Tex3D[id].x; } //-- read from 2 channel 3D render texture --// #pragma kernel read3DC2 RWStructuredBuffer _Buffer3DC2; [numthreads(8,8,8)] void read3DC2(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width + id.z * _Width * _Height; if(id.x < _Width && id.y < _Height && id.z < _Depth) _Buffer3DC2[idx] = _Tex3D[id].xy; } //-- read from 3 channel 3D render texture --// #pragma kernel read3DC3 RWStructuredBuffer _Buffer3DC3; [numthreads(8,8,8)] void read3DC3(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width + id.z * _Width * _Height; if(id.x < _Width && id.y < _Height && id.z < _Depth) _Buffer3DC3[idx] = _Tex3D[id].xyz; } //-- read from 4 channel 3D render texture --// #pragma kernel read3DC4 RWStructuredBuffer _Buffer3DC4; [numthreads(8,8,8)] void read3DC4(uint3 id : SV_DispatchThreadID) { int idx = id.x + id.y * _Width + id.z * _Width * _Height; if(id.x < _Width && id.y < _Height && id.z < _Depth) _Buffer3DC4[idx] = _Tex3D[id]; } //-- read single pixel from 3D render texure. Always reads all 4 channes --// #pragma kernel readSingle3D RWStructuredBuffer _BufferSingle3D; [numthreads(1,1,1)] void readSingle3D(uint3 id : SV_DispatchThreadID) { _BufferSingle3D[0] = _Tex3D[uint3(_IdxX,_IdxY,_IdxZ)]; } //-- read single pixel from 3D render texure using bilinear filtering. Always reads all 4 channes --// #pragma kernel readSingleBilinear3D [numthreads(1,1,1)] void readSingleBilinear3D(uint3 id : SV_DispatchThreadID) { _BufferSingle3D[0] = _Tex3D.SampleLevel(_LinearClamp, _UV.xyz, 0); } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/ReadData.compute.meta ================================================ fileFormatVersion: 2 guid: ecc396d20671d454e8020aa864197779 ComputeShaderImporter: externalObjects: {} currentAPIMask: 4 userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/SlopeVariance.compute ================================================ #pragma kernel CSMain Texture2D _Spectrum01; Texture2D _Spectrum23; float4 _GridSizes; float _SlopeVarianceDelta; float _Size; float _VarianceSize; RWTexture3D des; float getSlopeVariances(float2 k, float A, float B, float C, float2 spectrumSample) { float w = 1.0 - exp(A * k.x * k.x + B * k.x * k.y + C * k.y * k.y); float2 kw = k * w; return dot(kw, kw) * dot(spectrumSample, spectrumSample) * 2.0; } [numthreads(4,4,4)] void CSMain (uint3 id : SV_DispatchThreadID) { const float SCALE = 10.0; const float M_PI = 3.14159265; float a = id.x; float b = id.y; float c = id.z; float A = pow(a / (_VarianceSize - 1.0), 4.0) * SCALE; float C = pow(c / (_VarianceSize - 1.0), 4.0) * SCALE; float B = (2.0 * b / (_VarianceSize - 1.0) - 1.0) * sqrt(A * C); A = -0.5 * A; B = -B; C = -0.5 * C; float slopeVariances = _SlopeVarianceDelta; int size = _Size; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { int i = x >= _Size / 2.0 ? x - size : x; int j = y >= _Size / 2.0 ? y - size : y; float2 k = 2.0 * M_PI * float2(i, j); float4 spectrum01 = _Spectrum01[uint2(x,y)]; float4 spectrum23 = _Spectrum23[uint2(x,y)]; slopeVariances += getSlopeVariances(k / _GridSizes.x, A, B, C, spectrum01.xy); slopeVariances += getSlopeVariances(k / _GridSizes.y, A, B, C, spectrum01.zw); slopeVariances += getSlopeVariances(k / _GridSizes.z, A, B, C, spectrum23.xy); slopeVariances += getSlopeVariances(k / _GridSizes.w, A, B, C, spectrum23.zw); } } des[id] = slopeVariances; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/SlopeVariance.compute.meta ================================================ fileFormatVersion: 2 guid: 7004c8cc6d477784e8d85fbad56de5f8 ComputeShaderImporter: externalObjects: {} currentAPIMask: 131076 userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterDepthBuffer.shader ================================================ Shader "Scatterer/UnderwaterScatterDepthBuffer" { SubShader { Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Pass { Cull Off ZTest Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" uniform sampler2D ScattererScreenCopy; uniform sampler2D ScattererDepthCopy; float4x4 CameraToWorld; #pragma multi_compile DITHERING_OFF DITHERING_ON uniform float3 _planetPos; uniform float3 _Underwater_Color; uniform float transparencyDepth; uniform float darknessDepth; struct v2f { float4 screenPos : TEXCOORD0; float waterLightExtinction : TEXCOORD1; }; v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { v2f o; #if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0); #else outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0); #endif o.screenPos = ComputeScreenPos(outpos); float3 _camPos = _WorldSpaceCameraPos - _planetPos; o.waterLightExtinction = length(getSkyExtinction(normalize(_camPos + 10.0) * Rg , SUN_DIR)); return o; } float3 oceanColor(float3 viewDir, float3 lightDir, float3 surfaceDir) { float angleToLightDir = (dot(viewDir, surfaceDir) + 1 )* 0.5; float3 waterColor = pow(_Underwater_Color, 4.0 *(-1.0 * angleToLightDir + 1.0)); return waterColor; } struct fout { float4 color : COLOR; float depth : DEPTH; }; fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) { float2 uv = i.screenPos.xy / i.screenPos.w; #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;} #endif float zdepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0)); float3 worldPosRelCam = getPreciseWorldPosFromDepth(i.screenPos.xy / i.screenPos.w, zdepth, CameraToWorld) - _WorldSpaceCameraPos; float fragDistance = length(worldPosRelCam); float3 worldViewDir = worldPosRelCam / fragDistance; float3 _camPos = _WorldSpaceCameraPos - _planetPos; float underwaterDepth = Rg - length(_camPos); underwaterDepth = lerp(1.0,0.0,underwaterDepth / darknessDepth); float3 waterColor= underwaterDepth * hdrNoExposure(i.waterLightExtinction * _sunColor * oceanColor(worldViewDir,SUN_DIR,normalize(_camPos))); float alpha = min(fragDistance/transparencyDepth,1.0); float3 backGrnd = tex2Dlod(ScattererScreenCopy, float4(uv.x, uv.y,0.0,0.0)); backGrnd = dither(waterColor, screenPos) * alpha + (1.0 - alpha) * backGrnd; fout output; output.color = float4(backGrnd,1.0); output.depth = zdepth; return output; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterDepthBuffer.shader.meta ================================================ fileFormatVersion: 2 guid: a132bd53f9677ee489dac2f1da2b05ea ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterProjector.shader ================================================  Shader "Scatterer/UnderwaterScatterProjector" { SubShader { Tags {"Queue" = "Transparent-5" "IgnoreProjector" = "True" "RenderType" = "Transparent"} Pass { //Cull Front Cull Back ZTest LEqual ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #pragma multi_compile DITHERING_OFF DITHERING_ON uniform float3 _planetPos; uniform float3 _Underwater_Color; uniform float transparencyDepth; uniform float darknessDepth; struct v2f { float3 viewPos:TEXCOORD0; float3 viewDir:TEXCOORD1; float3 worldPos:TEXCOORD2; }; v2f vert(appdata_base v, out float4 outpos: SV_POSITION) { v2f o; outpos = UnityObjectToClipPos(v.vertex); o.viewPos = UnityObjectToViewPos(v.vertex.xyz); o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz; o.viewDir = o.worldPos - _WorldSpaceCameraPos; o.worldPos = o.worldPos - _planetPos; return o; } float3 oceanColor(float3 viewDir, float3 lightDir, float3 surfaceDir) { float angleToLightDir = (dot(viewDir, surfaceDir) + 1 )* 0.5; float3 waterColor = pow(_Underwater_Color, 4.0 *(-1.0 * angleToLightDir + 1.0)); return waterColor; } half4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target { float fragDistance = length(i.viewPos); float3 rayDir=normalize(i.viewDir); float3 _camPos = _WorldSpaceCameraPos - _planetPos; float waterLightExtinction = length(getSkyExtinction(normalize(_camPos + 10.0) * Rg , SUN_DIR)); float underwaterDepth = Rg - length(_camPos); underwaterDepth = lerp(1.0,0.0,underwaterDepth / darknessDepth); float3 waterColor= underwaterDepth * hdrNoExposure( waterLightExtinction * _sunColor * oceanColor(rayDir,SUN_DIR,normalize(_camPos))); float alpha = min(fragDistance/transparencyDepth,1.0); return float4(dither(waterColor, screenPos), alpha); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterProjector.shader.meta ================================================ fileFormatVersion: 2 guid: f1c6f7ed858be004eb1c56dada7ee838 timeCreated: 1550574813 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/WhiteCapsPrecompute0.shader ================================================ // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Proland/Ocean/WhiteCapsPrecompute0" { SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _Map5, _Map6, _Map7; uniform float4 _Choppyness; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } float4 frag(v2f IN): COLOR { float2 uv = IN.uv; // store Jacobian coeff value and variance float4 Jxx = _Choppyness*tex2D(_Map5, uv); float4 Jyy = _Choppyness*tex2D(_Map6, uv); float4 Jxy = _Choppyness*_Choppyness*tex2D(_Map7, uv); // Store partial jacobians float4 res = 0.25 + Jxx + Jyy + _Choppyness*Jxx*Jyy - Jxy*Jxy; float4 res2 = res*res; float4 col0 = float4(res.x, res2.x, res.y, res2.y); // OUT.col1 = float4(res.z, res2.z, res.w, res2.w); return col0; } ENDCG } Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform sampler2D _Map5, _Map6, _Map7; uniform float4 _Choppyness; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } float4 frag(v2f IN): COLOR { float2 uv = IN.uv; // store Jacobian coeff value and variance float4 Jxx = _Choppyness*tex2D(_Map5, uv); float4 Jyy = _Choppyness*tex2D(_Map6, uv); float4 Jxy = _Choppyness*_Choppyness*tex2D(_Map7, uv); // Store partial jacobians float4 res = 0.25 + Jxx + Jyy + _Choppyness*Jxx*Jyy - Jxy*Jxy; float4 res2 = res*res; // float4 col0 = float4(res.x, res2.x, res.y, res2.y); float4 col1 = float4(res.z, res2.z, res.w, res2.w); return col1; } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/WhiteCapsPrecompute0.shader.meta ================================================ fileFormatVersion: 2 guid: 725600e98a048ad46aacb96a8bb155cd timeCreated: 1459689357 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean.meta ================================================ fileFormatVersion: 2 guid: 1cd98b0d17936ed43bed805e1a150a88 folderAsset: yes timeCreated: 1541842604 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cginc ================================================ uniform sampler2D ringTexture; uniform float ringInnerRadius; uniform float ringOuterRadius; uniform float3 ringNormal; //only supporting Kopernicus linear rings for now (no support for tiled rings or rings with thickness) //rgb channels are returned modulated by alpha value (used for sunflare) //alpha value returned is actually 1-alpha (used for ring shadow on atmosphere/planet) inline float4 getLinearRingColor(float3 worldPos, float3 sunDir, float3 planetAndRingOrigin) { float parallel = 0.0; float3 ringIntersectPt = LinePlaneIntersection(worldPos, sunDir, ringNormal, planetAndRingOrigin, parallel); //calculate ring texture position on intersect float distance = length (ringIntersectPt - planetAndRingOrigin); float ringTexturePosition = (distance - ringInnerRadius) / (ringOuterRadius - ringInnerRadius); //inner and outer radiuses are converted to local space coords on plugin side ringTexturePosition = 1 - ringTexturePosition; //flip to match UVs float4 ringColor = tex2D(ringTexture, float2(ringTexturePosition,ringTexturePosition)); ringColor.a = 1-ringColor.a; ringColor.xyz*=ringColor.a; //don't apply any shadows if intersect point is not between inner and outer radius or line and plane are parallel ringColor = (ringTexturePosition > 1 || ringTexturePosition < 0 || parallel == 1.0 ) ? float4(1.0,1.0,1.0,1.0) : ringColor; return ringColor; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cginc.meta ================================================ fileFormatVersion: 2 guid: 29b7e99efaf64b949afd3d5b830c72aa timeCreated: 1542896604 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cgincBAK ================================================ uniform sampler2D ringTexture; uniform float ringInnerRadius; uniform float ringOuterRadius; uniform float3 ringNormal; //only supporting Kopernicus linear rings for now (no support for tiled rings or rings with thickness) //rgb channels are returned modulated by alpha value (used for sunflare) //alpha value returned is actually 1-alpha (used for ring shadow on atmosphere/planet) inline float4 getLinearRingColor(float3 worldPos, float3 sunDir, float3 planetAndRingOrigin) { float parallel = 0.0; float3 ringIntersectPt = LinePlaneIntersection(worldPos, sunDir, ringNormal, planetAndRingOrigin, parallel); //calculate ring texture position on intersect float distance = length (ringIntersectPt - planetAndRingOrigin); float ringTexturePosition = (distance - ringInnerRadius) / (ringOuterRadius - ringInnerRadius); //inner and outer radiuses are converted to local space coords on plugin side ringTexturePosition = 1 - ringTexturePosition; //flip to match UVs float4 ringColor = tex2D(ringTexture, float2(ringTexturePosition,ringTexturePosition)); ringColor.a = 1-ringColor.a; ringColor.xyz*=ringColor.a; //don't apply any shadows if intersect point is not between inner and outer radius or line and plane are parallel ringColor = (ringTexturePosition > 1 || ringTexturePosition < 0 || parallel == 1.0 ) ? float4(1.0,1.0,1.0,1.0) : ringColor; return ringColor; } inline float4 getLinearRingColorLod0(float3 worldPos, float3 sunDir, float3 planetAndRingOrigin) { float parallel = 0.0; float3 ringIntersectPt = LinePlaneIntersection(worldPos, sunDir, ringNormal, planetAndRingOrigin, parallel); //calculate ring texture position on intersect float distance = length (ringIntersectPt - planetAndRingOrigin); float ringTexturePosition = (distance - ringInnerRadius) / (ringOuterRadius - ringInnerRadius); //inner and outer radiuses are converted to local space coords on plugin side ringTexturePosition = 1 - ringTexturePosition; //flip to match UVs float4 ringColor = tex2Dlod(ringTexture, float4(ringTexturePosition,ringTexturePosition,0.0,0.0)); ringColor.a = 1-ringColor.a; ringColor.xyz*=ringColor.a; //don't apply any shadows if intersect point is not between inner and outer radius or line and plane are parallel ringColor = (ringTexturePosition > 1 || ringTexturePosition < 0 || parallel == 1.0 ) ? float4(1.0,1.0,1.0,1.0) : ringColor; return ringColor; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cgincBAK.meta ================================================ fileFormatVersion: 2 guid: 5b60206b4b7ac1043ba19efe7ecfd5be DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/DoublePrecisionEmulation.cginc ================================================ float times_frc(float a, float b) { return lerp(0.0, a * b, b != 0.0 ? 1.0 : 0.0); } float div_frc(float a, float b) { return lerp(0.0, a / b, b != 0.0 ? 1.0 : 0.0); } float plus_frc(float a, float b) { return lerp(a, a + b, b != 0.0 ? 1.0 : 0.0); } float minus_frc(float a, float b) { return lerp(a, a - b, b != 0.0 ? 1.0 : 0.0); } // create double-single number from float float2 ds_set(float a) { return float2(a, 0.0); } // Double emulation based on GLSL Mandelbrot Shader by Henry Thasler (www.thasler.org/blog) // // Emulation based on Fortran-90 double-single package. See http://crd.lbl.gov/~dhbailey/mpdist/ // Substract: res = ds_add(a, b) => res = a + b float2 ds_add (float2 dsa, float2 dsb) { float2 dsc; float t1, t2, e; t1 = plus_frc(dsa.x, dsb.x); e = minus_frc(t1, dsa.x); t2 = plus_frc(plus_frc(plus_frc(minus_frc(dsb.x, e), minus_frc(dsa.x, minus_frc(t1, e))), dsa.y), dsb.y); dsc.x = plus_frc(t1, t2); dsc.y = minus_frc(t2, minus_frc(dsc.x, t1)); return dsc; } // Substract: res = ds_sub(a, b) => res = a - b float2 ds_sub (float2 dsa, float2 dsb) { float2 dsc; float e, t1, t2; t1 = minus_frc(dsa.x, dsb.x); e = minus_frc(t1, dsa.x); t2 = minus_frc(plus_frc(plus_frc(minus_frc(minus_frc(0.0, dsb.x), e), minus_frc(dsa.x, minus_frc(t1, e))), dsa.y), dsb.y); dsc.x = plus_frc(t1, t2); dsc.y = minus_frc(t2, minus_frc(dsc.x, t1)); return dsc; } // Compare: res = -1 if a < b // = 0 if a == b // = 1 if a > b float ds_cmp(float2 dsa, float2 dsb) { if (dsa.x < dsb.x) { return -1.; } if (dsa.x > dsb.x) { return 1.; } if (dsa.y < dsb.y) { return -1.; } if (dsa.y > dsb.y) { return 1.; } return 0.; } // Multiply: res = ds_mul(a, b) => res = a * b float2 ds_mul (float2 dsa, float2 dsb) { float2 dsc; float c11, c21, c2, e, t1, t2; float a1, a2, b1, b2, cona, conb, split = 8193.; cona = times_frc(dsa.x, split); conb = times_frc(dsb.x, split); a1 = minus_frc(cona, minus_frc(cona, dsa.x)); b1 = minus_frc(conb, minus_frc(conb, dsb.x)); a2 = minus_frc(dsa.x, a1); b2 = minus_frc(dsb.x, b1); c11 = times_frc(dsa.x, dsb.x); c21 = plus_frc(times_frc(a2, b2), plus_frc(times_frc(a2, b1), plus_frc(times_frc(a1, b2), minus_frc(times_frc(a1, b1), c11)))); c2 = plus_frc(times_frc(dsa.x, dsb.y), times_frc(dsa.y, dsb.x)); t1 = plus_frc(c11, c2); e = minus_frc(t1, c11); t2 = plus_frc(plus_frc(times_frc(dsa.y, dsb.y), plus_frc(minus_frc(c2, e), minus_frc(c11, minus_frc(t1, e)))), c21); dsc.x = plus_frc(t1, t2); dsc.y = minus_frc(t2, minus_frc(dsc.x, t1)); return dsc; } // Divide: res = ds_div(a, b) => res = a / b float2 ds_div (float2 dsa, float2 dsb) { float2 dsc; float a1, a2, b1, b2, cona, conb, split = 8193.; float c11, c2, c21, e, s1, s2, t1, t2, t11, t12, t21, t22; s1 = div_frc(dsa.x,dsb.x); cona = times_frc(s1, split); conb = times_frc(dsb.x, split); a1 = minus_frc(cona, minus_frc(cona, s1)); b1 = minus_frc(conb, minus_frc(conb, dsb.x)); a2 = minus_frc(s1, a1); b2 = minus_frc(dsb.x, b1); c11 = times_frc(s1, dsb.x); c21 = plus_frc(times_frc(a2, b2), plus_frc(times_frc(a2, b1), plus_frc(times_frc(a1, b2), minus_frc(times_frc(a1, b1), c11)))); c2 = times_frc(s1, dsb.y); t1 = plus_frc(c11, c2); e = minus_frc(t1, c11); t2 = plus_frc(plus_frc(minus_frc(c2, e), minus_frc(c11, minus_frc(t1, e))), c21); t12 = plus_frc(t1,t2); t22 = minus_frc(t2,minus_frc(t12,t1)); t11 = minus_frc(dsa.x, t12); e = minus_frc(t11, dsa.x); t21 = minus_frc(plus_frc( plus_frc(minus_frc(-t12,e),minus_frc(dsa.x,minus_frc(t11,e))) ,dsa.y),t22); s2 = div_frc(plus_frc(t11,t21), dsb.x); dsc.x = plus_frc(s1, s2); dsc.y = minus_frc(s2, minus_frc(dsc.x, s1)); return dsc; } float2 ds_sqrt (float2 dsa) { float2 dsb; float t1, t2, t3; float2 f, s0, s1; if (dsa.x == 0.0) { return float2(0.0,0.0); } t1 = div_frc(1.0, sqrt(dsa.x)); t2 = times_frc(dsa.x, t1); s0 = ds_mul(ds_set(t2),ds_set(t2)); s1 = ds_sub(dsa, s0); t3 = times_frc(0.5, times_frc(s1.x,t1)); s0.x = t2; s0.y = 0.0; s1.x = t3; s1.y = 0.0; dsb = ds_add(s0, s1); return dsb; } // Couldn't get this to work // Sets B to the integer part of the DS number A and sets C equal to the // fractional part of A. Note that if A = -3.3, then B = -3 and C = -0.3. float4 ds_infr(float2 dsa) { int ic; float2 dsb, dsc, con, f, s0, s1; float t47, t23; t47 = pow(2,47); t23 = pow(2,23); con = float2(t47, t23); //not sure about this, data operator if (dsa.x == 0.0) return 0.0; //omitted dsa < 2^47 check here, should be fine f = float2(1.0,0.0); if (dsa.x > 0.0) { s0 = ds_add(dsa, con); dsb = ds_sub(s0,con); ic = ds_cmp(dsa, dsb); if (ic >= 0.0) { dsc = ds_sub(dsa,dsb); } else { s1 = ds_sub(dsb,f); dsb = s1; dsc = ds_sub(dsa,dsb); } } else { s0 = ds_sub(dsa,con); dsb = ds_add(s0,con); ic = ds_cmp(dsa,dsb); if (ic <= 0.0) { dsc = ds_sub(dsa,dsb); } else { s1 = ds_add(dsb,f); dsb = s1; dsc = ds_sub(dsa,dsb); } } return float4(dsb, dsc); } //Couldn't get this to work either, maybe something wrong with t47 and t23? // This sets B equal to the integer nearest to the DS number A. float2 dsn_int (float2 dsa) { float2 dsb, con, s0; float t47, t23; t47 = pow(2,47); t23 = pow(2,23); con = float2(t47, t23); //not sure about this, data operator, it may do something low-level, in which case this is screwed if (dsa.x == 0.0) { return float2(0.0,0.0); } if (dsa.x > 0.0) { s0 = ds_add(dsa, con); dsb = ds_sub(s0, con); } else { s0 = ds_sub(dsa,con); dsb = ds_add(s0,con); } return dsb; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/DoublePrecisionEmulation.cginc.meta ================================================ fileFormatVersion: 2 guid: 1a34c77a67cf21c4b8523a435293645b ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.cginc ================================================ // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) // Essentially a modified version of the unity screenSpace shadow collector shader // 1) Always use INV_PROJECTION because it offers better precision than the ray method when far/near ratio is very high // 2) Add a very small receiverPlaneDepthBias based on z value, to avoid shadow acne, jittering and other artifacts UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture); float4 _ShadowMapTexture_TexelSize; #define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED sampler2D _ODSWorldTexture; // ------------------------------------------------------------------ // Helpers // ------------------------------------------------------------------ UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); #include "../ShadowsCommon.cginc" struct appdata { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; #ifdef UNITY_STEREO_INSTANCING_ENABLED float3 ray0 : TEXCOORD1; float3 ray1 : TEXCOORD2; #else float3 ray : TEXCOORD1; #endif UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; // xy uv / zw screenpos float4 uv : TEXCOORD0; // View space ray, for perspective case float3 ray : TEXCOORD1; // Orthographic view space positions (need xy as well for oblique matrices) float3 orthoPosNear : TEXCOORD2; float3 orthoPosFar : TEXCOORD3; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float4 clipPos; #if defined(STEREO_CUBEMAP_RENDER_ON) clipPos = mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, v.vertex)); #else clipPos = UnityObjectToClipPos(v.vertex); #endif o.pos = clipPos; o.uv.xy = v.texcoord; // unity_CameraInvProjection at the PS level. o.uv.zw = ComputeNonStereoScreenPos(clipPos); // Perspective case #ifdef UNITY_STEREO_INSTANCING_ENABLED o.ray = unity_StereoEyeIndex == 0 ? v.ray0 : v.ray1; #else o.ray = v.ray; #endif // To compute view space position from Z buffer for orthographic case, // we need different code than for perspective case. We want to avoid // doing matrix multiply in the pixel shader: less operations, and less // constant registers used. Particularly with constant registers, having // unity_CameraInvProjection in the pixel shader would push the PS over SM2.0 // limits. clipPos.y *= _ProjectionParams.x; float3 orthoPosNear = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y,-1,1)).xyz; float3 orthoPosFar = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y, 1,1)).xyz; orthoPosNear.z *= -1; orthoPosFar.z *= -1; o.orthoPosNear = orthoPosNear; o.orthoPosFar = orthoPosFar; return o; } /** * Get camera space coord from depth and inv projection matrices */ inline float3 computeCameraSpacePosFromDepthAndInvProjMat(v2f i) { float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); #if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif // View position calculation for oblique clipped projection case. // this will not be as precise nor as fast as the other method // (which computes it from interpolated ray & depth) but will work // with funky projections. float4 clipPos = float4(i.uv.zw, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; return camPos.xyz; } /** * Get camera space coord from depth and info from VS */ inline float3 computeCameraSpacePosFromDepthAndVSInfo(v2f i) { float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); // 0..1 linear depth, 0 at camera, 1 at far plane. float depth = Linear01Depth(zdepth); #if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float3 adjustedRay = i.ray; float3 vposPersp = adjustedRay * depth; float3 camPos = vposPersp; return camPos.xyz; } inline float3 computeCameraSpacePosFromDepth(v2f i); /** * Hard shadow */ fixed4 frag_hard (v2f i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // required for sampling the correct slice of the shadow map render texture array float4 wpos; float3 vpos; #if defined(STEREO_CUBEMAP_RENDER_ON) wpos.xyz = tex2D(_ODSWorldTexture, i.uv.xy).xyz; wpos.w = 1.0f; vpos = mul(unity_WorldToCamera, wpos).xyz; #else vpos = computeCameraSpacePosFromDepth(i); wpos = mul (unity_CameraToWorld, float4(vpos,1)); #endif fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (wpos, vpos.z); float4 shadowCoord = GET_SHADOW_COORDINATES(wpos, cascadeWeights); //1 tap hard shadow fixed shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, shadowCoord); shadow = lerp(_LightShadowData.r, 1.0, shadow); fixed4 res = shadow; return res; } /** * Soft Shadow (SM 3.0) */ fixed4 frag_pcfSoft(v2f i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // required for sampling the correct slice of the shadow map render texture array float4 wpos; float3 vpos; #if defined(STEREO_CUBEMAP_RENDER_ON) wpos.xyz = tex2D(_ODSWorldTexture, i.uv.xy).xyz; wpos.w = 1.0f; vpos = mul(unity_WorldToCamera, wpos).xyz; #else vpos = computeCameraSpacePosFromDepth(i); // sample the cascade the pixel belongs to wpos = mul(unity_CameraToWorld, float4(vpos,1)); #endif fixed4 cascadeWeights = GET_CASCADE_WEIGHTS(wpos, vpos.z); float4 coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights); float zdepth2 = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); // float3 receiverPlaneDepthBias = float3(0.0,0.0,0.5*Linear01Depth(zdepth2)); //my best or worst hack yet? //seems to fix all issues, no peter-panning either //perfect for 5000 shadowDistance //Holds up to 8000-9000 shadow distance and gets swimmy after float3 receiverPlaneDepthBias = float3(0.0,0.0,2.0 * Linear01Depth(zdepth2)); //With the new hybrid reconstruction method this isn't needed anymore but what Parallax renders to depth buffer is slightly offset so use agressive bias #ifdef UNITY_USE_RECEIVER_PLANE_BIAS // Reveiver plane depth bias: need to calculate it based on shadow coordinate // as it would be in first cascade; otherwise derivatives // at cascade boundaries will be all wrong. So compute // it from cascade 0 UV, and scale based on which cascade we're in. float3 coordCascade0 = getShadowCoord_SingleCascade(wpos); float biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales); receiverPlaneDepthBias = UnityGetReceiverPlaneDepthBias(coordCascade0.xyz, biasMultiply); #endif #if defined(SHADER_API_MOBILE) half shadow = UnitySampleShadowmap_PCF5x5(coord, receiverPlaneDepthBias); #else half shadow = UnitySampleShadowmap_PCF7x7(coord, receiverPlaneDepthBias); #endif shadow = lerp(_LightShadowData.r, 1.0f, shadow); // Blend between shadow cascades if enabled // // Not working yet with split spheres, and no need when 1 cascade #if UNITY_USE_CASCADE_BLENDING && !defined(SHADOWS_SPLIT_SPHERES) && !defined(SHADOWS_SINGLE_CASCADE) half4 z4 = (float4(vpos.z,vpos.z,vpos.z,vpos.z) - _LightSplitsNear) / (_LightSplitsFar - _LightSplitsNear); half alpha = dot(z4 * cascadeWeights, half4(1,1,1,1)); UNITY_BRANCH if (alpha > 1 - UNITY_CASCADE_BLEND_DISTANCE) { // get alpha to 0..1 range over the blend distance alpha = (alpha - (1 - UNITY_CASCADE_BLEND_DISTANCE)) / UNITY_CASCADE_BLEND_DISTANCE; // sample next cascade cascadeWeights = fixed4(0, cascadeWeights.xyz); coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights); #ifdef UNITY_USE_RECEIVER_PLANE_BIAS biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales); receiverPlaneDepthBias = UnityGetReceiverPlaneDepthBias(coordCascade0.xyz, biasMultiply); #endif half shadowNextCascade = UnitySampleShadowmap_PCF3x3(coord, receiverPlaneDepthBias); shadowNextCascade = lerp(_LightShadowData.r, 1.0f, shadowNextCascade); shadow = lerp(shadow, shadowNextCascade, alpha); } #endif return shadow; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.cginc.meta ================================================ fileFormatVersion: 2 guid: 7895e41fc42ee304cbd33be552917a5a ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.shader ================================================ // This shader is now deprecated as the long distance version is now better in every way without adding a performance hit // Essentially a modified version of the unity screenSpace shadow collector shader // 1) Always use INV_PROJECTION because it offers better precision than the ray method when far/near ratio is very high // 2) Add a very small receiverPlaneDepthBias based on z value, to avoid shadow acne, jittering and other artifacts Shader "Scatterer/fixedScreenSpaceShadows" { Properties { _ShadowMapTexture ("", any) = "" {} _ODSWorldTexture("", 2D) = "" {} } CGINCLUDE #include "FixedScreenSpaceShadows.cginc" ENDCG //// ---------------------------------------------------------------------------------------- //// Subshader for hard shadows: //// Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked. // //SubShader { // Tags{ "ShadowmapFilter" = "HardShadow" } // Pass { // ZWrite Off ZTest Always Cull Off // // CGPROGRAM // #pragma vertex vert // #pragma fragment frag_hard // #pragma multi_compile_shadowcollector // // inline float3 computeCameraSpacePosFromDepth(v2f i) // { // return computeCameraSpacePosFromDepthAndVSInfo(i); // } // ENDCG // } //} // ---------------------------------------------------------------------------------------- // Subshader for hard shadows: // Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked. // This version does inv projection at the PS level, slower and less precise however more general. SubShader { // Tags{ "ShadowmapFilter" = "HardShadow_FORCE_INV_PROJECTION_IN_PS" } Tags{ "ShadowmapFilter" = "HardShadow" } Pass{ ZWrite Off ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag_hard #pragma multi_compile_shadowcollector inline float3 computeCameraSpacePosFromDepth(v2f i) { return computeCameraSpacePosFromDepthAndInvProjMat(i); } ENDCG } } //// ---------------------------------------------------------------------------------------- //// Subshader that does soft PCF filtering while collecting shadows. //// Requires SM3 GPU. // //Subshader { // Tags {"ShadowmapFilter" = "PCF_SOFT"} // Pass { // ZWrite Off ZTest Always Cull Off // // CGPROGRAM // #pragma vertex vert // #pragma fragment frag_pcfSoft // #pragma multi_compile_shadowcollector // #pragma target 3.0 // // inline float3 computeCameraSpacePosFromDepth(v2f i) // { // return computeCameraSpacePosFromDepthAndVSInfo(i); // } // ENDCG // } //} // ---------------------------------------------------------------------------------------- // Subshader that does soft PCF filtering while collecting shadows. // Requires SM3 GPU. // This version does inv projection at the PS level, slower and less precise however more general. // Subshader{ //Tags{ "ShadowmapFilter" = "PCF_SOFT_FORCE_INV_PROJECTION_IN_PS" } Tags {"ShadowmapFilter" = "PCF_SOFT"} Pass{ ZWrite Off ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag_pcfSoft #pragma multi_compile_shadowcollector #pragma target 3.0 inline float3 computeCameraSpacePosFromDepth(v2f i) { return computeCameraSpacePosFromDepthAndInvProjMat(i); } ENDCG } } Fallback Off } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.shader.meta ================================================ fileFormatVersion: 2 guid: e7719e74d14c6ca45a8d38ed1a32e5d9 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/LongDistanceScreenSpaceShadows.shader ================================================ // Same as fixedScreenSpaceShadows shader but uses the enhanced ray/projection method to calculate accurate position // Some other experimentes are kept in this file but no longer used: Including dual-depth method, binary search method, double precision method Shader "Scatterer/customScreenSpaceShadows" { Properties { _ShadowMapTexture ("", any) = "" {} _ODSWorldTexture("", 2D) = "" {} } CGINCLUDE #include "FixedScreenSpaceShadows.cginc" #include "DoublePrecisionEmulation.cginc" UNITY_DECLARE_DEPTH_TEXTURE(AdditionalDepthBuffer); float4x4 ScattererAdditionalInvProjection; /** * Get camera space coord from depth and inv projection matrices * No longer needed, deprecated in favor of hybrid ray/matrix method below */ inline float3 computeCameraSpacePosFromDualDepthAndInvProjMat(v2f i) { float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); float zdepth2 = SAMPLE_DEPTH_TEXTURE(AdditionalDepthBuffer, i.uv.xy); #if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; zdepth2 = 1 - zdepth2; #endif float4 clipPos = float4(i.uv.zw, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; float4 clipPos2 = float4(i.uv.zw, zdepth2, 1.0); clipPos2.xyz = 2.0f * clipPos2.xyz - 1.0f; float4 camPos2 = mul(ScattererAdditionalInvProjection, clipPos2); camPos2.xyz /= camPos2.w; camPos2.z *= -1; return length(camPos.xyz) < 8000 ? camPos.xyz : camPos2.xyz ; } //Refines the inaccurate worldPos from invprojection with a search algorithm //Apparently overshoots here even though it worked well for scattering shader float getRefinedDistanceFromDepth(float unrefinedDistance, float zdepth, float3 viewDir) { const int maxIterations = 30; //seems about perfect int iteration = 0; float maxSearchDistance = unrefinedDistance * 1.30; float minSearchDistance = unrefinedDistance * 0.70; float mid = 0; float3 camPos0 = float3(0.0,0.0,0.0); float4 clipPos = float4(0.0,0.0,0.0,1.0); float depth = -10.0; while ((iteration < maxIterations) && (depth != zdepth)) { mid = 0.5 * (maxSearchDistance + minSearchDistance); camPos0 = viewDir * mid; clipPos = mul(UNITY_MATRIX_P, float4(camPos0,1.0)); depth = clipPos.z/clipPos.w; maxSearchDistance = (depth < zdepth) ? mid : maxSearchDistance; minSearchDistance = (depth > zdepth) ? mid : minSearchDistance; iteration++; } return mid; } // Binary search method, worked well for the scattering shader but seems to overshoot here inline float3 computeEnhancedCameraSpacePosFromDepthAndInvProjMat(v2f i) { float textureZdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); float zdepth = textureZdepth; #if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(i.uv.zw, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; float invDepthLength = length(camPos.xyz); float3 viewDir = camPos.xyz / invDepthLength; //now refine the inaccurate distance float distance = invDepthLength; // if (distance > 8000.0) { distance = getRefinedDistanceFromDepth(distance, textureZdepth, viewDir); //seems like my method is overshooting actually, or something else is wrong with these params, to investigate, maybe the projection matrix, maybe the direction is flipped } camPos.xyz = distance * viewDir; return camPos.xyz; } //after implementing this it seems like this isn't even the source of the issue, but rather the ray direction that unity passes, good job unity wtf inline float2 Linear01DepthDoublePrecision( float z ) { //return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y); float2 doubleZBufferParamsY = ds_sub(ds_set(1.0), ds_div(ds_set(_ProjectionParams.y), ds_set(_ProjectionParams.z))); float2 doubleWhateverElse = ds_mul(ds_div(ds_set(_ProjectionParams.z), ds_set(_ProjectionParams.y)), ds_set(z)); float2 doubleResultLower = ds_add(doubleZBufferParamsY, doubleWhateverElse); float2 doubleResult = ds_div(ds_set(1.0), doubleResultLower); return doubleResult; } //This is the same ray method but calculations are done in emulated double precision //This ended up being useless, the source of the problem is the ray direction passed by unity inline float3 computeCameraSpacePosFromDepthAndVSInfoDoublePrecision(v2f i) { float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); // 0..1 linear depth, 0 at camera, 1 at far plane. float2 doublePrecisionDepth = Linear01DepthDoublePrecision(zdepth); float3 adjustedRay = i.ray; float3 rayDirection = normalize(i.ray); float3 vposPersp = adjustedRay * doublePrecisionDepth.x; return vposPersp; } /** * Use the ray method to find position, except use the ray direction calculated with the invProj method because it's more accurate * Kind of a hybrid of the two methods */ inline float3 computeCameraSpacePosFromLinearDepthAndInvProjMat(v2f i) { float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); #if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12 if (zdepth == 0.0) {discard;} #else if (zdepth == 1.0) {discard;} #endif float depth = Linear01Depth(zdepth); //float3 rayDirection = normalize(i.ray); //this ray is imprecise and can't be trusted //calculate our own ray direction using the inverse projection matrix method #if defined(UNITY_REVERSED_Z) zdepth = 1 - zdepth; #endif float4 clipPos = float4(i.uv.zw, zdepth, 1.0); clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; float4 camPos = mul(unity_CameraInvProjection, clipPos); camPos.xyz /= camPos.w; camPos.z *= -1; float3 rayDirection = normalize(camPos.xyz); float3 cameraForwardDir = float3(0,0,1); float aa = dot(rayDirection, cameraForwardDir); float3 vposPersp = rayDirection * depth/aa * _ProjectionParams.z; return vposPersp; } ENDCG // ---------------------------------------------------------------------------------------- // Subshader for hard shadows: // Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked. // This version does inv projection at the PS level, slower and less precise however more general. SubShader { Tags{ "ShadowmapFilter" = "HardShadow" } Pass{ ZWrite Off ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag_hard #pragma multi_compile_shadowcollector inline float3 computeCameraSpacePosFromDepth(v2f i) { return computeCameraSpacePosFromLinearDepthAndInvProjMat(i); } ENDCG } } // ---------------------------------------------------------------------------------------- // Subshader that does soft PCF filtering while collecting shadows. // Requires SM3 GPU. // This version does inv projection at the PS level, slower and less precise however more general. // Subshader{ Tags {"ShadowmapFilter" = "PCF_SOFT"} Pass{ ZWrite Off ZTest Always Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag_pcfSoft #pragma multi_compile_shadowcollector #pragma target 3.0 inline float3 computeCameraSpacePosFromDepth(v2f i) { return computeCameraSpacePosFromLinearDepthAndInvProjMat(i); } ENDCG } } Fallback Off } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/LongDistanceScreenSpaceShadows.shader.meta ================================================ fileFormatVersion: 2 guid: 02e622e7baa59ac449d2c5f5bc992795 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows.meta ================================================ fileFormatVersion: 2 guid: 5bcb408b7b5e4d346aeb4860ab1d9d9b folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ShadowsCommon.cginc ================================================ #include "UnityCG.cginc" #include "UnityShadowLibrary.cginc" // Configuration // Should receiver plane bias be used? This estimates receiver slope using derivatives, // and tries to tilt the PCF kernel along it. However, since we're doing it in screenspace // from the depth texture, the derivatives are wrong on edges or intersections of objects, // leading to possible shadow artifacts. So it's disabled by default. // See also UnityGetReceiverPlaneDepthBias in UnityShadowLibrary.cginc. //#define UNITY_USE_RECEIVER_PLANE_BIAS // Blend between shadow cascades to hide the transition seams? #define UNITY_USE_CASCADE_BLENDING 0 #define UNITY_CASCADE_BLEND_DISTANCE 0.1 // sizes of cascade projections, relative to first one float4 unity_ShadowCascadeScales; // // Keywords based defines // #if defined (SHADOWS_SPLIT_SPHERES) #define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights_splitSpheres(wpos) #else #define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights( wpos, z ) #endif #if defined (SHADOWS_SINGLE_CASCADE) #define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord_SingleCascade(wpos) #else #define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord(wpos,cascadeWeights) #endif /** * Gets the cascade weights based on the world position of the fragment. * Returns a float4 with only one component set that corresponds to the appropriate cascade. */ inline fixed4 getCascadeWeights(float3 wpos, float z) { fixed4 zNear = float4( z >= _LightSplitsNear ); fixed4 zFar = float4( z < _LightSplitsFar ); fixed4 weights = zNear * zFar; return weights; } /** * Gets the cascade weights based on the world position of the fragment and the poisitions of the split spheres for each cascade. * Returns a float4 with only one component set that corresponds to the appropriate cascade. */ inline fixed4 getCascadeWeights_splitSpheres(float3 wpos) { float3 fromCenter0 = wpos.xyz - unity_ShadowSplitSpheres[0].xyz; float3 fromCenter1 = wpos.xyz - unity_ShadowSplitSpheres[1].xyz; float3 fromCenter2 = wpos.xyz - unity_ShadowSplitSpheres[2].xyz; float3 fromCenter3 = wpos.xyz - unity_ShadowSplitSpheres[3].xyz; float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3)); fixed4 weights = float4(distances2 < unity_ShadowSplitSqRadii); weights.yzw = saturate(weights.yzw - weights.xyz); return weights; } /** * Returns the shadowmap coordinates for the given fragment based on the world position and z-depth. * These coordinates belong to the shadowmap atlas that contains the maps for all cascades. */ inline float4 getShadowCoord( float4 wpos, fixed4 cascadeWeights ) { float3 sc0 = mul (unity_WorldToShadow[0], wpos).xyz; float3 sc1 = mul (unity_WorldToShadow[1], wpos).xyz; float3 sc2 = mul (unity_WorldToShadow[2], wpos).xyz; float3 sc3 = mul (unity_WorldToShadow[3], wpos).xyz; float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1); #if defined(UNITY_REVERSED_Z) float noCascadeWeights = 1 - dot(cascadeWeights, float4(1, 1, 1, 1)); shadowMapCoordinate.z += noCascadeWeights; #endif return shadowMapCoordinate; } /** * Same as the getShadowCoord; but optimized for single cascade */ inline float4 getShadowCoord_SingleCascade( float4 wpos ) { return float4( mul (unity_WorldToShadow[0], wpos).xyz, 0); } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ShadowsCommon.cginc.meta ================================================ fileFormatVersion: 2 guid: 06bfdc59aae5325499d5beef3aa3d013 ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlare.shader ================================================ Shader "Scatterer/sunFlare" { CGINCLUDE #include "UnityCG.cginc" #include "../CommonAtmosphere.cginc" #include "../DepthCommon.cginc" uniform float sunGlareScale; uniform float sunGlareFade; uniform sampler2D sunSpikes; uniform sampler2D sunFlare; uniform sampler2D sunGhost1; uniform sampler2D sunGhost2; uniform sampler2D sunGhost3; uniform float3 flareColor; uniform sampler2D extinctionTexture; uniform float3 flareSettings; //intensity, aspect ratio, scale uniform float3 spikesSettings; uniform float4x4 ghost1Settings1; //each row is an instance of a ghost uniform float4x4 ghost1Settings2; //for each row: intensity, aspect ratio, scale, position on sun-screenCenter line. Intensity of 0 means nothing defined uniform float4x4 ghost2Settings1; uniform float4x4 ghost2Settings2; uniform float4x4 ghost3Settings1; uniform float4x4 ghost3Settings2; uniform float3 sunViewPortPos; uniform float aspectRatio; uniform float renderSunFlare; uniform float renderOnCurrentCamera; uniform float useDbufferOnCamera; struct v2f { float4 pos: SV_POSITION; float2 uv : TEXCOORD0; float3 color : TEXCOORD1; }; v2f flareVertexShader(appdata_base v, float3 sunViewPortPos, float3 settings) { v2f OUT; float drawFlare = (useDbufferOnCamera < 1.0) ? 1.0 : checkDepthBufferEmpty(sunViewPortPos.xy); //if there's something in the way don't render the flare sunViewPortPos.xy = 2.0 * sunViewPortPos.xy - float2(1.0,1.0); sunViewPortPos.y *= _ProjectionParams.x; v.vertex.xy = sunViewPortPos.xy + v.vertex.xy / (settings.z * sunGlareScale * float2(aspectRatio * settings.y, 1.0)); //change this so it no longer has to do a division OUT.pos = float4(v.vertex.xy, 1.0, 1.0); OUT.pos = (settings.x > 0.0) && (renderSunFlare == 1.0) && (_ProjectionParams.y < 200.0) && (renderOnCurrentCamera == 1.0) && (drawFlare ==1.0) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //if we don't need to render the sunflare, cull vertexes by placing them outside clip space //also use near plane to not render on far camera OUT.uv = v.texcoord.xy; OUT.color = settings.x * sunGlareFade * flareColor * tex2Dlod(extinctionTexture,float4(0.0,0.0,0.0,0.0)).rgb; return OUT; } struct v2g { float4 pos: SV_POSITION; float2 uv : TEXCOORD0; float3 color : TEXCOORD1; }; struct g2f { float4 pos: SV_POSITION; float2 uv : TEXCOORD0; float3 color : TEXCOORD1; }; v2g ghostVertexShader (appdata_base v, float3 sunViewPortPos, float ghostFade) { v2g OUT; OUT.pos = float4(v.vertex.xy, 1.0, 1.0); OUT.uv = v.texcoord.xy; float2 toScreenCenter=sunViewPortPos.xy-0.5; OUT.color = ghostFade * smoothstep(0,1.0,1.0-length(toScreenCenter)) * sunGlareFade * flareColor * tex2Dlod(extinctionTexture,float4(0.0,0.0,0.0,0.0)).rgb; return OUT; } g2f buildGhostVertex(v2g input, float4 ghostSettings, float3 sunViewPortPos) { g2f tri; tri.pos = input.pos; tri.pos.xy = sunViewPortPos.xy - sunViewPortPos.xy * ghostSettings.w + tri.pos.xy / (ghostSettings.z * float2(aspectRatio * ghostSettings.y, 1.0)); //change this so it no longer has to do a division tri.uv = input.uv; tri.color = input.color * ghostSettings.x ; return tri; } //geometry shader //for every triangle of the input, create a max of 8 triangles, (max 8 possible instances of each ghost) inline void ghostGeometryShader(v2g input[3], inout TriangleStream outStream, float4x4 settings1, float4x4 settings2, float3 sunViewPortPos) { float drawFlare = (useDbufferOnCamera < 1.0) ? 1.0 : checkDepthBufferEmpty(sunViewPortPos.xy); drawFlare = (renderSunFlare == 1.0) && (_ProjectionParams.y < 200.0) && (renderOnCurrentCamera == 1.0) && (drawFlare ==1.0) ? 1.0 : 0.0; sunViewPortPos.xy = 2.0 * sunViewPortPos.xy - float2(1.0,1.0); sunViewPortPos.y *= _ProjectionParams.x; for (int i=0; i<4; ++i) { if ((settings1[i].x == 0) || (drawFlare < 1.0)) break; outStream.Append(buildGhostVertex(input[0], settings1[i], sunViewPortPos)); outStream.Append(buildGhostVertex(input[1], settings1[i], sunViewPortPos)); outStream.Append(buildGhostVertex(input[2], settings1[i], sunViewPortPos)); outStream.RestartStrip(); } for (i=0; i<4; ++i) { if ((settings2[i].x == 0) || (drawFlare < 1.0)) break; outStream.Append(buildGhostVertex(input[0], settings2[i], sunViewPortPos)); outStream.Append(buildGhostVertex(input[1], settings2[i], sunViewPortPos)); outStream.Append(buildGhostVertex(input[2], settings2[i], sunViewPortPos)); outStream.RestartStrip(); } } ENDCG SubShader { Tags {"Queue" = "Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} //Pass 0: flare 1 Pass { ZWrite Off ZTest Off cull off Blend One OneMinusSrcColor //"reverse" soft-additive CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment frag #pragma glsl v2f vert(appdata_base v) { return flareVertexShader(v, sunViewPortPos, flareSettings); } float4 frag(v2f IN) : SV_Target { float3 sunColor= IN.color * tex2Dlod (sunFlare,float4(IN.uv.xy,0,0)).rgb; return float4(sunColor,1.0); } ENDCG } //Pass 1: flare2 Pass { ZWrite Off ZTest Off cull off Blend One OneMinusSrcColor CGPROGRAM #pragma target 3.0 #pragma vertex vert #pragma fragment frag #pragma glsl v2f vert(appdata_base v) { return flareVertexShader(v, sunViewPortPos, spikesSettings); } float4 frag(v2f IN) : SV_Target { float3 sunColor= IN.color * tex2Dlod (sunSpikes,float4(IN.uv.xy,0,0)).rgb; return float4(sunColor,1.0); } ENDCG } //Pass 2: ghost 1 Pass { ZWrite Off ZTest Off cull off Blend One OneMinusSrcColor CGPROGRAM #pragma vertex vert #pragma geometry geom #pragma fragment frag #pragma glsl uniform float ghost1Fade; v2g vert(appdata_base v) { return ghostVertexShader(v, sunViewPortPos, ghost1Fade); } [maxvertexcount(24)] void geom(triangle v2g input[3], inout TriangleStream outStream) { ghostGeometryShader(input, outStream, ghost1Settings1, ghost1Settings2, sunViewPortPos); } float4 frag(g2f IN) : SV_Target { float3 sunColor= IN.color * tex2Dlod (sunGhost1,float4(IN.uv.xy,0,0)).rgb; return float4(sunColor,1.0); } ENDCG } //Pass 3: ghost 2 Pass { ZWrite Off ZTest Off cull off Blend One OneMinusSrcColor CGPROGRAM #pragma vertex vert #pragma geometry geom #pragma fragment frag #pragma glsl uniform float ghost2Fade; v2g vert(appdata_base v) { return ghostVertexShader(v, sunViewPortPos, ghost2Fade); } [maxvertexcount(24)] void geom(triangle v2g input[3], inout TriangleStream outStream) { ghostGeometryShader(input, outStream, ghost2Settings1, ghost2Settings2, sunViewPortPos); } float4 frag(g2f IN) : SV_Target { float3 sunColor= IN.color * tex2Dlod (sunGhost2,float4(IN.uv.xy,0,0)).rgb; return float4(sunColor,1.0); } ENDCG } //Pass 4: ghost 3 Pass { ZWrite Off ZTest Off cull off Blend One OneMinusSrcColor CGPROGRAM #pragma vertex vert #pragma geometry geom #pragma fragment frag #pragma glsl uniform float ghost3Fade; v2g vert(appdata_base v) { return ghostVertexShader(v, sunViewPortPos, ghost3Fade); } [maxvertexcount(24)] void geom(triangle v2g input[3], inout TriangleStream outStream) { ghostGeometryShader(input, outStream, ghost3Settings1, ghost3Settings2, sunViewPortPos); } float4 frag(g2f IN) : SV_Target { float3 sunColor= IN.color * tex2Dlod (sunGhost3,float4(IN.uv.xy,0,0)).rgb; return float4(sunColor,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlare.shader.meta ================================================ fileFormatVersion: 2 guid: 34f9419ac53fdb44fa9676a451481931 ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlareExtinction.shader ================================================ // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Scatterer/sunFlareExtinction" { SubShader { Pass //pass 0 - atmospheric extinction { ZWrite Off ZTest Off cull off Blend DstColor Zero //multiplicative blending CGPROGRAM #include "UnityCG.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag #pragma multi_compile DISABLE_UNDERWATER_OFF DISABLE_UNDERWATER_ON uniform float Rg; uniform float Rt; uniform sampler2D _Sky_Transmittance; uniform float3 _Sun_WorldSunDir; uniform float3 _Globals_WorldCameraPos; uniform float _experimentalAtmoScale; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } float2 GetTransmittanceUV(float r, float mu) { float uR, uMu; uR = sqrt((r - Rg) / (Rt - Rg)); uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; return float2(uMu, uR); } float3 Transmittance(float r, float mu) { float2 uv = GetTransmittanceUV(r, mu); return tex2Dlod(_Sky_Transmittance, float4(uv,0,0)).rgb; } float SQRT(float f, float err) { return f >= 0.0 ? sqrt(f) : err; } float3 getExtinction(float3 camera, float3 viewdir) { float3 extinction = float3(1,1,1); Rt=Rg+(Rt-Rg)*_experimentalAtmoScale; float r = length(camera); float rMu = dot(camera, viewdir); float mu = rMu / r; //float deltaSq = sqrt(rMu * rMu - r * r + Rt*Rt); float deltaSq = SQRT(rMu * rMu - r * r + Rt*Rt,0.000001); float din = max(-rMu - deltaSq, 0.0); if (din > 0.0) { camera += din * viewdir; rMu += din; mu = rMu / Rt; r = Rt; } extinction = (r > Rt) ? float3(1,1,1) : Transmittance(r, mu); return extinction; } float4 frag(v2f IN): COLOR { float3 WSD = _Sun_WorldSunDir; float3 WCP = _Globals_WorldCameraPos; float3 extinction = getExtinction(WCP,WSD); #if defined (DISABLE_UNDERWATER_ON) //disable when underwater extinction = (length(WCP) >= Rg ) ? extinction : float4(0.0,0.0,0.0,1.0); #endif return float4(extinction,1.0); } ENDCG } Pass //pass 1 - ring extinction { ZWrite Off ZTest Off cull off Blend DstColor Zero //multiplicative blending CGPROGRAM #include "UnityCG.cginc" #include "../IntersectCommon.cginc" #include "../RingCommon.cginc" #pragma target 3.0 #pragma vertex vert #pragma fragment frag uniform float3 _Sun_WorldSunDir; uniform float3 _Globals_WorldCameraPos; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f OUT; OUT.pos = UnityObjectToClipPos(v.vertex); OUT.uv = v.texcoord; return OUT; } float4 frag(v2f IN): COLOR { float3 WCP = _Globals_WorldCameraPos; float4 ringColor = getLinearRingColor(WCP,_Sun_WorldSunDir,float3(0,0,0)); return float4(ringColor.xyz,1.0); } ENDCG } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlareExtinction.shader.meta ================================================ fileFormatVersion: 2 guid: 357e9aeae0d19c148b2437b05c8b3361 timeCreated: 1485103617 licenseType: Free ShaderImporter: defaultTextures: [] userData: assetBundleName: scatterershaders assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare.meta ================================================ fileFormatVersion: 2 guid: 1b0a41d64d4e9534481f804049080fbb folderAsset: yes timeCreated: 1541842621 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Utility.cginc ================================================ float mod(float x, float y) { return x - y * floor(x/y); } float3 hdr(float3 L, float exposure) { L = L * exposure; L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r); L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g); L.b = L.b < 1.413 ? pow(L.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.b); return L; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Utility.cginc.meta ================================================ fileFormatVersion: 2 guid: cb5112bfbee0a8545af567d810945a2a ShaderImporter: defaultTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/TestScenes.meta ================================================ fileFormatVersion: 2 guid: 15225778e2107e44bb700adf9df97a60 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Assets/shaders.meta ================================================ fileFormatVersion: 2 guid: 980daac0955b74442b91df43f0f1b776 folderAsset: yes timeCreated: 1459687924 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/AssetImportState ================================================ 19;0;4;0;0 ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/BuildPlayer.prefs ================================================ ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/CurrentLayout-default.dwlt ================================================ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &1 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_PixelRect: serializedVersion: 2 x: 0 y: 43 width: 2560 height: 1357 m_ShowMode: 4 m_Title: m_RootView: {fileID: 6} m_MinSize: {x: 950, y: 300} m_MaxSize: {x: 10000, y: 10000} --- !u!114 &2 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 9} - {fileID: 3} m_Position: serializedVersion: 2 x: 0 y: 30 width: 2560 height: 1307 m_MinSize: {x: 683, y: 494} m_MaxSize: {x: 14004, y: 14044} vertical: 0 controlID: 61 --- !u!114 &3 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 1957 y: 0 width: 603 height: 1307 m_MinSize: {x: 277, y: 72} m_MaxSize: {x: 4002, y: 4022} m_ActualView: {fileID: 14} m_Panes: - {fileID: 14} m_Selected: 0 m_LastSelected: 0 --- !u!114 &4 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 0 width: 539 height: 702 m_MinSize: {x: 202, y: 222} m_MaxSize: {x: 4002, y: 4022} m_ActualView: {fileID: 15} m_Panes: - {fileID: 15} m_Selected: 0 m_LastSelected: 0 --- !u!114 &5 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: ConsoleWindow m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 702 width: 1957 height: 605 m_MinSize: {x: 232, y: 272} m_MaxSize: {x: 10002, y: 10022} m_ActualView: {fileID: 13} m_Panes: - {fileID: 13} - {fileID: 18} m_Selected: 0 m_LastSelected: 1 --- !u!114 &6 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 7} - {fileID: 2} - {fileID: 8} m_Position: serializedVersion: 2 x: 0 y: 0 width: 2560 height: 1357 m_MinSize: {x: 950, y: 300} m_MaxSize: {x: 10000, y: 10000} --- !u!114 &7 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 0 width: 2560 height: 30 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} m_LastLoadedLayoutName: --- !u!114 &8 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 1337 width: 2560 height: 20 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} --- !u!114 &9 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 10} - {fileID: 5} m_Position: serializedVersion: 2 x: 0 y: 0 width: 1957 height: 1307 m_MinSize: {x: 406, y: 494} m_MaxSize: {x: 10002, y: 14044} vertical: 1 controlID: 105 --- !u!114 &10 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 4} - {fileID: 11} m_Position: serializedVersion: 2 x: 0 y: 0 width: 1957 height: 702 m_MinSize: {x: 406, y: 222} m_MaxSize: {x: 8006, y: 4022} vertical: 0 controlID: 106 --- !u!114 &11 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 539 y: 0 width: 1418 height: 702 m_MinSize: {x: 204, y: 222} m_MaxSize: {x: 4004, y: 4022} m_ActualView: {fileID: 17} m_Panes: - {fileID: 16} - {fileID: 17} - {fileID: 12} m_Selected: 1 m_LastSelected: 0 --- !u!114 &12 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12111, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 400, y: 100} m_MaxSize: {x: 2048, y: 2048} m_TitleContent: m_Text: Asset Store m_Image: {fileID: 357073275683767465, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 468 y: 181 width: 973 height: 501 m_ViewDataDictionary: {fileID: 0} --- !u!114 &13 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 230, y: 250} m_MaxSize: {x: 10000, y: 10000} m_TitleContent: m_Text: Project m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 0 y: 775 width: 1957 height: 586 m_ViewDataDictionary: {fileID: 0} m_SearchFilter: m_NameFilter: m_ClassNames: [] m_AssetLabels: [] m_AssetBundleNames: [] m_VersionControlStates: [] m_SoftLockControlStates: [] m_ReferencingInstanceIDs: m_SceneHandles: m_ShowAllHits: 0 m_SkipHidden: 0 m_SearchArea: 1 m_Folders: - Assets/Shaders/AA m_ViewMode: 1 m_StartGridSize: 64 m_LastFolders: - Assets/Shaders/AA m_LastFoldersGridSize: -1 m_LastProjectPath: C:\gh\scattererGithub\Scatterer\scatterer\Shaders\scattererShaders m_LockTracker: m_IsLocked: 0 m_FolderTreeState: scrollPos: {x: 0, y: 0} m_SelectedIDs: 942e0000 m_LastClickedID: 11924 m_ExpandedIDs: 00000000fe2c0000302d000000ca9a3b m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: SunFlare m_OriginalName: SunFlare m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 11838 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 0 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 5} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_AssetTreeState: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 m_ExpandedIDs: 00000000fe2c0000302d0000ba2d0000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 0} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_ListAreaState: m_SelectedInstanceIDs: m_LastClickedInstanceID: 0 m_HadKeyboardFocusLastEvent: 1 m_ExpandedInstanceIDs: c623000000000000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 5} m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_NewAssetIndexInList: -1 m_ScrollPosition: {x: 0, y: 0} m_GridSize: 64 m_SkipHiddenPackages: 0 m_DirectoriesAreaWidth: 283 --- !u!114 &14 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 275, y: 50} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Inspector m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 1957 y: 73 width: 601 height: 1288 m_ViewDataDictionary: {fileID: 0} m_OpenAddComponentMenu: 0 m_ObjectsLockedBeforeSerialization: [] m_InstanceIDsLockedBeforeSerialization: m_LockTracker: m_IsLocked: 0 m_PreviewResizer: m_CachedPref: 160 m_ControlHash: -371814159 m_PrefName: Preview_InspectorPreview m_PreviewWindow: {fileID: 0} m_LastInspectedObjectInstanceID: -1 m_LastVerticalScrollValue: 0 --- !u!114 &15 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Hierarchy m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 0 y: 73 width: 539 height: 683 m_ViewDataDictionary: {fileID: 0} m_SceneHierarchy: m_TreeViewState: scrollPos: {x: 0, y: 0} m_SelectedIDs: b0010000 m_LastClickedID: 0 m_ExpandedIDs: 76fbffff m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 0 m_ClientGUIView: {fileID: 4} m_SearchString: m_ExpandedScenes: [] m_CurrenRootInstanceID: 0 m_LockTracker: m_IsLocked: 0 m_CurrentSortingName: TransformSorting m_WindowGUID: d2da7c7f6b6a12f4db008859d58f4b06 --- !u!114 &16 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Scene m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 407 y: 73 width: 1216 height: 777 m_ViewDataDictionary: {fileID: 0} m_ShowContextualTools: 0 m_WindowGUID: e16c040b0f7d1444f814c10b57524ecd m_Gizmos: 1 m_SceneIsLit: 1 m_SceneLighting: 1 m_2DMode: 0 m_isRotationLocked: 0 m_PlayAudio: 0 m_AudioPlay: 0 m_Position: m_Target: {x: 2.5099688, y: 2.2473466, z: -3.8579397} speed: 2 m_Value: {x: 2.5099688, y: 2.2473466, z: -3.8579397} m_RenderMode: 0 m_CameraMode: drawMode: 0 name: Shaded section: Shading Mode m_ValidateTrueMetals: 0 m_DoValidateTrueMetals: 0 m_SceneViewState: showFog: 1 showMaterialUpdate: 0 showSkybox: 1 showFlares: 1 showImageEffects: 1 showParticleSystems: 1 grid: xGrid: m_Target: 0 speed: 2 m_Value: 0 yGrid: m_Target: 0 speed: 2 m_Value: 0 zGrid: m_Target: 0 speed: 2 m_Value: 0 m_Rotation: m_Target: {x: -0.09469341, y: 0.6731113, z: -0.08752819, w: -0.72821313} speed: 2 m_Value: {x: -0.09469341, y: 0.6731113, z: -0.0875282, w: -0.72821313} m_Size: m_Target: 15.153814 speed: 2 m_Value: 15.153814 m_Ortho: m_Target: 0 speed: 2 m_Value: 0 m_CameraSettings: m_Speed: 1 m_SpeedNormalized: 0.5 m_SpeedMin: 0.01 m_SpeedMax: 2 m_EasingEnabled: 1 m_EasingDuration: 0.4 m_AccelerationEnabled: 1 m_FieldOfView: 90 m_NearClip: 0.03 m_FarClip: 10000 m_DynamicClip: 1 m_OcclusionCulling: 0 m_ShowGlobalGrid: 1 m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0} m_LastSceneViewOrtho: 0 m_ReplacementShader: {fileID: 0} m_ReplacementString: m_SceneVisActive: 1 m_LastLockedObject: {fileID: 0} m_ViewIsLockedToObject: 0 --- !u!114 &17 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Game m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 539 y: 73 width: 1416 height: 683 m_ViewDataDictionary: {fileID: 0} m_VSyncEnabled: 0 m_MaximizeOnPlay: 0 m_Gizmos: 0 m_Stats: 0 m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 m_TargetDisplay: 0 m_ZoomArea: m_HRangeLocked: 0 m_VRangeLocked: 0 hZoomLockedByDefault: 0 vZoomLockedByDefault: 0 m_HBaseRangeMin: -708 m_HBaseRangeMax: 708 m_VBaseRangeMin: -333 m_VBaseRangeMax: 333 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 m_VAllowExceedBaseRangeMax: 1 m_ScaleWithWindow: 0 m_HSlider: 0 m_VSlider: 0 m_IgnoreScrollWheelUntilClicked: 0 m_EnableMouseInput: 1 m_EnableSliderZoomHorizontal: 0 m_EnableSliderZoomVertical: 0 m_UniformScale: 1 m_UpDirection: 1 m_DrawArea: serializedVersion: 2 x: 0 y: 17 width: 1416 height: 666 m_Scale: {x: 1, y: 1} m_Translation: {x: 708, y: 333} m_MarginLeft: 0 m_MarginRight: 0 m_MarginTop: 0 m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 x: -708 y: -333 width: 1416 height: 666 m_MinimalGUI: 1 m_defaultScale: 1 m_TargetTexture: {fileID: 0} m_CurrentColorSpace: 0 m_LastWindowPixelSize: {x: 1416, y: 683} m_ClearInEditMode: 1 m_NoCameraWarning: 1 m_LowResolutionForAspectRatios: 00000000000000000000 m_XRRenderMode: 0 --- !u!114 &18 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 100, y: 100} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Console m_Image: {fileID: 111653112392082826, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 0 y: 776 width: 1957 height: 585 m_ViewDataDictionary: {fileID: 0} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/CurrentLayout.dwlt ================================================ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &1 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_PixelRect: serializedVersion: 2 x: 0 y: 43 width: 1920 height: 997 m_ShowMode: 4 m_Title: m_RootView: {fileID: 6} m_MinSize: {x: 950, y: 300} m_MaxSize: {x: 10000, y: 10000} --- !u!114 &2 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 9} - {fileID: 3} m_Position: serializedVersion: 2 x: 0 y: 30 width: 1920 height: 947 m_MinSize: {x: 683, y: 492} m_MaxSize: {x: 14004, y: 14042} vertical: 0 controlID: 112 --- !u!114 &3 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 1146 y: 0 width: 774 height: 947 m_MinSize: {x: 275, y: 50} m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 13} m_Panes: - {fileID: 13} m_Selected: 0 m_LastSelected: 0 --- !u!114 &4 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 0 width: 285 height: 560 m_MinSize: {x: 202, y: 221} m_MaxSize: {x: 4002, y: 4021} m_ActualView: {fileID: 14} m_Panes: - {fileID: 14} m_Selected: 0 m_LastSelected: 0 --- !u!114 &5 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 560 width: 1146 height: 387 m_MinSize: {x: 232, y: 271} m_MaxSize: {x: 10002, y: 10021} m_ActualView: {fileID: 12} m_Panes: - {fileID: 12} - {fileID: 17} m_Selected: 0 m_LastSelected: 1 --- !u!114 &6 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 7} - {fileID: 2} - {fileID: 8} m_Position: serializedVersion: 2 x: 0 y: 0 width: 1920 height: 997 m_MinSize: {x: 950, y: 300} m_MaxSize: {x: 10000, y: 10000} --- !u!114 &7 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 0 width: 1920 height: 30 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} m_LastLoadedLayoutName: --- !u!114 &8 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 977 width: 1920 height: 20 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} --- !u!114 &9 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 10} - {fileID: 5} m_Position: serializedVersion: 2 x: 0 y: 0 width: 1146 height: 947 m_MinSize: {x: 406, y: 492} m_MaxSize: {x: 10002, y: 14042} vertical: 1 controlID: 69 --- !u!114 &10 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 4} - {fileID: 11} m_Position: serializedVersion: 2 x: 0 y: 0 width: 1146 height: 560 m_MinSize: {x: 406, y: 221} m_MaxSize: {x: 8006, y: 4021} vertical: 0 controlID: 45 --- !u!114 &11 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 285 y: 0 width: 861 height: 560 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 15} m_Panes: - {fileID: 15} - {fileID: 16} m_Selected: 0 m_LastSelected: 0 --- !u!114 &12 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_AutoRepaintOnSceneChange: 0 m_MinSize: {x: 230, y: 250} m_MaxSize: {x: 10000, y: 10000} m_TitleContent: m_Text: Project m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_DepthBufferBits: 0 m_Pos: serializedVersion: 2 x: 0 y: 652 width: 1144 height: 366 m_SearchFilter: m_NameFilter: m_ClassNames: [] m_AssetLabels: [] m_AssetBundleNames: [] m_VersionControlStates: [] m_SoftLockControlStates: [] m_ReferencingInstanceIDs: m_ScenePaths: [] m_ShowAllHits: 0 m_SearchArea: 0 m_Folders: - Assets/shaders/Instancing m_ViewMode: 1 m_StartGridSize: 64 m_LastFolders: - Assets/shaders/Instancing m_LastFoldersGridSize: -1 m_LastProjectPath: E:\gh\scattererGithub\Scatterer\scatterer\Shaders\scattererShaders m_IsLocked: 0 m_FolderTreeState: scrollPos: {x: 0, y: 0} m_SelectedIDs: 02270000 m_LastClickedID: 9986 m_ExpandedIDs: 00000000aa260000b826000000ca9a3bffffff7f m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 5} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_AssetTreeState: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 m_ExpandedIDs: 00000000aa260000b8260000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 0} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_ListAreaState: m_SelectedInstanceIDs: m_LastClickedInstanceID: 0 m_HadKeyboardFocusLastEvent: 1 m_ExpandedInstanceIDs: 76230000602300004a22000060220000542200005e220000322200001c22000000000000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 5} m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_NewAssetIndexInList: -1 m_ScrollPosition: {x: 0, y: 0} m_GridSize: 64 m_DirectoriesAreaWidth: 305 --- !u!114 &13 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_AutoRepaintOnSceneChange: 0 m_MinSize: {x: 275, y: 50} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Inspector m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_DepthBufferBits: 0 m_Pos: serializedVersion: 2 x: 1148 y: 92 width: 772 height: 926 m_ScrollPosition: {x: 0, y: 822.9551} m_InspectorMode: 0 m_PreviewResizer: m_CachedPref: 160 m_ControlHash: -371814159 m_PrefName: Preview_InspectorPreview m_PreviewWindow: {fileID: 0} --- !u!114 &14 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_AutoRepaintOnSceneChange: 0 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Hierarchy m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_DepthBufferBits: 0 m_Pos: serializedVersion: 2 x: 0 y: 92 width: 283 height: 539 m_TreeViewState: scrollPos: {x: 0, y: 0} m_SelectedIDs: ea010000 m_LastClickedID: 0 m_ExpandedIDs: 1afcffff00000000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 0 m_ClientGUIView: {fileID: 0} m_SearchString: m_ExpandedScenes: - m_CurrenRootInstanceID: 0 m_Locked: 0 m_CurrentSortingName: TransformSorting --- !u!114 &15 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_AutoRepaintOnSceneChange: 1 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Scene m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_DepthBufferBits: 32 m_Pos: serializedVersion: 2 x: 287 y: 92 width: 857 height: 539 m_SceneLighting: 0 lastFramingTime: 0 m_2DMode: 0 m_isRotationLocked: 0 m_AudioPlay: 0 m_Position: m_Target: {x: 0, y: 0, z: 0} speed: 2 m_Value: {x: 0, y: 0, z: 0} m_RenderMode: 0 m_ValidateTrueMetals: 0 m_SceneViewState: showFog: 1 showMaterialUpdate: 0 showSkybox: 1 showFlares: 1 showImageEffects: 1 grid: xGrid: m_Target: 0 speed: 2 m_Value: 0 yGrid: m_Target: 1 speed: 2 m_Value: 1 zGrid: m_Target: 0 speed: 2 m_Value: 0 m_Rotation: m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} speed: 2 m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} m_Size: m_Target: 8.301052 speed: 2 m_Value: 8.301052 m_Ortho: m_Target: 0 speed: 2 m_Value: 0 m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0} m_LastSceneViewOrtho: 0 m_ReplacementShader: {fileID: 0} m_ReplacementString: m_LastLockedObject: {fileID: 0} m_ViewIsLockedToObject: 0 --- !u!114 &16 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_AutoRepaintOnSceneChange: 1 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Game m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_DepthBufferBits: 32 m_Pos: serializedVersion: 2 x: 366 y: 17 width: 518 height: 205 m_MaximizeOnPlay: 0 m_Gizmos: 0 m_Stats: 0 m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 m_TargetDisplay: 0 m_ZoomArea: m_HRangeLocked: 0 m_VRangeLocked: 0 m_HBaseRangeMin: -259 m_HBaseRangeMax: 259 m_VBaseRangeMin: -94 m_VBaseRangeMax: 94 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 m_VAllowExceedBaseRangeMax: 1 m_ScaleWithWindow: 0 m_HSlider: 1 m_VSlider: 1 m_IgnoreScrollWheelUntilClicked: 0 m_EnableMouseInput: 1 m_EnableSliderZoom: 0 m_UniformScale: 1 m_UpDirection: 1 m_DrawArea: serializedVersion: 2 x: 0 y: 17 width: 518 height: 188 m_Scale: {x: 1, y: 1} m_Translation: {x: 259, y: 94} m_MarginLeft: 0 m_MarginRight: 0 m_MarginTop: 0 m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 x: -259 y: -94 width: 518 height: 188 m_MinimalGUI: 1 m_defaultScale: 1 m_TargetTexture: {fileID: 0} m_CurrentColorSpace: -1 m_LastWindowPixelSize: {x: 518, y: 205} m_ClearInEditMode: 1 m_NoCameraWarning: 1 m_LowResolutionForAspectRatios: 01000000000100000100 --- !u!114 &17 MonoBehaviour: m_ObjectHideFlags: 52 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_AutoRepaintOnSceneChange: 0 m_MinSize: {x: 100, y: 100} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Console m_Image: {fileID: 111653112392082826, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_DepthBufferBits: 0 m_Pos: serializedVersion: 2 x: 0 y: 652 width: 1496 height: 366 ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/CurrentMaximizeLayout.dwlt ================================================ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &1 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 3} - {fileID: 7} - {fileID: 9} - {fileID: 11} m_Position: serializedVersion: 2 x: 0 y: 30 width: 1920 height: 987 m_MinSize: {x: 911, y: 422} m_MaxSize: {x: 22006, y: 10022} vertical: 0 controlID: 9359 --- !u!114 &2 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Game m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 0 y: 579 width: 1118 height: 462 m_ViewDataDictionary: {fileID: 0} m_VSyncEnabled: 0 m_MaximizeOnPlay: 1 m_Gizmos: 0 m_Stats: 0 m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 m_TargetDisplay: 0 m_ZoomArea: m_HRangeLocked: 0 m_VRangeLocked: 0 hZoomLockedByDefault: 0 vZoomLockedByDefault: 0 m_HBaseRangeMin: -559 m_HBaseRangeMax: 559 m_VBaseRangeMin: -222.5 m_VBaseRangeMax: 222.5 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 m_VAllowExceedBaseRangeMax: 1 m_ScaleWithWindow: 0 m_HSlider: 0 m_VSlider: 0 m_IgnoreScrollWheelUntilClicked: 0 m_EnableMouseInput: 1 m_EnableSliderZoomHorizontal: 0 m_EnableSliderZoomVertical: 0 m_UniformScale: 1 m_UpDirection: 1 m_DrawArea: serializedVersion: 2 x: 0 y: 17 width: 1118 height: 445 m_Scale: {x: 1, y: 1} m_Translation: {x: 559, y: 222.5} m_MarginLeft: 0 m_MarginRight: 0 m_MarginTop: 0 m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 x: -559 y: -222.5 width: 1118 height: 445 m_MinimalGUI: 1 m_defaultScale: 1 m_TargetTexture: {fileID: 0} m_CurrentColorSpace: 0 m_LastWindowPixelSize: {x: 1118, y: 462} m_ClearInEditMode: 1 m_NoCameraWarning: 1 m_LowResolutionForAspectRatios: 00000000000000000000 m_XRRenderMode: 0 --- !u!114 &3 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: - {fileID: 4} - {fileID: 6} m_Position: serializedVersion: 2 x: 0 y: 0 width: 1118 height: 987 m_MinSize: {x: 202, y: 422} m_MaxSize: {x: 4002, y: 8022} vertical: 1 controlID: 9339 --- !u!114 &4 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 0 width: 1118 height: 506 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 5} m_Panes: - {fileID: 5} m_Selected: 0 m_LastSelected: 0 --- !u!114 &5 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Scene m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 0 y: 73 width: 1118 height: 487 m_ViewDataDictionary: {fileID: 0} m_ShowContextualTools: 0 m_WindowGUID: 417d2720dfd54b04e8c7f277f5480c5b m_Gizmos: 1 m_SceneIsLit: 1 m_SceneLighting: 1 m_2DMode: 0 m_isRotationLocked: 0 m_PlayAudio: 0 m_AudioPlay: 0 m_Position: m_Target: {x: 0, y: 0, z: 0} speed: 2 m_Value: {x: 0, y: 0, z: 0} m_RenderMode: 0 m_CameraMode: drawMode: 0 name: Shaded section: Shading Mode m_ValidateTrueMetals: 0 m_DoValidateTrueMetals: 0 m_SceneViewState: showFog: 1 showMaterialUpdate: 0 showSkybox: 1 showFlares: 1 showImageEffects: 1 showParticleSystems: 1 grid: xGrid: m_Target: 0 speed: 2 m_Value: 0 yGrid: m_Target: 1 speed: 2 m_Value: 1 zGrid: m_Target: 0 speed: 2 m_Value: 0 m_Rotation: m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} speed: 2 m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} m_Size: m_Target: 24.136803 speed: 2 m_Value: 24.136803 m_Ortho: m_Target: 0 speed: 2 m_Value: 0 m_CameraSettings: m_Speed: 1 m_SpeedNormalized: 0.5 m_SpeedMin: 0.01 m_SpeedMax: 2 m_EasingEnabled: 1 m_EasingDuration: 0.4 m_AccelerationEnabled: 1 m_FieldOfView: 90 m_NearClip: 0.03 m_FarClip: 10000 m_DynamicClip: 1 m_OcclusionCulling: 0 m_ShowGlobalGrid: 1 m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0} m_LastSceneViewOrtho: 0 m_ReplacementShader: {fileID: 0} m_ReplacementString: m_SceneVisActive: 1 m_LastLockedObject: {fileID: 0} m_ViewIsLockedToObject: 0 --- !u!114 &6 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 0 y: 506 width: 1118 height: 481 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 2} m_Panes: - {fileID: 2} m_Selected: 0 m_LastSelected: 0 --- !u!114 &7 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 1118 y: 0 width: 291 height: 987 m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 8} m_Panes: - {fileID: 8} m_Selected: 0 m_LastSelected: 0 --- !u!114 &8 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Hierarchy m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 1118 y: 73 width: 289 height: 968 m_ViewDataDictionary: {fileID: 0} m_SceneHierarchy: m_TreeViewState: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 m_ExpandedIDs: 76fbffff m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 0 m_ClientGUIView: {fileID: 0} m_SearchString: m_ExpandedScenes: [] m_CurrenRootInstanceID: 0 m_LockTracker: m_IsLocked: 0 m_CurrentSortingName: TransformSorting m_WindowGUID: df32a1043b8c1ff428dc088186916235 --- !u!114 &9 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 1409 y: 0 width: 234 height: 987 m_MinSize: {x: 230, y: 250} m_MaxSize: {x: 10000, y: 10000} m_ActualView: {fileID: 10} m_Panes: - {fileID: 10} m_Selected: 0 m_LastSelected: 0 --- !u!114 &10 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 230, y: 250} m_MaxSize: {x: 10000, y: 10000} m_TitleContent: m_Text: Project m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 1409 y: 73 width: 232 height: 968 m_ViewDataDictionary: {fileID: 0} m_SearchFilter: m_NameFilter: m_ClassNames: [] m_AssetLabels: [] m_AssetBundleNames: [] m_VersionControlStates: [] m_SoftLockControlStates: [] m_ReferencingInstanceIDs: m_SceneHandles: m_ShowAllHits: 0 m_SkipHidden: 0 m_SearchArea: 1 m_Folders: - Assets/Shaders/Ocean/Caustics m_ViewMode: 1 m_StartGridSize: 64 m_LastFolders: - Assets/Shaders/Ocean/Caustics m_LastFoldersGridSize: -1 m_LastProjectPath: E:\gh\scattererGithub\Scatterer\scatterer\Shaders\scattererShaders m_LockTracker: m_IsLocked: 0 m_FolderTreeState: scrollPos: {x: 0, y: 0} m_SelectedIDs: c22d0000 m_LastClickedID: 11714 m_ExpandedIDs: 000000003a2d00006e2d0000cc2f0000d42f000000ca9a3b m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 0} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_AssetTreeState: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 m_ExpandedIDs: 000000003a2d00006e2d0000cc2f0000d42f000000ca9a3b m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 0} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_ListAreaState: m_SelectedInstanceIDs: 2a310000 m_LastClickedInstanceID: 12586 m_HadKeyboardFocusLastEvent: 0 m_ExpandedInstanceIDs: m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 m_UserData: 0 m_IsWaitingForDelay: 0 m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 0} m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 m_Path: m_Icon: {fileID: 0} m_ResourceFile: m_NewAssetIndexInList: -1 m_ScrollPosition: {x: 0, y: 298} m_GridSize: 64 m_SkipHiddenPackages: 0 m_DirectoriesAreaWidth: 112 --- !u!114 &11 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 x: 1643 y: 0 width: 277 height: 987 m_MinSize: {x: 275, y: 50} m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 12} m_Panes: - {fileID: 12} m_Selected: 0 m_LastSelected: 0 --- !u!114 &12 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 275, y: 50} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Inspector m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_Pos: serializedVersion: 2 x: 1643 y: 73 width: 275 height: 968 m_ViewDataDictionary: {fileID: 0} m_OpenAddComponentMenu: 0 m_ObjectsLockedBeforeSerialization: [] m_InstanceIDsLockedBeforeSerialization: m_LockTracker: m_IsLocked: 0 m_PreviewResizer: m_CachedPref: -160 m_ControlHash: -371814159 m_PrefName: Preview_InspectorPreview m_PreviewWindow: {fileID: 0} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/EditorOnlyScriptingSettings.json ================================================ {"m_DefineSymbols":[{"first":1,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":7,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":13,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":19,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":21,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":25,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":26,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":27,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":28,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":29,"second":"UNITY_POST_PROCESSING_STACK_V2"}],"m_AllowUnsafeCode":false} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/EditorOnlyScriptingUserSettings.json ================================================ {"m_ScriptingRuntimeVersion":1,"m_DefineSymbols":[],"m_AllowUnsafeCode":false} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/EditorSnapSettings.asset ================================================ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &1 MonoBehaviour: m_ObjectHideFlags: 61 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 13954, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: m_SnapEnabled: 0 m_SnapSettings: m_SnapValue: {x: 0.25, y: 0.25, z: 0.25} m_SnapMultiplier: {x: 2048, y: 2048, z: 2048} m_Rotation: 15 m_Scale: 1 ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/LastSceneManagerSetup.txt ================================================ sceneSetups: - path: Assets/Shaders/Ocean/Caustics/CausticsScene.unity isLoaded: 1 isActive: 1 isSubScene: 0 ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/LibraryFormatVersion.txt ================================================ unityRebuildLibraryVersion: 11 unityForwardCompatibleVersion: 40 ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/.npmignore ================================================ automation/** utr_output/** .Editor/** .yamato/** *.zip* ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/CHANGELOG.md ================================================ # Changelog All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [1.2.16] - 2019-02-11 Update stylesheet to pass USS validation ## [1.2.15] - 2018-11-16 Added support for non-experimental UIElements. ## [1.2.11] - 2018-09-04 Made some performance improvements to reduce impact on ReloadAssemblies. ## [1.2.9] - 2018-08-13 Test issues for the Collab History Window are now fixed. ## [1.2.7] - 2018-08-07 Toolbar drop-down will no longer show up when package is uninstalled. ## [1.2.6] - 2018-06-15 Fixed an issue where Collab's History window wouldn't load properly. ## [1.2.5] - 2018-05-21 This is the first release of *Unity Package CollabProxy*. ### Added - Collab history and toolbar windows - Collab view and presenter classes - Collab Editor tests for view and presenter ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/CHANGELOG.md.meta ================================================ fileFormatVersion: 2 guid: 782c49e6e68074dc7ba12c95537825ce TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/DEPENDENCIES.md ================================================ Unity.CollabProxy.Dependencies 1.1.0-experimental Rohit Garg Dependencies for the CollabProxy package ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/DEPENDENCIES.md.meta ================================================ fileFormatVersion: 2 guid: 470530e667ad4475786b28fa3187ce95 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Documentation~/collab-proxy.md ================================================ # About Unity Collaborate Collaborate is a simple way for teams to save, share, and sync their Unity project. Please refer to the online documentation [here.](https://docs.unity3d.com/Manual/UnityCollaborate.html) ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/AssemblyInfo.cs ================================================ using System.Runtime.CompilerServices; using UnityEngine; [assembly: InternalsVisibleTo("Unity.CollabProxy.EditorTests")] ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/AssemblyInfo.cs.meta ================================================ fileFormatVersion: 2 guid: d4ef26aa386b44923b61c9c4b505a67c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Bootstrap.cs ================================================ using UnityEditor; using UnityEditor.Collaboration; using UnityEngine; namespace CollabProxy.UI { [InitializeOnLoad] public class Bootstrap { private const float kCollabToolbarButtonWidth = 78.0f; static Bootstrap() { Collab.ShowHistoryWindow = CollabHistoryWindow.ShowHistoryWindow; Collab.ShowToolbarAtPosition = CollabToolbarWindow.ShowCenteredAtPosition; Collab.IsToolbarVisible = CollabToolbarWindow.IsVisible; Collab.CloseToolbar = CollabToolbarWindow.CloseToolbar; Toolbar.AddSubToolbar(new CollabToolbarButton { Width = kCollabToolbarButtonWidth }); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Bootstrap.cs.meta ================================================ fileFormatVersion: 2 guid: 8aa8171e088f94069bbd1978a053f7dd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabAnalytics.cs ================================================ using System; namespace UnityEditor.Collaboration { internal static class CollabAnalytics { [Serializable] private struct CollabUserActionAnalyticsEvent { public string category; public string action; } public static void SendUserAction(string category, string action) { EditorAnalytics.SendCollabUserAction(new CollabUserActionAnalyticsEvent() { category = category, action = action }); } public static readonly string historyCategoryString = "History"; }; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabAnalytics.cs.meta ================================================ fileFormatVersion: 2 guid: f944311c8fff2479fa3ba741f6039fc8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabHistoryWindow.cs ================================================ using System; using System.Linq; using System.Collections.Generic; using UnityEditor.Collaboration; #if UNITY_2019_1_OR_NEWER using UnityEditor.UIElements; using UnityEngine.UIElements; #else using UnityEditor.Experimental.UIElements; using UnityEngine.Experimental.UIElements; using UnityEngine.Experimental.UIElements.StyleEnums; #endif using UnityEngine; using UnityEditor.Connect; namespace UnityEditor { internal class CollabHistoryWindow : EditorWindow, ICollabHistoryWindow { #if UNITY_2019_1_OR_NEWER private const string ResourcesPath = "Packages/com.unity.collab-proxy/Editor/Resources/Styles/"; #else private const string ResourcesPath = "StyleSheets/"; #endif const string kWindowTitle = "Collab History"; const string kServiceUrl = "developer.cloud.unity3d.com"; [MenuItem("Window/Asset Management/Collab History", false, 1)] public static void ShowHistoryWindow() { EditorWindow.GetWindow(kWindowTitle); } [MenuItem("Window/Asset Management/Collab History", true)] public static bool ValidateShowHistoryWindow() { return Collab.instance.IsCollabEnabledForCurrentProject(); } CollabHistoryPresenter m_Presenter; Dictionary m_Views; List m_HistoryItems = new List(); HistoryState m_State; VisualElement m_Container; PagedListView m_Pager; ScrollView m_HistoryView; int m_ItemsPerPage = 5; string m_InProgressRev; bool m_RevisionActionsEnabled; public CollabHistoryWindow() { minSize = new Vector2(275, 50); } public void OnEnable() { SetupGUI(); name = "CollabHistory"; if (m_Presenter == null) { m_Presenter = new CollabHistoryPresenter(this, new CollabHistoryItemFactory(), new RevisionsService(Collab.instance, UnityConnect.instance)); } m_Presenter.OnWindowEnabled(); } public void OnDisable() { m_Presenter.OnWindowDisabled(); } public bool revisionActionsEnabled { get { return m_RevisionActionsEnabled; } set { if (m_RevisionActionsEnabled == value) return; m_RevisionActionsEnabled = value; foreach (var historyItem in m_HistoryItems) { historyItem.RevisionActionsEnabled = value; } } } private void AddStyleSheetPath(VisualElement root, string path) { #if UNITY_2019_1_OR_NEWER root.styleSheets.Add(EditorGUIUtility.Load(path) as StyleSheet); #else root.AddStyleSheetPath(path); #endif } public void SetupGUI() { #if UNITY_2019_1_OR_NEWER var root = this.rootVisualElement; #else var root = this.GetRootVisualContainer(); #endif AddStyleSheetPath(root, ResourcesPath + "CollabHistoryCommon.uss"); if (EditorGUIUtility.isProSkin) { AddStyleSheetPath(root, ResourcesPath + "CollabHistoryDark.uss"); } else { AddStyleSheetPath(root, ResourcesPath + "CollabHistoryLight.uss"); } m_Container = new VisualElement(); m_Container.StretchToParentSize(); root.Add(m_Container); m_Pager = new PagedListView() { name = "PagedElement", pageSize = m_ItemsPerPage }; var errorView = new StatusView() { message = "An Error Occurred", icon = EditorGUIUtility.LoadIconRequired("Collab.Warning") as Texture, }; var noInternetView = new StatusView() { message = "No Internet Connection", icon = EditorGUIUtility.LoadIconRequired("Collab.NoInternet") as Texture, }; var maintenanceView = new StatusView() { message = "Maintenance", }; var loginView = new StatusView() { message = "Sign in to access Collaborate", buttonText = "Sign in...", callback = SignInClick, }; var noSeatView = new StatusView() { message = "Ask your project owner for access to Unity Teams", buttonText = "Learn More", callback = NoSeatClick, }; var waitingView = new StatusView() { message = "Updating...", }; m_HistoryView = new ScrollView() { name = "HistoryContainer", showHorizontal = false}; m_HistoryView.contentContainer.StretchToParentWidth(); m_HistoryView.Add(m_Pager); m_Views = new Dictionary() { {HistoryState.Error, errorView}, {HistoryState.Offline, noInternetView}, {HistoryState.Maintenance, maintenanceView}, {HistoryState.LoggedOut, loginView}, {HistoryState.NoSeat, noSeatView}, {HistoryState.Waiting, waitingView}, {HistoryState.Ready, m_HistoryView} }; } public void UpdateState(HistoryState state, bool force) { if (state == m_State && !force) return; m_State = state; switch (state) { case HistoryState.Ready: UpdateHistoryView(m_Pager); break; case HistoryState.Disabled: Close(); return; } m_Container.Clear(); m_Container.Add(m_Views[m_State]); } public void UpdateRevisions(IEnumerable datas, string tip, int totalRevisions, int currentPage) { var elements = new List(); var isFullDateObtained = false; // Has everything from this date been obtained? m_HistoryItems.Clear(); if (datas != null) { DateTime currentDate = DateTime.MinValue; foreach (var data in datas) { if (data.timeStamp.Date != currentDate.Date) { elements.Add(new CollabHistoryRevisionLine(data.timeStamp, isFullDateObtained)); currentDate = data.timeStamp; } var item = new CollabHistoryItem(data); m_HistoryItems.Add(item); var container = new VisualElement(); container.style.flexDirection = FlexDirection.Row; if (data.current) { isFullDateObtained = true; container.AddToClassList("currentRevision"); container.AddToClassList("obtainedRevision"); } else if (data.obtained) { container.AddToClassList("obtainedRevision"); } else { container.AddToClassList("absentRevision"); } // If we use the index as-is, the latest commit will become #1, but we want it to be last container.Add(new CollabHistoryRevisionLine(data.index)); container.Add(item); elements.Add(container); } } m_HistoryView.scrollOffset = new Vector2(0, 0); m_Pager.totalItems = totalRevisions; m_Pager.curPage = currentPage; m_Pager.items = elements; } public string inProgressRevision { get { return m_InProgressRev; } set { m_InProgressRev = value; foreach (var historyItem in m_HistoryItems) { historyItem.SetInProgressStatus(value); } } } public int itemsPerPage { set { if (m_ItemsPerPage == value) return; m_Pager.pageSize = m_ItemsPerPage; } } public PageChangeAction OnPageChangeAction { set { m_Pager.OnPageChanged = value; } } public RevisionAction OnGoBackAction { set { CollabHistoryItem.s_OnGoBack = value; } } public RevisionAction OnUpdateAction { set { CollabHistoryItem.s_OnUpdate = value; } } public RevisionAction OnRestoreAction { set { CollabHistoryItem.s_OnRestore = value; } } public ShowBuildAction OnShowBuildAction { set { CollabHistoryItem.s_OnShowBuild = value; } } public Action OnShowServicesAction { set { CollabHistoryItem.s_OnShowServices = value; } } void UpdateHistoryView(VisualElement history) { } void NoSeatClick() { var connection = UnityConnect.instance; var env = connection.GetEnvironment(); // Map environment to url - prod is special if (env == "production") env = ""; else env += "-"; var url = "https://" + env + kServiceUrl + "/orgs/" + connection.GetOrganizationId() + "/projects/" + connection.GetProjectName() + "/unity-teams/"; Application.OpenURL(url); } void SignInClick() { UnityConnect.instance.ShowLogin(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabHistoryWindow.cs.meta ================================================ fileFormatVersion: 2 guid: fed9dda667cab45d398d06402bba03f4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarButton.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEditor.Collaboration; using UnityEditor.Connect; using UnityEditor.Web; using UnityEngine; namespace UnityEditor { internal class CollabToolbarButton : SubToolbar, IDisposable { // Must match s_CollabIcon array enum CollabToolbarState { NeedToEnableCollab, UpToDate, Conflict, OperationError, ServerHasChanges, FilesToPush, InProgress, Disabled, Offline } private class CollabToolbarContent { readonly string m_iconName; readonly string m_toolTip; readonly CollabToolbarState m_state; static Dictionary m_CollabIcons; public CollabToolbarState RegisteredForState { get { return m_state; } } public GUIContent GuiContent { get { if (m_CollabIcons == null) { m_CollabIcons = new Dictionary(); } if (!m_CollabIcons.ContainsKey(this)) { m_CollabIcons.Add(this, EditorGUIUtility.TrTextContentWithIcon("Collab", m_toolTip, m_iconName)); } return m_CollabIcons[this]; } } public CollabToolbarContent(CollabToolbarState state, string iconName, string toolTip) { m_state = state; m_iconName = iconName; m_toolTip = toolTip; } } CollabToolbarContent[] m_toolbarContents; CollabToolbarState m_CollabToolbarState = CollabToolbarState.UpToDate; const float kCollabButtonWidth = 78.0f; ButtonWithAnimatedIconRotation m_CollabButton; string m_DynamicTooltip; static bool m_ShowCollabTooltip = false; private GUIContent currentCollabContent { get { CollabToolbarContent toolbarContent = m_toolbarContents.FirstOrDefault(c => c.RegisteredForState.Equals(m_CollabToolbarState)); GUIContent content = new GUIContent(toolbarContent == null? m_toolbarContents.First().GuiContent : toolbarContent.GuiContent); if (!m_ShowCollabTooltip) { content.tooltip = null; } else if (m_DynamicTooltip != "") { content.tooltip = m_DynamicTooltip; } if (Collab.instance.AreTestsRunning()) { content.text = "CTF"; } return content; } } public CollabToolbarButton() { m_toolbarContents = new[] { new CollabToolbarContent(CollabToolbarState.NeedToEnableCollab, "CollabNew", " You need to enable collab."), new CollabToolbarContent(CollabToolbarState.UpToDate, "Collab", " You are up to date."), new CollabToolbarContent(CollabToolbarState.Conflict, "CollabConflict", " Please fix your conflicts prior to publishing."), new CollabToolbarContent(CollabToolbarState.OperationError, "CollabError", " Last operation failed. Please retry later."), new CollabToolbarContent(CollabToolbarState.ServerHasChanges, "CollabPull", " Please update, there are server changes."), new CollabToolbarContent(CollabToolbarState.FilesToPush, "CollabPush", " You have files to publish."), new CollabToolbarContent(CollabToolbarState.InProgress, "CollabProgress", " Operation in progress."), new CollabToolbarContent(CollabToolbarState.Disabled, "CollabNew", " Collab is disabled."), new CollabToolbarContent(CollabToolbarState.Offline, "CollabNew", " Please check your network connection.") }; Collab.instance.StateChanged += OnCollabStateChanged; UnityConnect.instance.StateChanged += OnUnityConnectStateChanged; UnityConnect.instance.UserStateChanged += OnUnityConnectUserStateChanged; } void OnUnityConnectUserStateChanged(UserInfo state) { UpdateCollabToolbarState(); } void OnUnityConnectStateChanged(ConnectInfo state) { UpdateCollabToolbarState(); } public override void OnGUI(Rect rect) { DoCollabDropDown(rect); } Rect GUIToScreenRect(Rect guiRect) { Vector2 screenPoint = GUIUtility.GUIToScreenPoint(new Vector2(guiRect.x, guiRect.y)); guiRect.x = screenPoint.x; guiRect.y = screenPoint.y; return guiRect; } void ShowPopup(Rect rect) { // window should be centered on the button ReserveRight(kCollabButtonWidth / 2, ref rect); ReserveBottom(5, ref rect); // calculate screen rect before saving assets since it might open the AssetSaveDialog window var screenRect = GUIToScreenRect(rect); // save all the assets AssetDatabase.SaveAssets(); if (Collab.ShowToolbarAtPosition != null && Collab.ShowToolbarAtPosition(screenRect)) { GUIUtility.ExitGUI(); } } void DoCollabDropDown(Rect rect) { UpdateCollabToolbarState(); GUIStyle collabButtonStyle = "OffsetDropDown"; bool showPopup = Toolbar.requestShowCollabToolbar; Toolbar.requestShowCollabToolbar = false; bool enable = !EditorApplication.isPlaying; using (new EditorGUI.DisabledScope(!enable)) { bool animate = m_CollabToolbarState == CollabToolbarState.InProgress; EditorGUIUtility.SetIconSize(new Vector2(12, 12)); if (GetCollabButton().OnGUI(rect, currentCollabContent, animate, collabButtonStyle)) { showPopup = true; } EditorGUIUtility.SetIconSize(Vector2.zero); } if (m_CollabToolbarState == CollabToolbarState.Disabled) return; if (showPopup) { ShowPopup(rect); } } public void OnCollabStateChanged(CollabInfo info) { UpdateCollabToolbarState(); } public void UpdateCollabToolbarState() { var currentCollabState = CollabToolbarState.UpToDate; bool networkAvailable = UnityConnect.instance.connectInfo.online && UnityConnect.instance.connectInfo.loggedIn; m_DynamicTooltip = ""; if (UnityConnect.instance.isDisableCollabWindow) { currentCollabState = CollabToolbarState.Disabled; } else if (networkAvailable) { Collab collab = Collab.instance; CollabInfo currentInfo = collab.collabInfo; UnityErrorInfo errInfo; bool error = false; if (collab.GetError((UnityConnect.UnityErrorFilter.ByContext | UnityConnect.UnityErrorFilter.ByChild), out errInfo)) { error = (errInfo.priority <= (int)UnityConnect.UnityErrorPriority.Error); m_DynamicTooltip = errInfo.shortMsg; } if (!currentInfo.ready) { currentCollabState = CollabToolbarState.InProgress; } else if (error) { currentCollabState = CollabToolbarState.OperationError; } else if (currentInfo.inProgress) { currentCollabState = CollabToolbarState.InProgress; } else { bool collabEnable = Collab.instance.IsCollabEnabledForCurrentProject(); if (UnityConnect.instance.projectInfo.projectBound == false || !collabEnable) { currentCollabState = CollabToolbarState.NeedToEnableCollab; } else if (currentInfo.update) { currentCollabState = CollabToolbarState.ServerHasChanges; } else if (currentInfo.conflict) { currentCollabState = CollabToolbarState.Conflict; } else if (currentInfo.publish) { currentCollabState = CollabToolbarState.FilesToPush; } } } else { currentCollabState = CollabToolbarState.Offline; } if (Collab.IsToolbarVisible != null) { if (currentCollabState != m_CollabToolbarState || Collab.IsToolbarVisible() == m_ShowCollabTooltip) { m_CollabToolbarState = currentCollabState; m_ShowCollabTooltip = !Collab.IsToolbarVisible(); Toolbar.RepaintToolbar(); } } } void ReserveRight(float width, ref Rect pos) { pos.x += width; } void ReserveBottom(float height, ref Rect pos) { pos.y += height; } ButtonWithAnimatedIconRotation GetCollabButton() { if (m_CollabButton == null) { const int repaintsPerSecond = 20; const float animSpeed = 500f; const bool mouseDownButton = true; m_CollabButton = new ButtonWithAnimatedIconRotation(() => (float)EditorApplication.timeSinceStartup * animSpeed, Toolbar.RepaintToolbar, repaintsPerSecond, mouseDownButton); } return m_CollabButton; } public void Dispose() { Collab.instance.StateChanged -= OnCollabStateChanged; UnityConnect.instance.StateChanged -= OnUnityConnectStateChanged; UnityConnect.instance.UserStateChanged -= OnUnityConnectUserStateChanged; if (m_CollabButton != null) m_CollabButton.Clear(); } } } // namespace ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarButton.cs.meta ================================================ fileFormatVersion: 2 guid: 882f1a4147a284f028899b9c018e63eb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarWindow.cs ================================================ using UnityEngine; using UnityEditor.Collaboration; using UnityEditor.Web; using UnityEditor.Connect; namespace UnityEditor { [InitializeOnLoad] internal class WebViewStatic : ScriptableSingleton { [SerializeField] WebView m_WebView; static public WebView GetWebView() { return instance.m_WebView; } static public void SetWebView(WebView webView) { instance.m_WebView = webView; } } [InitializeOnLoad] internal class CollabToolbarWindow : WebViewEditorStaticWindow, IHasCustomMenu { internal override WebView webView { get {return WebViewStatic.GetWebView(); } set {WebViewStatic.SetWebView(value); } } private const string kWindowName = "Unity Collab Toolbar"; private static long s_LastClosedTime; private static CollabToolbarWindow s_CollabToolbarWindow; public static bool s_ToolbarIsVisible = false; const int kWindowWidth = 320; const int kWindowHeight = 350; public static void CloseToolbar() { foreach (CollabToolbarWindow window in Resources.FindObjectsOfTypeAll()) window.Close(); } [MenuItem("Window/Asset Management/Collab Toolbar", false /*IsValidateFunction*/, 2, true /* IsInternalMenu */)] public static CollabToolbarWindow ShowToolbarWindow() { //Create a new window if it does not exist if (s_CollabToolbarWindow == null) { s_CollabToolbarWindow = GetWindow(false, kWindowName) as CollabToolbarWindow; } return s_CollabToolbarWindow; } [MenuItem("Window/Asset Management/Collab Toolbar", true /*IsValidateFunction*/)] public static bool ValidateShowToolbarWindow() { return true; } public static bool IsVisible() { return s_ToolbarIsVisible; } public static bool ShowCenteredAtPosition(Rect buttonRect) { buttonRect.x -= kWindowWidth / 2; // We could not use realtimeSinceStartUp since it is set to 0 when entering/exitting playmode, we assume an increasing time when comparing time. long nowMilliSeconds = System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond; bool justClosed = nowMilliSeconds < s_LastClosedTime + 50; if (!justClosed) { // Method may have been triggered programmatically, without a user event to consume. if (Event.current.type != EventType.Layout) { Event.current.Use(); } if (s_CollabToolbarWindow == null) s_CollabToolbarWindow = CreateInstance() as CollabToolbarWindow; var windowSize = new Vector2(kWindowWidth, kWindowHeight); s_CollabToolbarWindow.initialOpenUrl = "file:///" + EditorApplication.userJavascriptPackagesPath + "unityeditor-collab-toolbar/dist/index.html"; s_CollabToolbarWindow.Init(); s_CollabToolbarWindow.ShowAsDropDown(buttonRect, windowSize); s_CollabToolbarWindow.OnFocus(); return true; } return false; } // Receives HTML title public void OnReceiveTitle(string title) { titleContent.text = title; } public new void OnInitScripting() { base.OnInitScripting(); } public override void OnEnable() { minSize = new Vector2(kWindowWidth, kWindowHeight); maxSize = new Vector2(kWindowWidth, kWindowHeight); initialOpenUrl = "file:///" + EditorApplication.userJavascriptPackagesPath + "unityeditor-collab-toolbar/dist/index.html"; base.OnEnable(); s_ToolbarIsVisible = true; } internal new void OnDisable() { s_LastClosedTime = System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond; if (s_CollabToolbarWindow) { s_ToolbarIsVisible = false; NotifyVisibility(s_ToolbarIsVisible); } s_CollabToolbarWindow = null; base.OnDisable(); } public new void OnDestroy() { OnLostFocus(); base.OnDestroy(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarWindow.cs.meta ================================================ fileFormatVersion: 2 guid: 6f516f1ec21a54a59a92bf99db2d9535 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Presenters/CollabHistoryPresenter.cs ================================================ using System.Collections.Generic; using UnityEditor.Connect; using UnityEditor.Web; namespace UnityEditor.Collaboration { internal class CollabHistoryPresenter { public const int ItemsPerPage = 5; ICollabHistoryWindow m_Window; ICollabHistoryItemFactory m_Factory; IRevisionsService m_Service; ConnectInfo m_ConnectState; CollabInfo m_CollabState; bool m_IsCollabError; int m_TotalRevisions; int m_CurrentPage; int m_RequestedPage; bool m_FetchInProgress; BuildAccess m_BuildAccess; string m_ProgressRevision; public bool BuildServiceEnabled {get; set; } public CollabHistoryPresenter(ICollabHistoryWindow window, ICollabHistoryItemFactory factory, IRevisionsService service) { m_Window = window; m_Factory = factory; m_Service = service; m_CurrentPage = 0; m_BuildAccess = new BuildAccess(); m_Service.FetchRevisionsCallback += OnFetchRevisions; } public void OnWindowEnabled() { UnityConnect.instance.StateChanged += OnConnectStateChanged; Collab.instance.StateChanged += OnCollabStateChanged; Collab.instance.RevisionUpdated += OnCollabRevisionUpdated; Collab.instance.JobsCompleted += OnCollabJobsCompleted; Collab.instance.ErrorOccurred += OnCollabError; Collab.instance.ErrorCleared += OnCollabErrorCleared; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; m_ConnectState = UnityConnect.instance.GetConnectInfo(); m_CollabState = Collab.instance.GetCollabInfo(); m_Window.revisionActionsEnabled = !EditorApplication.isPlayingOrWillChangePlaymode; // Setup window callbacks m_Window.OnPageChangeAction = OnUpdatePage; m_Window.OnUpdateAction = OnUpdate; m_Window.OnRestoreAction = OnRestore; m_Window.OnGoBackAction = OnGoBack; m_Window.OnShowBuildAction = ShowBuildForCommit; m_Window.OnShowServicesAction = ShowServicePage; m_Window.itemsPerPage = ItemsPerPage; // Initialize data UpdateBuildServiceStatus(); var state = RecalculateState(); // Only try to load the page if we're ready if (state == HistoryState.Ready) OnUpdatePage(m_CurrentPage); m_Window.UpdateState(state, true); } public void OnWindowDisabled() { UnityConnect.instance.StateChanged -= OnConnectStateChanged; Collab.instance.StateChanged -= OnCollabStateChanged; Collab.instance.RevisionUpdated -= OnCollabRevisionUpdated; Collab.instance.JobsCompleted -= OnCollabJobsCompleted; EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; } private void OnConnectStateChanged(ConnectInfo state) { m_ConnectState = state; m_Window.UpdateState(RecalculateState(), false); } private void OnCollabStateChanged(CollabInfo state) { // Sometimes a collab state change will trigger even though everything is the same if (m_CollabState.Equals(state)) return; if (m_CollabState.tip != state.tip) OnUpdatePage(m_CurrentPage); m_CollabState = state; m_Window.UpdateState(RecalculateState(), false); if (state.inProgress) { m_Window.inProgressRevision = m_ProgressRevision; } else { m_Window.inProgressRevision = null; } } private void OnCollabRevisionUpdated(CollabInfo state) { OnUpdatePage(m_CurrentPage); } private void OnCollabJobsCompleted(CollabInfo state) { m_ProgressRevision = null; } private void OnCollabError() { m_IsCollabError = true; m_Window.UpdateState(RecalculateState(), false); } private void OnCollabErrorCleared() { m_IsCollabError = false; m_FetchInProgress = true; m_Service.GetRevisions(m_CurrentPage * ItemsPerPage, ItemsPerPage); m_Window.UpdateState(RecalculateState(), false); } private void OnPlayModeStateChanged(PlayModeStateChange stateChange) { // If entering play mode, disable if (stateChange == PlayModeStateChange.ExitingEditMode || stateChange == PlayModeStateChange.EnteredPlayMode) { m_Window.revisionActionsEnabled = false; } // If exiting play mode, enable! else if (stateChange == PlayModeStateChange.EnteredEditMode || stateChange == PlayModeStateChange.ExitingPlayMode) { m_Window.revisionActionsEnabled = true; } } private HistoryState RecalculateState() { if (!m_ConnectState.online) return HistoryState.Offline; if (m_ConnectState.maintenance || m_CollabState.maintenance) return HistoryState.Maintenance; if (!m_ConnectState.loggedIn) return HistoryState.LoggedOut; if (!m_CollabState.seat) return HistoryState.NoSeat; if (!Collab.instance.IsCollabEnabledForCurrentProject()) return HistoryState.Disabled; if (!Collab.instance.IsConnected() || !m_CollabState.ready || m_FetchInProgress) return HistoryState.Waiting; if (m_ConnectState.error || m_IsCollabError) return HistoryState.Error; return HistoryState.Ready; } // TODO: Eventually this can be a listener on the build service status public void UpdateBuildServiceStatus() { foreach (var service in UnityConnectServiceCollection.instance.GetAllServiceInfos()) { if (service.name.Equals("Build")) { BuildServiceEnabled = service.enabled; } } } public void ShowBuildForCommit(string revisionID) { m_BuildAccess.ShowBuildForCommit(revisionID); } public void ShowServicePage() { m_BuildAccess.ShowServicePage(); } public void OnUpdatePage(int page) { m_FetchInProgress = true; m_Service.GetRevisions(page * ItemsPerPage, ItemsPerPage); m_Window.UpdateState(RecalculateState(), false); m_RequestedPage = page; } private void OnFetchRevisions(RevisionsResult data) { m_FetchInProgress = false; IEnumerable items = null; if (data != null) { m_CurrentPage = m_RequestedPage; m_TotalRevisions = data.RevisionsInRepo; items = m_Factory.GenerateElements(data.Revisions, m_TotalRevisions, m_CurrentPage * ItemsPerPage, m_Service.tipRevision, m_Window.inProgressRevision, m_Window.revisionActionsEnabled, BuildServiceEnabled, m_Service.currentUser); } // State must be recalculated prior to inserting items m_Window.UpdateState(RecalculateState(), false); m_Window.UpdateRevisions(items, m_Service.tipRevision, m_TotalRevisions, m_CurrentPage); } private void OnRestore(string revisionId, bool updatetorevision) { m_ProgressRevision = revisionId; Collab.instance.ResyncToRevision(revisionId); } private void OnGoBack(string revisionId, bool updatetorevision) { m_ProgressRevision = revisionId; Collab.instance.GoBackToRevision(revisionId, false); } private void OnUpdate(string revisionId, bool updatetorevision) { m_ProgressRevision = revisionId; Collab.instance.Update(revisionId, updatetorevision); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Presenters/CollabHistoryPresenter.cs.meta ================================================ fileFormatVersion: 2 guid: a7c91a123806d41a0873fcdcb629b1c4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Presenters.meta ================================================ fileFormatVersion: 2 guid: d437fe60bb34f45728664a5d930c1635 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/BuildStatusButton.cs ================================================ using System; using UnityEditor; using UnityEditor.Collaboration; using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace UnityEditor.Collaboration { internal class BuildStatusButton : Button { private readonly string iconPrefix = "Icons/Collab.Build"; private readonly string iconSuffix = ".png"; Label labelElement = new Label(); Image iconElement = new Image() {name = "BuildIcon"}; public BuildStatusButton(Action clickEvent) : base(clickEvent) { iconElement.image = EditorGUIUtility.Load(iconPrefix + iconSuffix) as Texture; labelElement.text = "Build Now"; Add(iconElement); Add(labelElement); } public BuildStatusButton(Action clickEvent, BuildState state, int failures) : base(clickEvent) { switch (state) { case BuildState.InProgress: iconElement.image = EditorGUIUtility.Load(iconPrefix + iconSuffix) as Texture; labelElement.text = "In progress"; break; case BuildState.Failed: iconElement.image = EditorGUIUtility.Load(iconPrefix + "Failed" + iconSuffix) as Texture; labelElement.text = failures + ((failures == 1) ? " failure" : " failures"); break; case BuildState.Success: iconElement.image = EditorGUIUtility.Load(iconPrefix + "Succeeded" + iconSuffix) as Texture; labelElement.text = "success"; break; } Add(iconElement); Add(labelElement); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/BuildStatusButton.cs.meta ================================================ fileFormatVersion: 2 guid: 0217a80286f79419daa202f69409f19b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDown.cs ================================================ using UnityEngine; using System.Collections.Generic; using UnityEditor.Connect; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace UnityEditor.Collaboration { internal class CollabHistoryDropDown : VisualElement { private readonly VisualElement m_FilesContainer; private readonly Label m_ToggleLabel; private int m_ChangesTotal; private string m_RevisionId; public CollabHistoryDropDown(ICollection changes, int changesTotal, bool changesTruncated, string revisionId) { m_FilesContainer = new VisualElement(); m_ChangesTotal = changesTotal; m_RevisionId = revisionId; m_ToggleLabel = new Label(ToggleText(false)); m_ToggleLabel.AddManipulator(new Clickable(ToggleDropdown)); Add(m_ToggleLabel); foreach (ChangeData change in changes) { m_FilesContainer.Add(new CollabHistoryDropDownItem(change.path, change.action)); } if (changesTruncated) { m_FilesContainer.Add(new Button(ShowAllClick) { text = "Show all on dashboard" }); } } private void ToggleDropdown() { if (Contains(m_FilesContainer)) { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "CollapseAssets"); Remove(m_FilesContainer); m_ToggleLabel.text = ToggleText(false); } else { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ExpandAssets"); Add(m_FilesContainer); m_ToggleLabel.text = ToggleText(true); } } private string ToggleText(bool open) { var icon = open ? "\u25bc" : "\u25b6"; var change = m_ChangesTotal == 1 ? "Change" : "Changes"; return string.Format("{0} {1} Asset {2}", icon, m_ChangesTotal, change); } private void ShowAllClick() { var host = UnityConnect.instance.GetConfigurationURL(CloudConfigUrl.CloudServicesDashboard); var org = UnityConnect.instance.GetOrganizationId(); var proj = UnityConnect.instance.GetProjectGUID(); var url = string.Format("{0}/collab/orgs/{1}/projects/{2}/commits?commit={3}", host, org, proj, m_RevisionId); CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ShowAllOnDashboard"); Application.OpenURL(url); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDown.cs.meta ================================================ fileFormatVersion: 2 guid: a483595b0257945278dc75c5ff7d82ee MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDownItem.cs ================================================ using System; using System.IO; using System.Linq; using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace UnityEditor.Collaboration { internal class CollabHistoryDropDownItem : VisualElement { public CollabHistoryDropDownItem(string path, string action) { var fileName = Path.GetFileName(path); var isFolder = Path.GetFileNameWithoutExtension(path).Equals(fileName); var fileIcon = GetIconElement(action, fileName, isFolder); var metaContainer = new VisualElement(); var fileNameLabel = new Label { name = "FileName", text = fileName }; var filePathLabel = new Label { name = "FilePath", text = path }; metaContainer.Add(fileNameLabel); metaContainer.Add(filePathLabel); Add(fileIcon); Add(metaContainer); } private Image GetIconElement(string action, string fileName, bool isFolder) { var prefix = isFolder ? "Folder" : "File"; var actionName = action.First().ToString().ToUpper() + action.Substring(1); // Use the same icon for renamed and moved files actionName = actionName.Equals("Renamed") ? "Moved" : actionName; var iconElement = new Image { name = "FileIcon", image = EditorGUIUtility.LoadIcon("Icons/Collab." + prefix + actionName + ".png") }; return iconElement; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDownItem.cs.meta ================================================ fileFormatVersion: 2 guid: d912d4873af534bd4a9d44bf1b52f14e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItem.cs ================================================ using System; using System.Linq; using System.Security.Cryptography; using UnityEditor.Connect; using UnityEditor.Web; using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; using UnityEngine.Experimental.UIElements.StyleEnums; #endif namespace UnityEditor.Collaboration { internal class CollabHistoryItem : VisualElement { public static RevisionAction s_OnRestore; public static RevisionAction s_OnGoBack; public static RevisionAction s_OnUpdate; public static ShowBuildAction s_OnShowBuild; public static Action s_OnShowServices; private readonly string m_RevisionId; private readonly string m_FullDescription; private readonly DateTime m_TimeStamp; private readonly Button m_Button; private readonly HistoryProgressSpinner m_ProgressSpinner; private VisualElement m_ActionsTray; private VisualElement m_Details; private Label m_Description; private Label m_TimeAgo; private readonly Button m_ExpandCollapseButton; private bool m_Expanded; private const int kMaxDescriptionChars = 500; public bool RevisionActionsEnabled { set { m_Button.SetEnabled(value); } } public DateTime timeStamp { get { return m_TimeStamp; } } public CollabHistoryItem(RevisionData data) { m_RevisionId = data.id; m_TimeStamp = data.timeStamp; name = "HistoryItem"; m_ActionsTray = new VisualElement {name = "HistoryItemActionsTray"}; m_ProgressSpinner = new HistoryProgressSpinner(); m_Details = new VisualElement {name = "HistoryDetail"}; var author = new Label(data.authorName) {name = "Author"}; m_TimeAgo = new Label(TimeAgo.GetString(m_TimeStamp)); m_FullDescription = data.comment; var shouldTruncate = ShouldTruncateDescription(m_FullDescription); if (shouldTruncate) { m_Description = new Label(GetTruncatedDescription(m_FullDescription)); } else { m_Description = new Label(m_FullDescription); } m_Description.name = "RevisionDescription"; var dropdown = new CollabHistoryDropDown(data.changes, data.changesTotal, data.changesTruncated, data.id); if (data.current) { m_Button = new Button(Restore) {name = "ActionButton", text = "Restore"}; } else if (data.obtained) { m_Button = new Button(GoBackTo) {name = "ActionButton", text = "Go back to..."}; } else { m_Button = new Button(UpdateTo) {name = "ActionButton", text = "Update"}; } m_Button.SetEnabled(data.enabled); m_ProgressSpinner.ProgressEnabled = data.inProgress; m_ActionsTray.Add(m_ProgressSpinner); m_ActionsTray.Add(m_Button); m_Details.Add(author); m_Details.Add(m_TimeAgo); m_Details.Add(m_Description); if (shouldTruncate) { m_ExpandCollapseButton = new Button(ToggleDescription) { name = "ToggleDescription", text = "Show More" }; m_Details.Add(m_ExpandCollapseButton); } if (data.buildState != BuildState.None) { BuildStatusButton buildButton; if (data.buildState == BuildState.Configure) buildButton = new BuildStatusButton(ShowServicePage); else buildButton = new BuildStatusButton(ShowBuildForCommit, data.buildState, data.buildFailures); m_Details.Add(buildButton); } m_Details.Add(m_ActionsTray); m_Details.Add(dropdown); Add(m_Details); this.schedule.Execute(UpdateTimeAgo).Every(1000 * 20); } public static void SetUpCallbacks(RevisionAction Restore, RevisionAction GoBack, RevisionAction Update) { s_OnRestore = Restore; s_OnGoBack = GoBack; s_OnUpdate = Update; } public void SetInProgressStatus(string revisionIdInProgress) { if (String.IsNullOrEmpty(revisionIdInProgress)) { m_Button.SetEnabled(true); m_ProgressSpinner.ProgressEnabled = false; } else { m_Button.SetEnabled(false); if (m_RevisionId.Equals(revisionIdInProgress)) { m_ProgressSpinner.ProgressEnabled = true; } } } void ShowBuildForCommit() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ShowBuild"); if (s_OnShowBuild != null) { s_OnShowBuild(m_RevisionId); } } void ShowServicePage() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ShowServices"); if (s_OnShowServices != null) { s_OnShowServices(); } } void Restore() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "Restore"); if (s_OnRestore != null) { s_OnRestore(m_RevisionId, false); } } void GoBackTo() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "GoBackTo"); if (s_OnGoBack != null) { s_OnGoBack(m_RevisionId, false); } } void UpdateTo() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "Update"); if (s_OnUpdate != null) { s_OnUpdate(m_RevisionId, true); } } void UpdateTimeAgo() { m_TimeAgo.text = TimeAgo.GetString(m_TimeStamp); } bool ShouldTruncateDescription(string description) { return description.Contains(Environment.NewLine) || description.Length > kMaxDescriptionChars; } string GetTruncatedDescription(string description) { string result = description.Contains(Environment.NewLine) ? description.Substring(0, description.IndexOf(Environment.NewLine)) : description; if (result.Length > kMaxDescriptionChars) { result = result.Substring(0, kMaxDescriptionChars) + "..."; } return result; } void ToggleDescription() { if (m_Expanded) { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "CollapseDescription"); m_Expanded = false; m_ExpandCollapseButton.text = "Show More"; m_Description.text = GetTruncatedDescription(m_FullDescription); } else { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ExpandDescription"); m_Expanded = true; m_ExpandCollapseButton.text = "Show Less"; m_Description.text = m_FullDescription; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItem.cs.meta ================================================ fileFormatVersion: 2 guid: c4c1445ee948a4124bfa9fb818a17e36 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItemFactory.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEditor.Collaboration; using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; using UnityEngine.Experimental.UIElements.StyleEnums; #endif namespace UnityEditor.Collaboration { internal class CollabHistoryItemFactory : ICollabHistoryItemFactory { const int k_MaxChangesPerRevision = 10; public IEnumerable GenerateElements(IEnumerable revisions, int totalRevisions, int startIndex, string tipRev, string inProgressRevision, bool revisionActionsEnabled, bool buildServiceEnabled, string currentUser) { int index = startIndex; foreach (var rev in revisions) { index++; var current = rev.revisionID == tipRev; // Calculate build status BuildState buildState = BuildState.None; int buildFailures = 0; if (rev.buildStatuses != null && rev.buildStatuses.Length > 0) { bool inProgress = false; foreach (CloudBuildStatus buildStatus in rev.buildStatuses) { if (buildStatus.complete) { if (!buildStatus.success) { buildFailures++; } } else { inProgress = true; break; } } if (inProgress) { buildState = BuildState.InProgress; } else if (buildFailures > 0) { buildState = BuildState.Failed; } else { buildState = BuildState.Success; } } else if (current && !buildServiceEnabled) { buildState = BuildState.Configure; } // Calculate the number of changes performed on files and folders (not meta files) var paths = new Dictionary(); foreach (ChangeAction change in rev.entries) { if (change.path.EndsWith(".meta")) { var path = change.path.Substring(0, change.path.Length - 5); // Actions taken on meta files are secondary to any actions taken on the main file if (!paths.ContainsKey(path)) paths[path] = new ChangeData() {path = path, action = change.action}; } else { paths[change.path] = new ChangeData() {path = change.path, action = change.action}; } } var displayName = (rev.author != currentUser) ? rev.authorName : "You"; var item = new RevisionData { id = rev.revisionID, index = totalRevisions - index + 1, timeStamp = TimeStampToDateTime(rev.timeStamp), authorName = displayName, comment = rev.comment, obtained = rev.isObtained, current = current, inProgress = (rev.revisionID == inProgressRevision), enabled = revisionActionsEnabled, buildState = buildState, buildFailures = buildFailures, changes = paths.Values.Take(k_MaxChangesPerRevision).ToList(), changesTotal = paths.Values.Count, changesTruncated = paths.Values.Count > k_MaxChangesPerRevision, }; yield return item; } } private static DateTime TimeStampToDateTime(double timeStamp) { DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); dateTime = dateTime.AddSeconds(timeStamp).ToLocalTime(); return dateTime; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItemFactory.cs.meta ================================================ fileFormatVersion: 2 guid: fc46f91ea1e8e4ca2ab693fef9156dbe MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryRevisionLine.cs ================================================ using System; using UnityEditor; using UnityEditor.Collaboration; using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace UnityEditor.Collaboration { internal class CollabHistoryRevisionLine : VisualElement { public CollabHistoryRevisionLine(int number) { AddNumber(number); AddLine("topLine"); AddLine("bottomLine"); AddIndicator(); } public CollabHistoryRevisionLine(DateTime date, bool isFullDateObtained) { AddLine(isFullDateObtained ? "obtainedDateLine" : "absentDateLine"); AddHeader(GetFormattedHeader(date)); AddToClassList("revisionLineHeader"); } private void AddHeader(string content) { Add(new Label { text = content }); } private void AddIndicator() { Add(new VisualElement { name = "RevisionIndicator" }); } private void AddLine(string className = null) { var line = new VisualElement { name = "RevisionLine" }; if (!String.IsNullOrEmpty(className)) { line.AddToClassList(className); } Add(line); } private void AddNumber(int number) { Add(new Label { text = number.ToString(), name = "RevisionIndex" }); } private string GetFormattedHeader(DateTime date) { string result = "Commits on " + date.ToString("MMM d"); switch (date.Day) { case 1: case 21: case 31: result += "st"; break; case 2: case 22: result += "nd"; break; case 3: case 23: result += "rd"; break; default: result += "th"; break; } return result; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryRevisionLine.cs.meta ================================================ fileFormatVersion: 2 guid: 3c737f7a9d78541d1ab25f28f045dd32 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/HistoryProgressSpinner.cs ================================================ using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace UnityEditor.Collaboration { internal class HistoryProgressSpinner : Image { private readonly Texture2D[] m_StatusWheelTextures; private bool m_ProgressEnabled; private IVisualElementScheduledItem m_Animation; public bool ProgressEnabled { set { if (m_ProgressEnabled == value) return; m_ProgressEnabled = value; visible = value; if (value) { if (m_Animation == null) { m_Animation = this.schedule.Execute(AnimateProgress).Every(33); } else { m_Animation.Resume(); } } else { if (m_Animation != null) { m_Animation.Pause(); } } } } public HistoryProgressSpinner() { m_StatusWheelTextures = new Texture2D[12]; for (int i = 0; i < 12; i++) { m_StatusWheelTextures[i] = EditorGUIUtility.LoadIcon("WaitSpin" + i.ToString("00")); } image = m_StatusWheelTextures[0]; style.width = m_StatusWheelTextures[0].width; style.height = m_StatusWheelTextures[0].height; visible = false; } private void AnimateProgress(TimerState obj) { int frame = (int)Mathf.Repeat(Time.realtimeSinceStartup * 10, 11.99f); image = m_StatusWheelTextures[frame]; MarkDirtyRepaint(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/HistoryProgressSpinner.cs.meta ================================================ fileFormatVersion: 2 guid: cf6aca931950a4a6a886e214e9e649c4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/ICollabHistoryItemFactory.cs ================================================ using System; using System.Collections.Generic; using UnityEditor.Collaboration; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace UnityEditor.Collaboration { internal interface ICollabHistoryItemFactory { IEnumerable GenerateElements(IEnumerable revsRevisions, int mTotalRevisions, int startIndex, string tipRev, string inProgressRevision, bool revisionActionsEnabled, bool buildServiceEnabled, string currentUser); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/ICollabHistoryItemFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 821f5482c5a3f4389885f4432433f56f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/PagedListView.cs ================================================ using System; using System.Collections.Generic; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; using UnityEngine.Experimental.UIElements.StyleEnums; #endif namespace UnityEditor.Collaboration { internal interface IPagerData { int curPage { get; } int totalPages { get; } PageChangeAction OnPageChanged { get; } } internal class PagerElement : VisualElement { IPagerData m_Data; readonly Label m_PageText; readonly Button m_DownButton; readonly Button m_UpButton; public PagerElement(IPagerData dataSource) { m_Data = dataSource; this.style.flexDirection = FlexDirection.Row; this.style.alignSelf = Align.Center; Add(m_DownButton = new Button(OnPageDownClicked) {text = "\u25c5 Newer"}); m_DownButton.AddToClassList("PagerDown"); m_PageText = new Label(); m_PageText.AddToClassList("PagerLabel"); Add(m_PageText); Add(m_UpButton = new Button(OnPageUpClicked) {text = "Older \u25bb"}); m_UpButton.AddToClassList("PagerUp"); UpdateControls(); } void OnPageDownClicked() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "NewerPage"); m_Data.OnPageChanged(m_Data.curPage - 1); } void OnPageUpClicked() { CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "OlderPage"); m_Data.OnPageChanged(m_Data.curPage + 1); } public void Refresh() { UpdateControls(); } void UpdateControls() { var curPage = m_Data.curPage; var totalPages = m_Data.totalPages; m_PageText.text = (curPage + 1) + " / " + totalPages; m_DownButton.SetEnabled(curPage > 0); m_UpButton.SetEnabled(curPage < totalPages - 1); } } internal enum PagerLocation { Top, Bottom, } internal class PagedListView : VisualElement, IPagerData { public const int DefaultItemsPerPage = 10; readonly VisualElement m_ItemContainer; readonly PagerElement m_PagerTop, m_PagerBottom; int m_PageSize = DefaultItemsPerPage; IEnumerable m_Items; int m_TotalItems; int m_CurPage; public int pageSize { set { m_PageSize = value; } } public IEnumerable items { set { m_Items = value; LayoutItems(); } } public int totalItems { set { if (m_TotalItems == value) return; m_TotalItems = value; UpdatePager(); } } public PageChangeAction OnPageChanged { get; set; } public PagedListView() { m_PagerTop = new PagerElement(this); m_ItemContainer = new VisualElement() { name = "PagerItems", }; Add(m_ItemContainer); m_Items = new List(); m_PagerBottom = new PagerElement(this); } void LayoutItems() { m_ItemContainer.Clear(); foreach (var item in m_Items) { m_ItemContainer.Add(item); } } void UpdatePager() { if (m_PagerTop.parent != this && totalPages > 1 && curPage > 0) Insert(0, m_PagerTop); if (m_PagerTop.parent == this && (totalPages <= 1 || curPage == 0)) Remove(m_PagerTop); if (m_PagerBottom.parent != this && totalPages > 1) Add(m_PagerBottom); if (m_PagerBottom.parent == this && totalPages <= 1) Remove(m_PagerBottom); m_PagerTop.Refresh(); m_PagerBottom.Refresh(); } int pageCount { get { var pages = m_TotalItems / m_PageSize; if (m_TotalItems % m_PageSize > 0) pages++; return pages; } } public int curPage { get { return m_CurPage; } set { m_CurPage = value; UpdatePager(); } } public int totalPages { get { var extraPage = 0; if (m_TotalItems % m_PageSize > 0) extraPage = 1; return m_TotalItems / m_PageSize + extraPage; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/PagedListView.cs.meta ================================================ fileFormatVersion: 2 guid: 50de529b6a28f4a7093045e08810a5df MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/StatusView.cs ================================================ using System; using UnityEditor; using UnityEngine; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; using UnityEngine.Experimental.UIElements.StyleEnums; #endif namespace UnityEditor.Collaboration { internal class StatusView : VisualElement { Image m_Image; Label m_Message; Button m_Button; Action m_Callback; public Texture icon { get { return m_Image.image; } set { m_Image.image = value; m_Image.visible = value != null; // Until "display: hidden" is added, this is the only way to hide an element m_Image.style.height = value != null ? 150 : 0; } } public string message { get { return m_Message.text; } set { m_Message.text = value; m_Message.visible = value != null; } } public string buttonText { get { return m_Button.text; } set { m_Button.text = value; UpdateButton(); } } public Action callback { get { return m_Callback; } set { m_Callback = value; UpdateButton(); } } public StatusView() { name = "StatusView"; this.StretchToParentSize(); m_Image = new Image() { name = "StatusIcon", visible = false, style = { height = 0f }}; m_Message = new Label() { name = "StatusMessage", visible = false}; m_Button = new Button(InternalCallaback) { name = "StatusButton", visible = false}; Add(m_Image); Add(m_Message); Add(m_Button); } private void UpdateButton() { m_Button.visible = m_Button.text != null && m_Callback != null; } private void InternalCallaback() { m_Callback(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/StatusView.cs.meta ================================================ fileFormatVersion: 2 guid: 08e9894bdf0834710b22d3c0aa245ac0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views.meta ================================================ fileFormatVersion: 2 guid: fd0a39b4d296d4d509b4f1dbd08d0630 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab.meta ================================================ fileFormatVersion: 2 guid: c18cb9388313e4287ad5895ee735c47d folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryCommon.uss ================================================ .unity-button { min-height:0; -unity-text-align:middle-center; margin-left:4px; margin-top:3px; margin-right:4px; margin-bottom:3px; border-left-width:6px; border-top-width:4px; border-right-width:6px; border-bottom-width:4px; padding-left:6px; padding-top:2px; padding-right:6px; padding-bottom:3px; } .unity-label { overflow: hidden; margin-left:4px; margin-top:2px; margin-right:4px; margin-bottom:2px; padding-left:2px; padding-top:1px; min-height: 0; } #HistoryContainer { flex: 1 0 0; } #HistoryItem { flex: 1 0 0; flex-direction: row; } #HistoryDetail { margin-top: 10px; margin-left: 10px; margin-bottom: 10px; margin-right: 10px; padding-top: 4px; flex: 1 0 0; } #Author { -unity-font-style: bold; font-size: 12px; } #HistoryDetail > Button { align-self: flex-end; } CollabHistoryRevisionLine { width: 40px; } #RevisionLine { flex: 1 0 0; margin-left: 35px; width: 1.5px; } #RevisionLine.topLine { height: 20px; flex: 0 0 auto; } #RevisionLine.absentDateLine { background-color: #797676; } .absentRevision #RevisionLine { background-color: #797676; } .currentRevision #RevisionLine.topLine { background-color: #797676; } #RevisionIndex { position: absolute; min-width: 23px; -unity-text-align: middle-right; top: 15.8px; font-size: 9px; } #RevisionIndicator { position: absolute; background-color: #000; border-radius: 3px; width: 8px; height: 8px; border-bottom-width: 2px; border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; top: 20px; left: 32px; } .revisionLineHeader { width: 200px; height: 20px; } .revisionLineHeader > .unity-label { position: absolute; margin-left: 47px; margin-top: 3px; } #PagerItems { flex-direction: column; } PagerElement > .unity-label { margin-top: 8px; } .absentRevision #RevisionIndicator { border-color: #797676; } .absentRevision #RevisionIndex { color: #797676; } .currentRevision #HistoryDetail { border-top-width: 2px; } #HistoryItem #RevisionDescription { white-space: normal; } #HistoryItem #ToggleDescription { align-self: flex-start; padding-top: 0; padding-left: 0; padding-right: 0; padding-bottom: 2px; } #HistoryItem #ActionButton { position: absolute; right: 0; } #HistoryItem #BuildIcon { width: 16px; height: 13px; } #HistoryItemActionsTray { flex: 1 0 0; flex-direction: row; align-items: center; height: 38px; margin-left: 10px; margin-right: 10px; } CollabHistoryDropDown { border-top-width: 1px; } CollabHistoryDropDown > .unity-label { padding-top: 10px; padding-bottom: 10px; } CollabHistoryDropDownItem { flex-direction: row; border-top-width: 1px; overflow: hidden; } #FileIcon { align-self: center; width: 26px; height: 26px; } #FileName { -unity-font-style: bold; padding-bottom: 0; margin-bottom: 0; } #FileIcon { padding-top: 0; margin-top: 0; } #ErrorBar { height: 24px; background-color: #ff0000; color: #000; font-size: 12px; } #ErrorBar > #CloseButton { position: absolute; right: 0; top: 0; width: 24px; height: 24px; color: #000; font-size: 18px; -unity-font-style: bold; } #StatusView { flex-direction: column; justify-content: center; align-self: center; align-items: center; flex: 1 0 0; } #StatusView > #StatusIcon { width: 115px; height: 150px; } #StatusView > #StatusMessage { font-size: 22px; width: 230px; white-space: normal; -unity-text-align: middle-center; } #StatusView > #StatusButton { font-size: 12px; margin-top: 20px; background-image: none; width: 108px; height: 29px; } BuildStatusButton.unity-button { flex-direction: row; align-self: flex-end; align-items: center; margin-right: 10px; padding-left:0; padding-top:0; padding-right:0; padding-bottom:0; } BuildStatusButton.unity-button .unity-label { padding-left: 2px; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryCommon.uss.meta ================================================ fileFormatVersion: 2 guid: 3a2d94c8977984b67984caeff9fa666e ScriptedImporter: fileIDToRecycleName: 11400000: stylesheet externalObjects: {} userData: assetBundleName: assetBundleVariant: script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryDark.uss ================================================ #HistoryContainer { background-color: #292929; } .obtainedRevision #HistoryDetail { background-color: #333; } .absentRevision #HistoryDetail { background-color: #595959; } #StatusView { background-color: #292929; } #StatusView > #StatusMessage { color: #959995; } BuildStatusButton.unity-button { color: #B4B4B4; background-image: resource("Builtin Skins/DarkSkin/Images/btn.png"); } BuildStatusButton.unity-button:hover { color: #FFF; } BuildStatusButton.unity-button:hover:active { background-image: resource("Builtin Skins/DarkSkin/Images/btn act.png"); } BuildStatusButton.unity-button:checked { color: #F0F0F0; background-image: resource("Builtin Skins/DarkSkin/Images/btn on.png"); } BuildStatusButton.unity-button:hover:checked { color: #FFF; } BuildStatusButton.unity-button:hover:active:checked { background-image: resource("Builtin Skins/DarkSkin/Images/btn onact.png"); } BuildStatusButton.unity-button:focus:checked { background-image: resource("Builtin Skins/DarkSkin/Images/btn on focus.png"); } CollabHistoryDropDown { border-color: #292929; } CollabHistoryDropDownItem { border-color: #292929; } #RevisionLine.obtainedDateLine { background-color: #0cb4cc; } .obtainedRevision #RevisionLine { background-color: #0cb4cc; } #RevisionIndex { color: #0cb4cc; } #RevisionIndicator { border-color: #0cb4cc; } .currentRevision #RevisionIndicator { background-color: #0cb4cc; } .currentRevision #HistoryDetail { border-color: #0cb4cc; } #StatusView > #StatusButton { background-color: #0cb4cc; border-color: #0cb4cc; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryDark.uss.meta ================================================ fileFormatVersion: 2 guid: 70d4d75a2877243758b0750cbc75b6eb ScriptedImporter: fileIDToRecycleName: 11400000: stylesheet externalObjects: {} userData: assetBundleName: assetBundleVariant: script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryLight.uss ================================================ #HistoryContainer { background-color: #a2a2a2; } .obtainedRevision #HistoryDetail { background-color: #c2c2c2; } .absentRevision #HistoryDetail { background-color: #dedede; } #StatusView { background-color: #a2a2a3; } #StatusView > #StatusMessage { color: #000; } BuildStatusButton.unity-button { color: #111; background-image: resource("Builtin Skins/LightSkin/Images/btn.png"); } BuildStatusButton.unity-button:hover { color: #000; } BuildStatusButton.unity-button:hover:active { background-image: resource("Builtin Skins/LightSkin/Images/btn act.png"); } BuildStatusButton.unity-button:checked { color: #F0F0F0; background-image: resource("Builtin Skins/LightSkin/Images/btn on.png"); } BuildStatusButton.unity-button:hover:checked { color: #000; } BuildStatusButton.unity-button:hover:active:checked { background-image: resource("Builtin Skins/LightSkin/Images/btn onact.png"); } BuildStatusButton.unity-button:focus:checked { background-image: resource("Builtin Skins/LightSkin/Images/btn on focus.png"); } CollabHistoryDropDown { border-color: #a2a2a2; } CollabHistoryDropDownItem { border-color: #a2a2a2; } #RevisionLine.obtainedDateLine { background-color: #018d98; } .obtainedRevision #RevisionLine { background-color: #018d98; } #RevisionIndex { color: #018d98; } #RevisionIndicator { border-color: #018d98; } .currentRevision #RevisionIndicator { background-color: #018d98; } .currentRevision #HistoryDetail { border-color: #018d98; } #StatusView > #StatusButton { background-color: #018d98; border-color: #018d98; } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryLight.uss.meta ================================================ fileFormatVersion: 2 guid: b52bde26a83564960bcb90217f72b910 ScriptedImporter: fileIDToRecycleName: 11400000: stylesheet externalObjects: {} userData: assetBundleName: assetBundleVariant: script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles.meta ================================================ fileFormatVersion: 2 guid: 6b1ae1e78552c459d9ce27048ff51c7f folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources.meta ================================================ fileFormatVersion: 2 guid: a6ab6fd2b91214e8a9c8ec2224a528de folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Unity.CollabProxy.Editor.asmdef ================================================ { "name": "Unity.CollabProxy.Editor", "includePlatforms": [ "Editor" ], "excludePlatforms": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Unity.CollabProxy.Editor.asmdef.meta ================================================ fileFormatVersion: 2 guid: 645165c8169474bfbbeb8fb0bcfd26f5 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor.meta ================================================ fileFormatVersion: 2 guid: d31e5d760880a4e52a3a75322481d0d2 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/LICENSE.md ================================================ **Unity Companion Package License v1.0 ("_License_")** Copyright © 2017 Unity Technologies ApS ("**_Unity_**") Unity hereby grants to you a worldwide, non-exclusive, no-charge, and royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute the software that is made available with this License ("**_Software_**"), subject to the following terms and conditions: 1. *Unity Companion Use Only*. Exercise of the license granted herein is limited to exercise for the creation, use, and/or distribution of applications, software, or other content pursuant to a valid Unity development engine software license ("**_Engine License_**"). That means while use of the Software is not limited to use in the software licensed under the Engine License, the Software may not be used for any purpose other than the creation, use, and/or distribution of Engine License-dependent applications, software, or other content. No other exercise of the license granted herein is permitted. 1. *No Modification of Engine License*. Neither this License nor any exercise of the license granted herein modifies the Engine License in any way. 1. *Ownership & Grant Back to You*. 3.1. You own your content. In this License, "derivative works" means derivatives of the Software itself--works derived only from the Software by you under this License (for example, modifying the code of the Software itself to improve its efficacy); “derivative works” of the Software do not include, for example, games, apps, or content that you create using the Software. You keep all right, title, and interest to your own content. 3.2. Unity owns its content. While you keep all right, title, and interest to your own content per the above, as between Unity and you, Unity will own all right, title, and interest to all intellectual property rights (including patent, trademark, and copyright) in the Software and derivative works of the Software, and you hereby assign and agree to assign all such rights in those derivative works to Unity. 3.3. You have a license to those derivative works. Subject to this License, Unity grants to you the same worldwide, non-exclusive, no-charge, and royalty-free copyright license to derivative works of the Software you create as is granted to you for the Software under this License. 1. *Trademarks*. You are not granted any right or license under this License to use any trademarks, service marks, trade names, products names, or branding of Unity or its affiliates ("**_Trademarks_**"). Descriptive uses of Trademarks are permitted; see, for example, Unity’s Branding Usage Guidelines at [https://unity3d.com/public-relations/brand](https://unity3d.com/public-relations/brand). 1. *Notices & Third-Party Rights*. This License, including the copyright notice above, must be provided in all substantial portions of the Software and derivative works thereof (or, if that is impracticable, in any other location where such notices are customarily placed). Further, if the Software is accompanied by a Unity "third-party notices" or similar file, you acknowledge and agree that software identified in that file is governed by those separate license terms. 1. *DISCLAIMER, LIMITATION OF LIABILITY*. THE SOFTWARE AND ANY DERIVATIVE WORKS THEREOF IS PROVIDED ON AN "AS IS" BASIS, AND IS PROVIDED WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR NONINFRINGEMENT. IN NO EVENT SHALL ANY COPYRIGHT HOLDER OR AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES (WHETHER DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL, INCLUDING PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, AND BUSINESS INTERRUPTION), OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR OUT OF, OR IN CONNECTION WITH, THE SOFTWARE OR ANY DERIVATIVE WORKS THEREOF OR THE USE OF OR OTHER DEALINGS IN SAME, EVEN WHERE ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1. *USE IS ACCEPTANCE and License Versions*. Your receipt and use of the Software constitutes your acceptance of this License and its terms and conditions. Software released by Unity under this License may be modified or updated and the License with it; upon any such modification or update, you will comply with the terms of the updated License for any use of any of the Software under the updated License. 1. *Use in Compliance with Law and Termination*. Your exercise of the license granted herein will at all times be in compliance with applicable law and will not infringe any proprietary rights (including intellectual property rights); this License will terminate immediately on any breach by you of this License. 1. *Severability*. If any provision of this License is held to be unenforceable or invalid, that provision will be enforced to the maximum extent possible and the other provisions will remain in full force and effect. 1. *Governing Law and Venue*. This License is governed by and construed in accordance with the laws of Denmark, except for its conflict of laws rules; the United Nations Convention on Contracts for the International Sale of Goods will not apply. If you reside (or your principal place of business is) within the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the state and federal courts located in San Francisco County, California concerning any dispute arising out of this License ("**_Dispute_**"). If you reside (or your principal place of business is) outside the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the courts located in Copenhagen, Denmark concerning any Dispute. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/LICENSE.md.meta ================================================ fileFormatVersion: 2 guid: c754112a02f354a6696fa4f2b99e95a5 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/README.md ================================================ # Collab Proxy UPM Package This is the packaged version of Collab, currently limited to containing the History and Toolbar windows, along with supporting classes. ## Development Check this repository out in your {$PROJECT}/Packages/ folder, under the name com.unity.collab-proxy. The classes will be built by Unity. ## Testing In order to run the tests, you will need to add this project to the testables key in your manifest.json - once you have done this, the tests will be picked up by the Unity Test Runner window. ## Building You may build this project using msbuild. The commands to do so can be seen under .gitlab-ci.yml. ## Deploying Gitlab will automatically build your project when you deploy. You can download the resulting artifact, which will be a dll, and place it in your Editor/bin/ folder. Open the package in Unity to generate the meta files, and then you will be able to publish. We're currently looking into a way to avoid this manual process. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/README.md.meta ================================================ fileFormatVersion: 2 guid: ac281230df7b14becb40b3c479f1b429 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests/Editor/HistoryTests.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEditor.Collaboration; using UnityEngine.TestTools; using NUnit.Framework; namespace UnityEditor.Collaboration.Tests { [TestFixture] internal class HistoryTests { private TestHistoryWindow _window; private TestRevisionsService _service; private CollabHistoryPresenter _presenter; [SetUp] public void SetUp() { _window = new TestHistoryWindow(); _service = new TestRevisionsService(); _presenter = new CollabHistoryPresenter(_window, new CollabHistoryItemFactory(), _service); } [TearDown] public void TearDown() { } [Test] public void CollabHistoryPresenter_OnUpdatePage__PropagatesRevisionResult() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(authorName: "authorName", comment: "comment", revisionID: "revisionID"), } }; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual("revisionID", item.id); Assert.AreEqual("authorName", item.authorName); Assert.AreEqual("comment", item.comment); } [Test] public void CollabHistoryPresenter_OnUpdatePage__RevisionNumberingIsInOrder() { _service.result = new RevisionsResult() { RevisionsInRepo = 4, Revisions = new List() { new Revision(revisionID: "0"), new Revision(revisionID: "1"), new Revision(revisionID: "2"), new Revision(revisionID: "3"), } }; _presenter.OnUpdatePage(0); var items = _window.items.ToArray(); Assert.AreEqual(4, items[0].index); Assert.AreEqual(3, items[1].index); Assert.AreEqual(2, items[2].index); Assert.AreEqual(1, items[3].index); } [Test] public void CollabHistoryPresenter_OnUpdatePage__RevisionNumberingChangesForMorePages() { _service.result = new RevisionsResult() { RevisionsInRepo = 12, Revisions = new List() { new Revision(revisionID: "0"), new Revision(revisionID: "1"), new Revision(revisionID: "2"), new Revision(revisionID: "3"), new Revision(revisionID: "4"), } }; _presenter.OnUpdatePage(1); var items = _window.items.ToArray(); Assert.AreEqual(12, items[0].index); Assert.AreEqual(11, items[1].index); Assert.AreEqual(10, items[2].index); Assert.AreEqual(9, items[3].index); Assert.AreEqual(8, items[4].index); } [Test] public void CollabHistoryPresenter_OnUpdatePage__ObtainedIsCalculated() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(isObtained: false), new Revision(isObtained: true), } }; _presenter.OnUpdatePage(0); var items = _window.items.ToArray(); Assert.IsFalse(items[0].obtained); Assert.IsTrue(items[1].obtained); } [Test] public void CollabHistoryPresenter_OnUpdatePage__CurrentIsCalculated() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "1"), new Revision(revisionID: "2"), new Revision(revisionID: "3"), } }; _service.tipRevision = "2"; _presenter.OnUpdatePage(0); var items = _window.items.ToArray(); Assert.AreEqual(false, items[0].current); Assert.AreEqual(true, items[1].current); Assert.AreEqual(false, items[2].current); } [Test] public void CollabHistoryPresenter_OnUpdatePage__InProgressIsCalculated() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "1"), new Revision(revisionID: "2"), new Revision(revisionID: "3"), } }; _window.inProgressRevision = "2"; _presenter.OnUpdatePage(0); var items = _window.items.ToArray(); Assert.IsFalse(items[0].inProgress); Assert.IsTrue(items[1].inProgress); Assert.IsFalse(items[2].inProgress); } [Test] public void CollabHistoryPresenter_OnUpdatePage__EnabledIsCalculated() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0"), } }; _window.revisionActionsEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(true, item.enabled); } [Test] public void CollabHistoryPresenter_OnUpdatePage__DisabledIsCalculated() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0"), } }; _window.revisionActionsEnabled = false; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(false, item.enabled); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasNoneWhenNotTip() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "1"), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = false; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.None, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateTipHasNoneWhenEnabled() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0"), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.None, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasConfigureWhenTip() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0"), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = false; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.Configure, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasConfigureWhenZeroBuildStatus() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0"), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = false; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.Configure, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasNoneWhenZeroBuildStatuses() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0"), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.None, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasSuccessWhenCompleteAndSucceeded() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision ( revisionID: "0", buildStatuses: new CloudBuildStatus[1] { new CloudBuildStatus(complete: true, success: true), } ), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.Success, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasInProgress() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision ( revisionID: "0", buildStatuses: new CloudBuildStatus[1] { new CloudBuildStatus(complete: false), } ), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.InProgress, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasFailure() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision ( revisionID: "0", buildStatuses: new CloudBuildStatus[1] { new CloudBuildStatus(complete: true, success: false), } ), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.Failed, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasFailureWhenAnyBuildsFail() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision ( revisionID: "0", buildStatuses: new CloudBuildStatus[3] { new CloudBuildStatus(complete: true, success: false), new CloudBuildStatus(complete: true, success: false), new CloudBuildStatus(complete: true, success: true), } ), } }; _service.tipRevision = "0"; _presenter.BuildServiceEnabled = true; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(BuildState.Failed, item.buildState); } [Test] public void CollabHistoryPresenter_OnUpdatePage__ChangesPropagateThrough() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0", entries: GenerateChangeActions(3)), } }; _presenter.OnUpdatePage(0); var item = _window.items.First(); var changes = item.changes.ToList(); Assert.AreEqual("Path0", changes[0].path); Assert.AreEqual("Path1", changes[1].path); Assert.AreEqual("Path2", changes[2].path); } [Test] public void CollabHistoryPresenter_OnUpdatePage__ChangesTotalIsCalculated() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0", entries: GenerateChangeActions(3)), } }; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(3, item.changes.Count); } [Test] public void CollabHistoryPresenter_OnUpdatePage__ChangesTruncatedIsCalculated() { for (var i = 0; i < 20; i++) { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(revisionID: "0", entries: GenerateChangeActions(i)), } }; _presenter.OnUpdatePage(0); var item = _window.items.First(); Assert.AreEqual(i > 10, item.changesTruncated); } } [Test] public void CollabHistoryPresenter_OnUpdatePage__OnlyKeeps10ChangeActions() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision(authorName: "Test", author: "test", entries: GenerateChangeActions(12)), } }; _presenter.OnUpdatePage(1); var item = _window.items.First(); Assert.AreEqual(10, item.changes.Count); Assert.AreEqual(12, item.changesTotal); Assert.AreEqual(true, item.changesTruncated); } [Test] public void CollabHistoryPresenter_OnUpdatePage__DeduplicatesMetaFiles() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision ( authorName: "Test", author: "test", revisionID: "", entries: new ChangeAction[2] { new ChangeAction(path: "Path1", action: "Action1"), new ChangeAction(path: "Path1.meta", action: "Action1"), } ), } }; _presenter.OnUpdatePage(1); var item = _window.items.First(); Assert.AreEqual(1, item.changes.Count); Assert.AreEqual(1, item.changesTotal); Assert.AreEqual("Path1", item.changes.First().path); } [Test] public void CollabHistoryPresenter_OnUpdatePage__FolderMetaFilesAreCounted() { _service.result = new RevisionsResult() { Revisions = new List() { new Revision ( authorName: "Test", author: "test", entries: new ChangeAction[1] { new ChangeAction(path: "Folder1.meta", action: "Action1"), } ), } }; _presenter.OnUpdatePage(1); var item = _window.items.First(); Assert.AreEqual(1, item.changes.Count); Assert.AreEqual(1, item.changesTotal); Assert.AreEqual("Folder1", item.changes.First().path); } private static ChangeAction[] GenerateChangeActions(int count) { var entries = new ChangeAction[count]; for (var i = 0; i < count; i++) entries[i] = new ChangeAction(path: "Path" + i, action: "Action" + i); return entries; } } internal class TestRevisionsService : IRevisionsService { public RevisionsResult result; public event RevisionsDelegate FetchRevisionsCallback; public string tipRevision { get; set; } public string currentUser { get; set; } public void GetRevisions(int offset, int count) { if(FetchRevisionsCallback != null) { FetchRevisionsCallback(result); } } } internal class TestHistoryWindow : ICollabHistoryWindow { public IEnumerable items; public bool revisionActionsEnabled { get; set; } public int itemsPerPage { get; set; } public string errMessage { get; set; } public string inProgressRevision { get; set; } public PageChangeAction OnPageChangeAction { get; set; } public RevisionAction OnGoBackAction { get; set; } public RevisionAction OnUpdateAction { get; set; } public RevisionAction OnRestoreAction { get; set; } public ShowBuildAction OnShowBuildAction { get; set; } public Action OnShowServicesAction { get; set; } public void UpdateState(HistoryState state, bool force) { } public void UpdateRevisions(IEnumerable items, string tip, int totalRevisions, int currPage) { this.items = items; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests/Editor/HistoryTests.cs.meta ================================================ fileFormatVersion: 2 guid: 23a56a19774ed42b6b65646af08a003c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests/Editor/Unity.CollabProxy.EditorTests.asmdef ================================================ { "name": "Unity.CollabProxy.EditorTests", "references": [ "Unity.CollabProxy.Editor" ], "optionalUnityReferences": [ "TestAssemblies" ], "includePlatforms": [ "Editor" ], "excludePlatforms": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests/Editor/Unity.CollabProxy.EditorTests.asmdef.meta ================================================ fileFormatVersion: 2 guid: 782de34c17796430ba8d0ceddb60944e AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests/Editor.meta ================================================ fileFormatVersion: 2 guid: 4506ac79f5b274cb1b249ed7f4abfb9a folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests.meta ================================================ fileFormatVersion: 2 guid: 1369382d2c5e64dc5b2ec0b6b0a94531 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/package.json ================================================ { "name": "com.unity.collab-proxy", "displayName": "Unity Collaborate", "version": "1.2.16", "unity": "2018.3", "description": "Collaborate is a simple way for teams to save, share, and sync their Unity project", "keywords": [ "collab", "collaborate", "teams", "team", "cloud", "backup" ], "dependencies": {}, "repository": { "type": "git", "url": "https://gitlab.cds.internal.unity3d.com/upm-packages/cloud-services/collab-proxy.git", "revision": "070e173b6a36e1d6097b1d95e09c08840c23f6ca" } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/package.json.meta ================================================ fileFormatVersion: 2 guid: 57b0c806ba25b48aa8a6ecb3345a4a9b TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/.gitlab-ci.yml ================================================ image: node:6.10.0 stages: - push_to_packman_staging push_to_packman_staging: stage: push_to_packman_staging only: - tags script: - sed -i "s/0.0.1-PLACEHOLDERVERSION/$CI_COMMIT_TAG/g" package.json - sed -i "s/PLACEHOLDERSHA/$CI_COMMIT_SHA/g" package.json - sed -i "s/0.0.1-PLACEHOLDERVERSION/$CI_COMMIT_TAG/g" CHANGELOG.md - curl -u $USER_NAME:$API_KEY https://staging-packages.unity.com/auth > .npmrc - npm publish ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/CHANGELOG.md ================================================ # Changelog All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [1.0.0] - 2019-02-21 ### This is the first release of *Unity Package com.unity.ext.nunit*. - Migrated the custom version of nunit from inside of unity. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/CHANGELOG.md.meta ================================================ fileFormatVersion: 2 guid: f49bbe06ffa5ae24abe32abdab430c24 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/Documentation~/ext.nunit.md ================================================ # Custom Nunit build to work with Unity This version of nunit works with all platforms, il2cpp and Mono AOT. For Nunit Documentation: https://github.com/nunit/docs/wiki/NUnit-Documentation ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/LICENSE.md ================================================ Copyright (c) 2018 Charlie Poole, Rob Prouse 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: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/LICENSE.md.meta ================================================ fileFormatVersion: 2 guid: f91a00d2dca52b843b2d50ccf750737d TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/README.md ================================================ # Custom Nunit build to work with Unity This version of nunit works with all platforms, il2cpp and Mono AOT. For Nunit Documentation: https://github.com/nunit/docs/wiki/NUnit-Documentation ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/README.md.meta ================================================ fileFormatVersion: 2 guid: 5da62a0c1c5218c4aa16b74546a7822d TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/This is a custom build DONT include.txt ================================================ This is a custom nUnit build meant to be used by Unity editor and players. It shoul not be included or referenced from anywhere (unless you know what you're doing) Build from this repo https://github.com/Unity-Technologies/nunit ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/This is a custom build DONT include.txt.meta ================================================ fileFormatVersion: 2 guid: 3d67ccdf81bed8247ad0db2d5f47a7d1 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.dll.mdb.meta ================================================ fileFormatVersion: 2 guid: 6f768c3714a34a549960ea903fbadcc2 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.dll.meta ================================================ fileFormatVersion: 2 guid: f1605f5534186904fa2c4c42acbfe01e PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} defineConstraints: ["UNITY_INCLUDE_TESTS"] isPreloaded: 0 isOverridable: 1 isExplicitlyReferenced: 1 platformData: - first: '': Any second: enabled: 0 settings: {} - first: Any: second: enabled: 1 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true - first: Windows Store Apps: WindowsStoreApps second: enabled: 0 settings: CPU: AnyCPU userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.pdb.meta ================================================ fileFormatVersion: 2 guid: f136f1f122a53c64c9af51baecaa9c96 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.xml ================================================ nunit.framework Basic Asserts on strings. The Equals method throws an InvalidOperationException. This is done to make sure there is no mistake by calling this function. override the default ReferenceEquals to throw an InvalidOperationException. This implementation makes sure there is no mistake in calling this function as part of Assert. Asserts that a string is found within another string. The expected string The string to be examined The message to display in case of failure Arguments used in formatting the message Asserts that a string is found within another string. The expected string The string to be examined Asserts that a string is not found within another string. The expected string The string to be examined The message to display in case of failure Arguments used in formatting the message Asserts that a string is found within another string. The expected string The string to be examined Asserts that a string starts with another string. The expected string The string to be examined The message to display in case of failure Arguments used in formatting the message Asserts that a string starts with another string. The expected string The string to be examined Asserts that a string does not start with another string. The expected string The string to be examined The message to display in case of failure Arguments used in formatting the message Asserts that a string does not start with another string. The expected string The string to be examined Asserts that a string ends with another string. The expected string The string to be examined The message to display in case of failure Arguments used in formatting the message Asserts that a string ends with another string. The expected string The string to be examined Asserts that a string does not end with another string. The expected string The string to be examined The message to display in case of failure Arguments used in formatting the message Asserts that a string does not end with another string. The expected string The string to be examined Asserts that two strings are equal, without regard to case. The expected string The actual string The message to display in case of failure Arguments used in formatting the message Asserts that two strings are equal, without regard to case. The expected string The actual string Asserts that two strings are not equal, without regard to case. The expected string The actual string The message to display in case of failure Arguments used in formatting the message Asserts that two strings are not equal, without regard to case. The expected string The actual string Asserts that a string matches an expected regular expression pattern. The regex pattern to be matched The actual string The message to display in case of failure Arguments used in formatting the message Asserts that a string matches an expected regular expression pattern. The regex pattern to be matched The actual string Asserts that a string does not match an expected regular expression pattern. The regex pattern to be used The actual string The message to display in case of failure Arguments used in formatting the message Asserts that a string does not match an expected regular expression pattern. The regex pattern to be used The actual string Combines multiple filters so that a test must pass all of them in order to pass this filter. A base class for multi-part filters Interface to be implemented by filters applied to tests. The filter applies when running the test, after it has been loaded, since this is the only time an ITest exists. Interface to be implemented by filters applied to tests. The filter applies when running the test, after it has been loaded, since this is the only time an ITest exists. An object implementing IXmlNodeBuilder is able to build an XML representation of itself and any children. Returns a TNode representing the current object. If true, children are included where applicable A TNode representing the result Returns a TNode representing the current object after adding it as a child of the supplied parent node. The parent node. If true, children are included, where applicable Determine if a particular test passes the filter criteria. Pass may examine the parents and/or descendants of a test, depending on the semantics of the particular filter The test to which the filter is applied True if the test passes the filter, otherwise false Determine if a test matches the filter expicitly. That is, it must be a direct match of the test itself or one of it's children. The test to which the filter is applied True if the test matches the filter explicityly, otherwise false Unique Empty filter. Determine if a particular test passes the filter criteria. The default implementation checks the test itself, its parents and any descendants. Derived classes may override this method or any of the Match methods to change the behavior of the filter. The test to which the filter is applied True if the test passes the filter, otherwise false Determine if a test matches the filter expicitly. That is, it must be a direct match of the test itself or one of it's children. The test to which the filter is applied True if the test matches the filter explicityly, otherwise false Determine whether the test itself matches the filter criteria, without examining either parents or descendants. This is overridden by each different type of filter to perform the necessary tests. The test to which the filter is applied True if the filter matches the any parent of the test Determine whether any ancestor of the test matches the filter criteria The test to which the filter is applied True if the filter matches the an ancestor of the test Determine whether any descendant of the test matches the filter criteria. The test to be matched True if at least one descendant matches the filter criteria Create a TestFilter instance from an xml representation. Create a TestFilter from it's TNode representation Adds an XML node True if recursive The added XML node Adds an XML node Parent node True if recursive The added XML node Indicates whether this is the EmptyFilter Indicates whether this is a top-level filter, not contained in any other filter. Nested class provides an empty filter - one that always returns true when called. It never matches explicitly. Constructs an empty CompositeFilter Constructs a CompositeFilter from an array of filters Adds a filter to the list of filters The filter to be added Checks whether the CompositeFilter is matched by a test. The test to be matched Checks whether the CompositeFilter is matched by a test. The test to be matched Checks whether the CompositeFilter is explicit matched by a test. The test to be matched Adds an XML node Parent node True if recursive The added XML node Return a list of the composing filters. Gets the element name Element name Constructs an empty AndFilter Constructs an AndFilter from an array of filters Checks whether the AndFilter is matched by a test The test to be matched True if all the component filters pass, otherwise false Checks whether the AndFilter is matched by a test The test to be matched True if all the component filters match, otherwise false Checks whether the AndFilter is explicit matched by a test. The test to be matched True if all the component filters explicit match, otherwise false Gets the element name Element name SubstringConstraint can test whether a string contains the expected substring. StringConstraint is the abstract base for constraints that operate on strings. It supports the IgnoreCase modifier for string operations. The Constraint class is the base of all built-in constraints within NUnit. It provides the operator overloads used to combine constraints. Interface for all constraints The IResolveConstraint interface is implemented by all complete and resolvable constraints and expressions. Return the top-level constraint for this expression Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult Applies the constraint to an ActualValueDelegate that returns the value to be tested. The default implementation simply evaluates the delegate but derived classes may override it to provide for delayed processing. An ActualValueDelegate A ConstraintResult Test whether the constraint is satisfied by a given reference. The default implementation simply dereferences the value but derived classes may override it to provide for delayed processing. A reference to the value to be tested A ConstraintResult The display name of this Constraint for use by ToString(). The Description of what this constraint tests, for use in messages and in the ConstraintResult. Arguments provided to this Constraint, for use in formatting the description. The ConstraintBuilder holding this constraint Construct a constraint with optional arguments Arguments to be saved Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult Applies the constraint to an ActualValueDelegate that returns the value to be tested. The default implementation simply evaluates the delegate but derived classes may override it to provide for delayed processing. An ActualValueDelegate A ConstraintResult Test whether the constraint is satisfied by a given reference. The default implementation simply dereferences the value but derived classes may override it to provide for delayed processing. A reference to the value to be tested A ConstraintResult Retrieves the value to be tested from an ActualValueDelegate. The default implementation simply evaluates the delegate but derived classes may override it to provide for delayed processing. An ActualValueDelegate Delegate evaluation result Default override of ToString returns the constraint DisplayName followed by any arguments within angle brackets. Returns the string representation of this constraint This operator creates a constraint that is satisfied only if both argument constraints are satisfied. This operator creates a constraint that is satisfied if either of the argument constraints is satisfied. This operator creates a constraint that is satisfied if the argument constraint is not satisfied. Returns a DelayedConstraint with the specified delay time. The delay in milliseconds. Returns a DelayedConstraint with the specified delay time and polling interval. The delay in milliseconds. The interval at which to test the constraint. Resolves any pending operators and returns the resolved constraint. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. Arguments provided to this Constraint, for use in formatting the description. The ConstraintBuilder holding this constraint Returns a ConstraintExpression by appending And to the current constraint. Returns a ConstraintExpression by appending And to the current constraint. Returns a ConstraintExpression by appending Or to the current constraint. The expected value Indicates whether tests should be case-insensitive Description of this constraint Constructs a StringConstraint without an expected value Constructs a StringConstraint given an expected value The expected value Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Test whether the constraint is satisfied by a given string The string to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. Modify the constraint to ignore case in matching. Initializes a new instance of the class. The expected. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Abstract base class used for prefixes Construct given a base constraint The base constraint Prefix used in forming the constraint description The Description of what this constraint tests, for use in messages and in the ConstraintResult. AssignableToConstraint is used to test that an object can be assigned to a given Type. TypeConstraint is the abstract base for constraints that take a Type as their expected value. The expected Type used by the constraint The type of the actual argument to which the constraint was applied Construct a TypeConstraint for a given Type The expected type for the constraint Prefix used in forming the constraint description Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult Apply the constraint to an actual value, returning true if it succeeds The actual argument True if the constraint succeeds, otherwise false. Construct an AssignableToConstraint for the type provided Apply the constraint to an actual value, returning true if it succeeds The actual argument True if the constraint succeeds, otherwise false. Summary description for MaxTimeAttribute. PropertyAttribute is used to attach information to a test as a name/value pair.. The abstract base class for all custom attributes defined by NUnit. Default constructor The IApplyToTest interface is implemented by self-applying attributes that modify the state of a test in some way. Modifies a test as defined for the specific attribute. The test to modify Construct a PropertyAttribute with a name and string value The name of the property The property value Construct a PropertyAttribute with a name and int value The name of the property The property value Construct a PropertyAttribute with a name and double value The name of the property The property value Constructor for derived classes that set the property dictionary directly. Constructor for use by derived classes that use the name of the type as the property name. Derived classes must ensure that the Type of the property value is a standard type supported by the BCL. Any custom types will cause a serialization Exception when in the client. Modifies a test by adding properties to it. The test to modify Gets the property dictionary for this attribute Objects implementing this interface are used to wrap the entire test, including SetUp and TearDown. ICommandWrapper is implemented by attributes and other objects able to wrap a TestCommand with another command. Attributes or other objects should implement one of the derived interfaces, rather than this one, since they indicate in which part of the command chain the wrapper should be applied. Wrap a command and return the result. The command to be wrapped The wrapped command Construct a MaxTimeAttribute, given a time in milliseconds. The maximum elapsed time in milliseconds Randomizer returns a set of random _values in a repeatable way, to allow re-running of tests if necessary. It extends the .NET Random class, providing random values for a much wider range of types. The class is used internally by the framework to generate test case data and is also exposed for use by users through the TestContext.Random property. For consistency with the underlying Random Type, methods returning a single value use the prefix "Next..." Those without an argument return a non-negative value up to the full positive range of the Type. Overloads are provided for specifying a maximum or a range. Methods that return arrays or strings use the prefix "Get..." to avoid confusion with the single-value methods. Default characters for random functions. Default characters are the English alphabet (uppercase & lowercase), arabic numerals, and underscore Get a Randomizer for a particular member, returning one that has already been created if it exists. This ensures that the same _values are generated each time the tests are reloaded. Get a randomizer for a particular parameter, returning one that has already been created if it exists. This ensures that the same values are generated each time the tests are reloaded. Create a new Randomizer using the next seed available to ensure that each randomizer gives a unique sequence of values. Default constructor Construct based on seed value Returns a random unsigned int. Returns a random unsigned int less than the specified maximum. Returns a random unsigned int within a specified range. Returns a non-negative random short. Returns a non-negative random short less than the specified maximum. Returns a non-negative random short within a specified range. Returns a random unsigned short. Returns a random unsigned short less than the specified maximum. Returns a random unsigned short within a specified range. Returns a random long. Returns a random long less than the specified maximum. Returns a non-negative random long within a specified range. Returns a random ulong. Returns a random ulong less than the specified maximum. Returns a non-negative random long within a specified range. Returns a random Byte Returns a random Byte less than the specified maximum. Returns a random Byte within a specified range Returns a random SByte Returns a random sbyte less than the specified maximum. Returns a random sbyte within a specified range Returns a random bool Returns a random bool based on the probablility a true result Returns a random double between 0.0 and the specified maximum. Returns a random double within a specified range. Returns a random float. Returns a random float between 0.0 and the specified maximum. Returns a random float within a specified range. Returns a random enum value of the specified Type as an object. Returns a random enum value of the specified Type. Generate a random string based on the characters from the input string. desired length of output string. string representing the set of characters from which to construct the resulting string A random string of arbitrary length Generate a random string based on the characters from the input string. desired length of output string. A random string of arbitrary length Uses DefaultStringChars as the input character set Generate a random string based on the characters from the input string. A random string of the default length Uses DefaultStringChars as the input character set Returns a random decimal. Returns a random decimal between positive zero and the specified maximum. Returns a random decimal within a specified range, which is not permitted to exceed decimal.MaxVal in the current implementation. A limitation of this implementation is that the range from min to max must not exceed decimal.MaxVal. Initial seed used to create randomizers for this run The IFixtureBuilder interface is exposed by a class that knows how to build a TestFixture from one or more Types. In general, it is exposed by an attribute, but may be implemented in a helper class used by the attribute in some cases. Build one or more TestFixtures from type provided. At least one non-null TestSuite must always be returned, since the method is generally called because the user has marked the target class as a fixture. If something prevents the fixture from being used, it will be returned nonetheless, labelled as non-runnable. The type info of the fixture to be used. A TestSuite object or one derived from TestSuite. The ITestBuilder interface is exposed by a class that knows how to build one or more TestMethods from a MethodInfo. In general, it is exposed by an attribute, which has additional information available to provide the necessary test parameters to distinguish the test cases built. Build one or more TestMethods from the provided MethodInfo. The method to be used as a test The TestSuite to which the method will be added A TestMethod object The IReflectionInfo interface is implemented by NUnit wrapper objects that perform reflection. Returns an array of custom attributes of the specified type applied to this object Returns a value indicating whether an attribute of the specified type is defined on this object. Represents the result of running a test suite The TestResult class represents the result of a test. The ITestResult interface represents the result of a test. Gets the ResultState of the test result, which indicates the success or failure of the test. Gets the name of the test result Gets the full name of the test result Gets the elapsed time for running the test in seconds Gets or sets the time the test started running. Gets or sets the time the test finished running. Gets the message associated with a test failure or with not running the test Gets any stacktrace associated with an error or failure. Not available in the Compact Framework 1.0. Gets the number of asserts executed when running the test and all its children. Gets the number of test cases that failed when running the test and all its children. Gets the number of test cases that passed when running the test and all its children. Gets the number of test cases that were skipped when running the test and all its children. Gets the number of test cases that were inconclusive when running the test and all its children. Indicates whether this result has any child results. Accessing HasChildren should not force creation of the Children collection in classes implementing this interface. Gets the the collection of child results. Gets the Test to which this result applies. Gets any text output written to this result. The minimum duration for tests Error message for when child tests have errors Error message for when child tests are ignored Aggregate assertion count Construct a test result given a Test The test to be used Returns the Xml representation of the result. If true, descendant results are included An XmlNode representing the result Adds the XML representation of the result as a child of the supplied parent node.. The parent node. If true, descendant results are included Set the result of the test The ResultState to use in the result Set the result of the test The ResultState to use in the result A message associated with the result state Set the result of the test The ResultState to use in the result A message associated with the result state Stack trace giving the location of the command Set the test result based on the type of exception thrown The exception that was thrown Set the test result based on the type of exception thrown The exception that was thrown THe FailureSite to use in the result RecordTearDownException appends the message and stacktrace from an exception arising during teardown of the test to any previously recorded information, so that any earlier failure information is not lost. Note that calling Assert.Ignore, Assert.Inconclusive, etc. during teardown is treated as an error. If the current result represents a suite, it may show a teardown error even though all contained tests passed. The Exception to be recorded Adds a reason element to a node and returns it. The target node. The new reason element. Adds a failure element to a node and returns it. The target node. The new failure element. Gets the test with which this result is associated. Gets the ResultState of the test result, which indicates the success or failure of the test. Gets the name of the test result Gets the full name of the test result Gets or sets the elapsed time for running the test in seconds Gets or sets the time the test started running. Gets or sets the time the test finished running. Gets the message associated with a test failure or with not running the test Gets any stacktrace associated with an error or failure. Gets or sets the count of asserts executed when running the test. Gets the number of test cases that failed when running the test and all its children. Gets the number of test cases that passed when running the test and all its children. Gets the number of test cases that were skipped when running the test and all its children. Gets the number of test cases that were inconclusive when running the test and all its children. Indicates whether this result has any child results. Gets the collection of child results. Gets a TextWriter, which will write output to be included in the result. Gets any text output written to this result. Construct a TestSuiteResult base on a TestSuite The TestSuite to which the result applies Adds a child result to this result, setting this result's ResultState to Failure if the child result failed. The result to be added Gets the number of test cases that failed when running the test and all its children. Gets the number of test cases that passed when running the test and all its children. Gets the number of test cases that were skipped when running the test and all its children. Gets the number of test cases that were inconclusive when running the test and all its children. Indicates whether this result has any child results. Gets the collection of child results. TestSuite represents a composite test, which contains other tests. The Test abstract class represents a test within the framework. Common interface supported by all representations of a test. Only includes informational fields. The Run method is specifically excluded to allow for data-only representations of a test. Gets the id of the test Gets the name of the test Gets the fully qualified name of the test Gets the name of the class containing this test. Returns null if the test is not associated with a class. Gets the name of the method implementing this test. Returns null if the test is not implemented as a method. Gets the Type of the test fixture, if applicable, or null if no fixture type is associated with this test. Gets an IMethod for the method implementing this test. Returns null if the test is not implemented as a method. Gets the RunState of the test, indicating whether it can be run. Count of the test cases ( 1 if this is a test case ) Gets the properties of the test Gets the parent test, if any. The parent test or null if none exists. Returns true if this is a test suite Gets a bool indicating whether the current test has any descendant tests. Gets this test's child tests A list of child tests Gets a fixture object for running this test. Static value to seed ids. It's started at 1000 so any uninitialized ids will stand out. The SetUp methods. The teardown methods Used to cache the declaring type for this MethodInfo Method property backing field Constructs a test given its name The name of the test Constructs a test given the path through the test hierarchy to its parent and a name. The parent tests full name The name of the test TODO: Documentation needed for constructor Construct a test from a MethodInfo Creates a TestResult for this test. A TestResult suitable for this type of test. Modify a newly constructed test by applying any of NUnit's common attributes, based on a supplied ICustomAttributeProvider, which is usually the reflection element from which the test was constructed, but may not be in some instances. The attributes retrieved are saved for use in subsequent operations. An object implementing ICustomAttributeProvider Add standard attributes and members to a test node. Returns the Xml representation of the test If true, include child tests recursively Returns an XmlNode representing the current result after adding it as a child of the supplied parent node. The parent node. If true, descendant results are included Compares this test to another test for sorting purposes The other test Value of -1, 0 or +1 depending on whether the current test is less than, equal to or greater than the other test Gets or sets the id of the test Gets or sets the name of the test Gets or sets the fully qualified name of the test Gets the name of the class where this test was declared. Returns null if the test is not associated with a class. Gets the name of the method implementing this test. Returns null if the test is not implemented as a method. Gets the TypeInfo of the fixture used in running this test or null if no fixture type is associated with it. Gets a MethodInfo for the method implementing this test. Returns null if the test is not implemented as a method. Whether or not the test should be run Gets the name used for the top-level element in the XML representation of this test Gets a string representing the type of test. Used as an attribute value in the XML representation of a test and has no other function in the framework. Gets a count of test cases represented by or contained under this test. Gets the properties for this test Returns true if this is a TestSuite Gets a bool indicating whether the current test has any descendant tests. Gets the parent as a Test object. Used by the core to set the parent. Gets this test's child tests A list of child tests Gets or sets a fixture object for running this test. Static prefix used for ids in this AppDomain. Set by FrameworkController. Gets or Sets the Int value representing the seed for the RandomGenerator Our collection of child tests Initializes a new instance of the class. The name of the suite. Initializes a new instance of the class. Name of the parent suite. The name of the suite. Initializes a new instance of the class. Type of the fixture. Initializes a new instance of the class. Type of the fixture. Sorts tests under this suite. Adds a test to the suite. The test. Overridden to return a TestSuiteResult. A TestResult for this test. Returns an XmlNode representing the current result after adding it as a child of the supplied parent node. The parent node. If true, descendant results are included Check that setup and teardown methods marked by certain attributes meet NUnit's requirements and mark the tests not runnable otherwise. The attribute type to check for Gets this test's child tests The list of child tests Gets a count of test cases represented by or contained under this test. The arguments to use in creating the fixture Set to true to suppress sorting this suite's contents Gets a bool indicating whether the current test has any descendant tests. Gets the name used for the top-level element in the XML representation of this test A PropertyBag represents a collection of name value pairs that allows duplicate entries with the same key. Methods are provided for adding a new pair as well as for setting a key to a single value. All keys are strings but _values may be of any type. Null _values are not permitted, since a null entry represents the absence of the key. A PropertyBag represents a collection of name/value pairs that allows duplicate entries with the same key. Methods are provided for adding a new pair as well as for setting a key to a single value. All keys are strings but _values may be of any type. Null _values are not permitted, since a null entry represents the absence of the key. The entries in a PropertyBag are of two kinds: those that take a single value and those that take multiple _values. However, the PropertyBag has no knowledge of which entries fall into each category and the distinction is entirely up to the code using the PropertyBag. When working with multi-valued properties, client code should use the Add method to add name/value pairs and indexing to retrieve a list of all _values for a given key. For example: bag.Add("Tag", "one"); bag.Add("Tag", "two"); Assert.That(bag["Tag"], Is.EqualTo(new string[] { "one", "two" })); When working with single-valued propeties, client code should use the Set method to set the value and Get to retrieve the value. The GetSetting methods may also be used to retrieve the value in a type-safe manner while also providing default. For example: bag.Set("Priority", "low"); bag.Set("Priority", "high"); // replaces value Assert.That(bag.Get("Priority"), Is.EqualTo("high")); Assert.That(bag.GetSetting("Priority", "low"), Is.EqualTo("high")); Adds a key/value pair to the property bag The key The value Sets the value for a key, removing any other _values that are already in the property set. Gets a single value for a key, using the first one if multiple _values are present and returning null if the value is not found. Gets a flag indicating whether the specified key has any entries in the property set. The key to be checked True if their are _values present, otherwise false Gets or sets the list of _values for a particular key The key for which the _values are to be retrieved or set Gets a collection containing all the keys in the property set Adds a key/value pair to the property set The key The value Sets the value for a key, removing any other _values that are already in the property set. Gets a single value for a key, using the first one if multiple _values are present and returning null if the value is not found. Gets a flag indicating whether the specified key has any entries in the property set. The key to be checked True if their are _values present, otherwise false Returns an XmlNode representating the current PropertyBag. Not used An XmlNode representing the PropertyBag Returns an XmlNode representing the PropertyBag after adding it as a child of the supplied parent node. The parent node. Not used Gets a collection containing all the keys in the property set Gets or sets the list of _values for a particular key Thrown when an assertion failed. Here to preserve the inner exception and hence its stack trace. Initializes a new instance of the class. Initializes a new instance of the class. The error message that explains the reason for the exception Initializes a new instance of the class. The error message that explains the reason for the exception The exception that caused the current exception Serialization Constructor FullName filter selects tests based on their FullName ValueMatchFilter selects tests based on some value, which is expected to be contained in the test. Construct a ValueMatchFilter for a single value. The value to be included. Match the input provided by the derived class The value to be matchedT True for a match, false otherwise. Adds an XML node Parent node True if recursive The added XML node Returns the value matched by the filter - used for testing Indicates whether the value is a regular expression Gets the element name Element name Construct a FullNameFilter for a single name The name the filter will recognize. Match a test against a single value. Gets the element name Element name NotFilter negates the operation of another filter Construct a not filter on another filter The filter to be negated Determine if a particular test passes the filter criteria. The default implementation checks the test itself, its parents and any descendants. Derived classes may override this method or any of the Match methods to change the behavior of the filter. The test to which the filter is applied True if the test passes the filter, otherwise false Check whether the filter matches a test The test to be matched True if it matches, otherwise false Determine if a test matches the filter expicitly. That is, it must be a direct match of the test itself or one of it's children. The test to which the filter is applied True if the test matches the filter explicityly, otherwise false Adds an XML node Parent node True if recursive The added XML node Gets the base filter SequentialStrategy creates test cases by using all of the parameter data sources in parallel, substituting null when any of them run out of data. CombiningStrategy is the abstract base for classes that know how to combine values provided for individual test parameters to create a set of test cases. Gets the test cases generated by the CombiningStrategy. The test cases. Gets the test cases generated by the CombiningStrategy. The test cases. NUnitTestFixtureBuilder is able to build a fixture given a class marked with a TestFixtureAttribute or an unmarked class containing test methods. In the first case, it is called by the attribute and in the second directly by NUnitSuiteBuilder. Build a TestFixture from type provided. A non-null TestSuite must always be returned, since the method is generally called because the user has marked the target class as a fixture. If something prevents the fixture from being used, it should be returned nonetheless, labelled as non-runnable. An ITypeInfo for the fixture to be used. A TestSuite object or one derived from TestSuite. Overload of BuildFrom called by tests that have arguments. Builds a fixture using the provided type and information in the ITestFixtureData object. The TypeInfo for which to construct a fixture. An object implementing ITestFixtureData or null. Method to add test cases to the newly constructed fixture. The fixture to which cases should be added Method to create a test case from a MethodInfo and add it to the fixture being built. It first checks to see if any global TestCaseBuilder addin wants to build the test case. If not, it uses the internal builder collection maintained by this fixture builder. The default implementation has no test case builders. Derived classes should add builders to the collection in their constructor. The method for which a test is to be created The test suite being built. A newly constructed Test UniqueItemsConstraint tests whether all the items in a collection are unique. CollectionItemsEqualConstraint is the abstract base class for all collection constraints that apply some notion of item equality as a part of their operation. CollectionConstraint is the abstract base class for constraints that operate on collections. Construct an empty CollectionConstraint Construct a CollectionConstraint Determines whether the specified enumerable is empty. The enumerable. true if the specified enumerable is empty; otherwise, false. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Protected method to be implemented by derived classes Construct an empty CollectionConstraint Construct a CollectionConstraint Flag the constraint to use the supplied IComparer object. The IComparer object to use. Self. Flag the constraint to use the supplied IComparer object. The IComparer object to use. Self. Flag the constraint to use the supplied Comparison object. The IComparer object to use. Self. Flag the constraint to use the supplied IEqualityComparer object. The IComparer object to use. Self. Flag the constraint to use the supplied IEqualityComparer object. The IComparer object to use. Self. Compares two collection members for equality Return a new CollectionTally for use in making tests The collection to be included in the tally Flag the constraint to ignore case and return self. Check that all items are unique. The Description of what this constraint tests, for use in messages and in the ConstraintResult. SamePathOrUnderConstraint tests that one path is under another PathConstraint serves as the abstract base of constraints that operate on paths and provides several helper methods. Construct a PathConstraint for a give expected path The expected path Returns the string representation of this constraint Canonicalize the provided path The path in standardized form Test whether one path in canonical form is a subpath of another path The first path - supposed to be the parent path The second path - supposed to be the child path Modifies the current instance to be case-sensitive and returns it. Initializes a new instance of the class. The expected path Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. NoItemConstraint applies another constraint to each item in a collection, failing if any of them succeeds. Construct a SomeItemsConstraint on top of an existing constraint Apply the item constraint to each item in the collection, failing if any item fails. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. EndsWithConstraint can test whether a string ends with an expected substring. Initializes a new instance of the class. The expected string Test whether the constraint is matched by the actual value. This is a template method, which calls the IsMatch method of the derived class. ValuesAttribute is used to provide literal arguments for an individual parameter of a test. The abstract base class for all data-providing attributes defined by NUnit. Used to select all data sources for a method, class or parameter. Default constructor The IParameterDataSource interface is implemented by types that can provide data for a test method parameter. Gets an enumeration of data items for use as arguments for a test method parameter. The parameter for which data is needed An enumeration containing individual data items The collection of data to be returned. Must be set by any derived attribute classes. We use an object[] so that the individual elements may have their type changed in GetData if necessary Constructs for use with an Enum parameter. Will pass every enum value in to the test. Construct with one argument Construct with two arguments Construct with three arguments Construct with an array of arguments Get the collection of _values to be used as arguments Marks a test to use a pairwise join of any argument data provided. Arguments will be combined in such a way that all possible pairs of arguments are used. Marks a test to use a particular CombiningStrategy to join any parameter data provided. Since this is the default, the attribute is optional. Construct a CombiningStrategyAttribute incorporating an ICombiningStrategy and an IParamterDataProvider. Combining strategy to be used in combining data An IParameterDataProvider to supply data Construct a CombiningStrategyAttribute incorporating an object that implements ICombiningStrategy and an IParameterDataProvider. This constructor is provided for CLS compliance. Combining strategy to be used in combining data An IParameterDataProvider to supply data Construct one or more TestMethods from a given MethodInfo, using available parameter data. The MethodInfo for which tests are to be constructed. The suite to which the tests will be added. One or more TestMethods Modify the test by adding the name of the combining strategy to the properties. The test to modify Default constructor CultureAttribute is used to mark a test fixture or an individual method as applying to a particular Culture only. Abstract base for Attributes that are used to include tests in the test run based on environmental settings. Constructor with no included items specified, for use with named property syntax. Constructor taking one or more included items Comma-delimited list of included items Name of the item that is needed in order for a test to run. Multiple items may be given, separated by a comma. Name of the item to be excluded. Multiple items may be given, separated by a comma. The reason for including or excluding the test Constructor with no cultures specified, for use with named property syntax. Constructor taking one or more cultures Comma-deliminted list of cultures Causes a test to be skipped if this CultureAttribute is not satisfied. The test to modify Tests to determine if the current culture is supported based on the properties of this attribute. True, if the current culture is supported Test to determine if the a particular culture or comma- delimited set of cultures is in use. Name of the culture or comma-separated list of culture ids True if the culture is in use on the system Test to determine if one of a collection of cultures is being used currently. The current state of a work item Ready to run or continue Work Item is executing Complete A WorkItem may be an individual test case, a fixture or a higher level grouping of tests. All WorkItems inherit from the abstract WorkItem class, which uses the template pattern to allow derived classes to perform work in whatever way is needed. A WorkItem is created with a particular TestExecutionContext and is responsible for re-establishing that context in the current thread before it begins or resumes execution. Creates a work item. The test for which this WorkItem is being created. The filter to be used in selecting any child Tests. Construct a WorkItem for a particular test. The test that the WorkItem will run Initialize the TestExecutionContext. This must be done before executing the WorkItem. Originally, the context was provided in the constructor but delaying initialization of the context until the item is about to be dispatched allows changes in the parent context during OneTimeSetUp to be reflected in the child. The TestExecutionContext to use Execute the current work item, including any child work items. Cancel (abort or stop) a WorkItem true if the WorkItem should be aborted, false if it should run to completion Method that performs actually performs the work. It should set the State to WorkItemState.Complete when done. Method called by the derived class when all work is complete Event triggered when the item is complete Gets the current state of the WorkItem The test being executed by the work item The execution context The unique id of the worker executing this item. The test actions to be performed before and after this test The test result TODO: Documentation needed for class TODO: Documentation needed for class TestCommand is the abstract base class for all test commands in the framework. A TestCommand represents a single stage in the execution of a test, e.g.: SetUp/TearDown, checking for Timeout, verifying the returned result from a method, etc. TestCommands may decorate other test commands so that the execution of a lower-level command is nested within that of a higher level command. All nested commands are executed synchronously, as a single unit. Scheduling test execution on separate threads is handled at a higher level, using the task dispatcher. Construct a TestCommand for a test. The test to be executed Runs the test in a specified context, returning a TestResult. The TestExecutionContext to be used for running the test. A TestResult Gets the test associated with this command. TODO: Documentation needed for field TODO: Documentation needed for method TODO: Documentation needed for constructor Initializes a new instance of the class. The inner command. The max time allowed in milliseconds Runs the test, saving a TestResult in the supplied TestExecutionContext The context in which the test should run. A TestResult The ITestListener interface is used internally to receive notifications of significant events while a test is being run. The events are propagated to clients by means of an AsyncCallback. NUnit extensions may also monitor these events. Called when a test has just started The test that is starting Called when a test has finished The result of the test Called when a test produces output for immediate display A TestOutput object containing the text to display The ITestAssemblyBuilder interface is implemented by a class that is able to build a suite of tests given an assembly or an assembly filename. Build a suite of tests from a provided assembly The assembly from which tests are to be built A dictionary of options to use in building the suite A TestSuite containing the tests found in the assembly Build a suite of tests given the filename of an assembly The filename of the assembly from which tests are to be built A dictionary of options to use in building the suite A TestSuite containing the tests found in the assembly InternalTrace provides facilities for tracing the execution of the NUnit framework. Tests and classes under test may make use of Console writes, System.Diagnostics.Trace or various loggers and NUnit itself traps and processes each of them. For that reason, a separate internal trace is needed. Note: InternalTrace uses a global lock to allow multiple threads to write trace messages. This can easily make it a bottleneck so it must be used sparingly. Keep the trace Level as low as possible and only insert InternalTrace writes where they are needed. TODO: add some buffering and a separate writer thread as an option. TODO: figure out a way to turn on trace in specific classes only. Initialize the internal trace facility using the name of the log to be written to and the trace level. The log name The trace level Initialize the internal trace using a provided TextWriter and level A TextWriter The InternalTraceLevel Get a named Logger Get a logger named for a particular Type. Gets a flag indicating whether the InternalTrace is initialized The ITypeInfo interface is an abstraction of a .NET Type Returns true if the Type wrapped is equal to the argument Get the display name for this typeInfo. Get the display name for an oject of this type, constructed with specific arguments Returns a Type representing a generic type definition from which this Type can be constructed. Returns a new ITypeInfo representing an instance of this generic Type using the supplied Type arguments Returns a value indicating whether this type has a method with a specified public attribute Returns an array of IMethodInfos for methods of this Type that match the specified flags. Gets the public constructor taking the specified argument Types Returns a value indicating whether this Type has a public constructor taking the specified argument Types. Construct an object of this Type, using the specified arguments. Gets the underlying Type on which this ITypeInfo is based Gets the base type of this type as an ITypeInfo Gets the Name of the Type Gets the FullName of the Type Gets the assembly in which the type is declared Gets the Namespace of the Type Gets a value indicating whether the type is abstract. Gets a value indicating whether the Type is a generic Type Gets a value indicating whether the Type has generic parameters that have not been replaced by specific Types. Gets a value indicating whether the Type is a generic Type definition Gets a value indicating whether the type is sealed. Gets a value indicating whether this type is a static class. Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult The Description of what this constraint tests, for use in messages and in the ConstraintResult. Defines methods to manipulate thread-safe collections intended for producer/consumer usage. Specifies the type of elements in the collection. All implementations of this interface must enable all members of this interface to be used concurrently from multiple threads. Attempts to add an object to the . The object to add to the . true if the object was added successfully; otherwise, false. The was invalid for this collection. Attempts to remove and return an object from the . When this method returns, if the object was removed and returned successfully, contains the removed object. If no object was available to be removed, the value is unspecified. true if an object was removed and returned successfully; otherwise, false. Copies the elements contained in the to a new array. A new array containing the elements copied from the . Copies the elements of the to an , starting at a specified index. The one-dimensional that is the destination of the elements copied from the . The array must have zero-based indexing. The zero-based index in at which copying begins. is a null reference (Nothing in Visual Basic). is less than zero. is equal to or greater than the length of the -or- The number of elements in the source is greater than the available space from to the end of the destination . Provide the context information of the current test. This is an adapter for the internal ExecutionContext class, hiding the internals from the user test. Construct a TestContext for an ExecutionContext The ExecutionContext to adapt Gets a TextWriter that will send output directly to Console.Error Gets a TextWriter for use in displaying immediate progress messages TestParameters object holds parameters for the test run, if any are specified Write the string representation of a boolean value to the current result Write a char to the current result Write a char array to the current result Write the string representation of a double to the current result Write the string representation of an Int32 value to the current result Write the string representation of an Int64 value to the current result Write the string representation of a decimal value to the current result Write the string representation of an object to the current result Write the string representation of a Single value to the current result Write a string to the current result Write the string representation of a UInt32 value to the current result Write the string representation of a UInt64 value to the current result Write a formatted string to the current result Write a formatted string to the current result Write a formatted string to the current result Write a formatted string to the current result Write a line terminator to the current result Write the string representation of a boolean value to the current result followed by a line terminator Write a char to the current result followed by a line terminator Write a char array to the current result followed by a line terminator Write the string representation of a double to the current result followed by a line terminator Write the string representation of an Int32 value to the current result followed by a line terminator Write the string representation of an Int64 value to the current result followed by a line terminator Write the string representation of a decimal value to the current result followed by a line terminator Write the string representation of an object to the current result followed by a line terminator Write the string representation of a Single value to the current result followed by a line terminator Write a string to the current result followed by a line terminator Write the string representation of a UInt32 value to the current result followed by a line terminator Write the string representation of a UInt64 value to the current result followed by a line terminator Write a formatted string to the current result followed by a line terminator Write a formatted string to the current result followed by a line terminator Write a formatted string to the current result followed by a line terminator Write a formatted string to the current result followed by a line terminator This method adds the a new ValueFormatterFactory to the chain of responsibility used for fomatting values in messages. The scope of the change is the current TestContext. The factory delegate This method provides a simplified way to add a ValueFormatter delegate to the chain of responsibility, creating the factory delegate internally. It is useful when the Type of the object is the only criterion for selection of the formatter, since it can be used without getting involved with a compould function. The type supported by this formatter The ValueFormatter delegate Get the current test context. This is created as needed. The user may save the context for use within a test, but it should not be used outside the test for which it is created. Gets a TextWriter that will send output to the current test result. Get a representation of the current test. Gets a Representation of the TestResult for the current test. Gets the unique name of the Worker that is executing this test. Gets the directory containing the current test assembly. Gets the directory to be used for outputting files created by this test run. Gets the random generator. The random generator. TestAdapter adapts a Test for consumption by the user test code. Construct a TestAdapter for a Test The Test to be adapted Gets the unique Id of a test The name of the test, which may or may not be the same as the method name. The name of the method representing the test. The FullName of the test The ClassName of the test The properties of the test. ResultAdapter adapts a TestResult for consumption by the user test code. Construct a ResultAdapter for a TestResult The TestResult to be adapted Gets a ResultState representing the outcome of the test. Gets the message associated with a test failure or with not running the test Gets any stacktrace associated with an error or failure. Gets the number of test cases that failed when running the test and all its children. Gets the number of test cases that passed when running the test and all its children. Gets the number of test cases that were skipped when running the test and all its children. Gets the number of test cases that were inconclusive when running the test and all its children. ExceptionHelper provides static methods for working with exceptions Rethrows an exception, preserving its stack trace The exception to rethrow Builds up a message, using the Message field of the specified exception as well as any InnerExceptions. The exception. A combined message string. Builds up a message, using the Message field of the specified exception as well as any InnerExceptions. The exception. A combined stack trace. Gets the stack trace of the exception. The exception. A string representation of the stack trace. CultureDetector is a helper class used by NUnit to determine whether a test should be run based on the current culture. Default constructor uses the current culture. Construct a CultureDetector for a particular culture for testing. The culture to be used Test to determine if one of a collection of cultures is being used currently. Tests to determine if the current culture is supported based on a culture attribute. The attribute to examine Test to determine if the a particular culture or comma- delimited set of cultures is in use. Name of the culture or comma-separated list of culture ids True if the culture is in use on the system Return the last failure reason. Results are not defined if called before IsSupported( Attribute ) is called. PairwiseStrategy creates test cases by combining the parameter data so that all possible pairs of data items are used. The number of test cases that cover all possible pairs of test function parameters values is significantly less than the number of test cases that cover all possible combination of test function parameters values. And because different studies show that most of software failures are caused by combination of no more than two parameters, pairwise testing can be an effective ways to test the system when it's impossible to test all combinations of parameters. The PairwiseStrategy code is based on "jenny" tool by Bob Jenkins: http://burtleburtle.net/bob/math/jenny.html Gets the test cases generated by this strategy instance. A set of test cases. FleaRand is a pseudo-random number generator developed by Bob Jenkins: http://burtleburtle.net/bob/rand/talksmall.html#flea Initializes a new instance of the FleaRand class. The seed. FeatureInfo represents coverage of a single value of test function parameter, represented as a pair of indices, Dimension and Feature. In terms of unit testing, Dimension is the index of the test parameter and Feature is the index of the supplied value in that parameter's list of sources. Initializes a new instance of FeatureInfo class. Index of a dimension. Index of a feature. A FeatureTuple represents a combination of features, one per test parameter, which should be covered by a test case. In the PairwiseStrategy, we are only trying to cover pairs of features, so the tuples actually may contain only single feature or pair of features, but the algorithm itself works with triplets, quadruples and so on. Initializes a new instance of FeatureTuple class for a single feature. Single feature. Initializes a new instance of FeatureTuple class for a pair of features. First feature. Second feature. TestCase represents a single test case covering a list of features. Initializes a new instance of TestCaseInfo class. A number of features in the test case. PairwiseTestCaseGenerator class implements an algorithm which generates a set of test cases which covers all pairs of possible values of test function. The algorithm starts with creating a set of all feature tuples which we will try to cover (see method). This set includes every single feature and all possible pairs of features. We store feature tuples in the 3-D collection (where axes are "dimension", "feature", and "all combinations which includes this feature"), and for every two feature (e.g. "A" and "B") we generate both ("A", "B") and ("B", "A") pairs. This data structure extremely reduces the amount of time needed to calculate coverage for a single test case (this calculation is the most time-consuming part of the algorithm). Then the algorithm picks one tuple from the uncovered tuple, creates a test case that covers this tuple, and then removes this tuple and all other tuples covered by this test case from the collection of uncovered tuples. Picking a tuple to cover There are no any special rules defined for picking tuples to cover. We just pick them one by one, in the order they were generated. Test generation Test generation starts from creating a completely random test case which covers, nevertheless, previously selected tuple. Then the algorithm tries to maximize number of tuples which this test covers. Test generation and maximization process repeats seven times for every selected tuple and then the algorithm picks the best test case ("seven" is a magic number which provides good results in acceptable time). Maximizing test coverage To maximize tests coverage, the algorithm walks thru the list of mutable dimensions (mutable dimension is a dimension that are not included in the previously selected tuple). Then for every dimension, the algorithm walks thru the list of features and checks if this feature provides better coverage than randomly selected feature, and if yes keeps this feature. This process repeats while it shows progress. If the last iteration doesn't improve coverage, the process ends. In addition, for better results, before start every iteration, the algorithm "scrambles" dimensions - so for every iteration dimension probes in a different order. Creates a set of test cases for specified dimensions. An array which contains information about dimensions. Each element of this array represents a number of features in the specific dimension. A set of test cases. Provides data from fields marked with the DatapointAttribute or the DatapointsAttribute. The IDataPointProvider interface is used by extensions that provide data for a single test parameter. Determine whether any data is available for a parameter. An IParameterInfo representing one argument to a parameterized test True if any data is available, otherwise false. Return an IEnumerable providing data for use with the supplied parameter. An IParameterInfo representing one argument to a parameterized test An IEnumerable providing the required data Determine whether any data is available for a parameter. A ParameterInfo representing one argument to a parameterized test True if any data is available, otherwise false. Return an IEnumerable providing data for use with the supplied parameter. A ParameterInfo representing one argument to a parameterized test An IEnumerable providing the required data CombinatorialStrategy creates test cases by using all possible combinations of the parameter data. Gets the test cases generated by the CombiningStrategy. The test cases. ThrowsNothingConstraint tests that a delegate does not throw an exception. Test whether the constraint is satisfied by a given value The value to be tested True if no exception is thrown, otherwise false Applies the constraint to an ActualValueDelegate that returns the value to be tested. The default implementation simply evaluates the delegate but derived classes may override it to provide for delayed processing. An ActualValueDelegate A ConstraintResult Gets text describing a constraint Operator that requires at least one of it's arguments to succeed Abstract base class for all binary operators The ConstraintOperator class is used internally by a ConstraintBuilder to represent an operator that modifies or combines constraints. Constraint operators use left and right precedence _values to determine whether the top operator on the stack should be reduced before pushing a new operator. The precedence value used when the operator is about to be pushed to the stack. The precedence value used when the operator is on the top of the stack. Reduce produces a constraint from the operator and any arguments. It takes the arguments from the constraint stack and pushes the resulting constraint on it. The syntax element preceding this operator The syntax element following this operator The precedence value used when the operator is about to be pushed to the stack. The precedence value used when the operator is on the top of the stack. Reduce produces a constraint from the operator and any arguments. It takes the arguments from the constraint stack and pushes the resulting constraint on it. Abstract method that produces a constraint by applying the operator to its left and right constraint arguments. Gets the left precedence of the operator Gets the right precedence of the operator Construct an OrOperator Apply the operator to produce an OrConstraint The Numerics class contains common operations on numeric _values. Checks the type of the object, returning true if the object is a numeric type. The object to check true if the object is a numeric type Checks the type of the object, returning true if the object is a floating point numeric type. The object to check true if the object is a floating point numeric type Checks the type of the object, returning true if the object is a fixed point numeric type. The object to check true if the object is a fixed point numeric type Test two numeric _values for equality, performing the usual numeric conversions and using a provided or default tolerance. If the tolerance provided is Empty, this method may set it to a default tolerance. The expected value The actual value A reference to the tolerance in effect True if the _values are equal Compare two numeric _values, performing the usual numeric conversions. The expected value The actual value The relationship of the _values to each other FalseConstraint tests that the actual value is false Initializes a new instance of the class. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure TestFixtureAttribute is used to mark a class that represents a TestFixture. The ITestCaseData interface is implemented by a class that is able to return the data required to create an instance of a parameterized test fixture. The ITestData interface is implemented by a class that represents a single instance of a parameterized test. Gets the name to be used for the test Gets the RunState for this test case. Gets the argument list to be provided to the test Gets the property dictionary for the test case Get the TypeArgs if separately set Default constructor Construct with a object[] representing a set of arguments. In .NET 2.0, the arguments may later be separated into type arguments and constructor arguments. Build a fixture from type provided. Normally called for a Type on which the attribute has been placed. The type info of the fixture to be used. A an IEnumerable holding one TestFixture object. Gets or sets the name of the test. The name of the test. Gets or sets the RunState of this test fixture. The arguments originally provided to the attribute Properties pertaining to this fixture Get or set the type arguments. If not set explicitly, any leading arguments that are Types are taken as type arguments. Descriptive text for this fixture The author of this fixture The type that this fixture is testing Gets or sets the ignore reason. May set RunState as a side effect. The ignore reason. Gets or sets the reason for not running the fixture. The reason. Gets or sets the ignore reason. When set to a non-null non-empty value, the test is marked as ignored. The ignore reason. Gets or sets a value indicating whether this is explicit. true if explicit; otherwise, false. Gets and sets the category for this fixture. May be a comma-separated list of categories. TestCaseAttribute is used to mark parameterized test cases and provide them with their arguments. The ITestCaseData interface is implemented by a class that is able to return complete testcases for use by a parameterized test method. Gets the expected result of the test case Returns true if an expected result has been set IImplyFixture is an empty marker interface used by attributes like TestAttribute that cause the class where they are used to be treated as a TestFixture even without a TestFixtureAttribute. Marker interfaces are not usually considered a good practice, but we use it here to avoid cluttering the attribute hierarchy with classes that don't contain any extra implementation. Construct a TestCaseAttribute with a list of arguments. This constructor is not CLS-Compliant Construct a TestCaseAttribute with a single argument Construct a TestCaseAttribute with a two arguments Construct a TestCaseAttribute with a three arguments Performs several special conversions allowed by NUnit in order to permit arguments with types that cannot be used in the constructor of an Attribute such as TestCaseAttribute or to simplify their use. The arguments to be converted The ParameterInfo array for the method Construct one or more TestMethods from a given MethodInfo, using available parameter data. The MethodInfo for which tests are to be constructed. The suite to which the tests will be added. One or more TestMethods Gets or sets the name of the test. The name of the test. Gets or sets the RunState of this test case. Gets the list of arguments to a test case Gets the properties of the test case Gets or sets the expected result. The result. Returns true if the expected result has been set Gets or sets the description. The description. The author of this test The type that this test is testing Gets or sets the reason for ignoring the test Gets or sets a value indicating whether this is explicit. true if explicit; otherwise, false. Gets or sets the reason for not running the test. The reason. Gets or sets the ignore reason. When set to a non-null non-empty value, the test is marked as ignored. The ignore reason. Comma-delimited list of platforms to run the test for Comma-delimited list of platforms to not run the test for Gets and sets the category for this test case. May be a comma-separated list of categories. GenericMethodHelper is able to deduce the Type arguments for a generic method from the actual arguments provided. Construct a GenericMethodHelper for a method MethodInfo for the method to examine Return the type argments for the method, deducing them from the arguments actually provided. The arguments to the method An array of type arguments. TestActionCommand runs the BeforeTest actions for a test, then runs the test and finally runs the AfterTestActions. Initializes a new instance of the class. The inner command. Runs the test, saving a TestResult in the supplied TestExecutionContext. The context in which the test should run. A TestResult Provides internal logging to the NUnit framework Interface for logging within the engine Logs the specified message at the error level. The message. Logs the specified message at the error level. The message. The arguments. Logs the specified message at the warning level. The message. Logs the specified message at the warning level. The message. The arguments. Logs the specified message at the info level. The message. Logs the specified message at the info level. The message. The arguments. Logs the specified message at the debug level. The message. Logs the specified message at the debug level. The message. The arguments. Initializes a new instance of the class. The name. The log level. The writer where logs are sent. Logs the message at error level. The message. Logs the message at error level. The message. The message arguments. Logs the message at warm level. The message. Logs the message at warning level. The message. The message arguments. Logs the message at info level. The message. Logs the message at info level. The message. The message arguments. Logs the message at debug level. The message. Logs the message at debug level. The message. The message arguments. ClassName filter selects tests based on the class FullName Construct a FullNameFilter for a single name The name the filter will recognize. Match a test against a single value. Gets the element name Element name PropertyFilter is able to select or exclude tests based on their properties. Construct a PropertyFilter using a property name and expected value A property name The expected value of the property Check whether the filter matches a test The test to be matched Adds an XML node Parent node True if recursive The added XML node Gets the element name Element name Env is a static class that provides some of the features of System.Environment that are not available under all runtimes The newline sequence in the current environment. Path to the 'My Documents' folder Directory used for file output if not specified on commandline. The Assert class contains a collection of static methods that implement the most common assertions used in NUnit. The Assert class contains a collection of static methods that implement the most common assertions used in NUnit. Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition The message to display in case of failure Array of objects to be used in formatting the message Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition Asserts that a condition is false. If the condition is true the method throws an . The evaluated condition Verifies that the object that is passed in is not equal to null If the object is null then an is thrown. The object that is to be tested The message to display in case of failure Array of objects to be used in formatting the message Verifies that the object that is passed in is not equal to null If the object is null then an is thrown. The object that is to be tested Verifies that the object that is passed in is not equal to null If the object is null then an is thrown. The object that is to be tested The message to display in case of failure Array of objects to be used in formatting the message Verifies that the object that is passed in is not equal to null If the object is null then an is thrown. The object that is to be tested Verifies that the object that is passed in is equal to null If the object is not null then an is thrown. The object that is to be tested The message to display in case of failure Array of objects to be used in formatting the message Verifies that the object that is passed in is equal to null If the object is not null then an is thrown. The object that is to be tested Verifies that the object that is passed in is equal to null If the object is not null then an is thrown. The object that is to be tested The message to display in case of failure Array of objects to be used in formatting the message Verifies that the object that is passed in is equal to null If the object is not null then an is thrown. The object that is to be tested Verifies that the double that is passed in is an NaN value. If the object is not NaN then an is thrown. The value that is to be tested The message to display in case of failure Array of objects to be used in formatting the message Verifies that the double that is passed in is an NaN value. If the object is not NaN then an is thrown. The value that is to be tested Verifies that the double that is passed in is an NaN value. If the object is not NaN then an is thrown. The value that is to be tested The message to display in case of failure Array of objects to be used in formatting the message Verifies that the double that is passed in is an NaN value. If the object is not NaN then an is thrown. The value that is to be tested Assert that a string is empty - that is equal to string.Empty The string to be tested The message to display in case of failure Array of objects to be used in formatting the message Assert that a string is empty - that is equal to string.Empty The string to be tested Assert that an array, list or other collection is empty An array, list or other collection implementing ICollection The message to display in case of failure Array of objects to be used in formatting the message Assert that an array, list or other collection is empty An array, list or other collection implementing ICollection Assert that a string is not empty - that is not equal to string.Empty The string to be tested The message to display in case of failure Array of objects to be used in formatting the message Assert that a string is not empty - that is not equal to string.Empty The string to be tested Assert that an array, list or other collection is not empty An array, list or other collection implementing ICollection The message to display in case of failure Array of objects to be used in formatting the message Assert that an array, list or other collection is not empty An array, list or other collection implementing ICollection Asserts that an int is zero. The number to be examined Asserts that an int is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned int is zero. The number to be examined Asserts that an unsigned int is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a Long is zero. The number to be examined Asserts that a Long is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned Long is zero. The number to be examined Asserts that an unsigned Long is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a decimal is zero. The number to be examined Asserts that a decimal is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a double is zero. The number to be examined Asserts that a double is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a float is zero. The number to be examined Asserts that a float is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an int is not zero. The number to be examined Asserts that an int is not zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned int is not zero. The number to be examined Asserts that an unsigned int is not zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a Long is not zero. The number to be examined Asserts that a Long is not zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned Long is not zero. The number to be examined Asserts that an unsigned Long is not zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a decimal is zero. The number to be examined Asserts that a decimal is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a double is zero. The number to be examined Asserts that a double is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a float is zero. The number to be examined Asserts that a float is zero. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an int is negative. The number to be examined Asserts that an int is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned int is negative. The number to be examined Asserts that an unsigned int is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a Long is negative. The number to be examined Asserts that a Long is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned Long is negative. The number to be examined Asserts that an unsigned Long is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a decimal is negative. The number to be examined Asserts that a decimal is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a double is negative. The number to be examined Asserts that a double is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a float is negative. The number to be examined Asserts that a float is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an int is negative. The number to be examined Asserts that an int is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned int is negative. The number to be examined Asserts that an unsigned int is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a Long is negative. The number to be examined Asserts that a Long is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an unsigned Long is negative. The number to be examined Asserts that an unsigned Long is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a decimal is negative. The number to be examined Asserts that a decimal is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a double is negative. The number to be examined Asserts that a double is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that a float is negative. The number to be examined Asserts that a float is negative. The number to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object may be assigned a value of a given Type. The expected Type. The object under examination The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object may be assigned a value of a given Type. The expected Type. The object under examination Asserts that an object may be assigned a value of a given Type. The expected Type. The object under examination The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object may be assigned a value of a given Type. The expected Type. The object under examination Asserts that an object may not be assigned a value of a given Type. The expected Type. The object under examination The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object may not be assigned a value of a given Type. The expected Type. The object under examination Asserts that an object may not be assigned a value of a given Type. The expected Type. The object under examination The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object may not be assigned a value of a given Type. The expected Type. The object under examination Asserts that an object is an instance of a given type. The expected Type The object being examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object is an instance of a given type. The expected Type The object being examined Asserts that an object is an instance of a given type. The expected Type The object being examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object is an instance of a given type. The expected Type The object being examined Asserts that an object is not an instance of a given type. The expected Type The object being examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object is not an instance of a given type. The expected Type The object being examined Asserts that an object is not an instance of a given type. The expected Type The object being examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object is not an instance of a given type. The expected Type The object being examined Verifies that a delegate throws a particular exception when called. A constraint to be satisfied by the exception A TestSnippet delegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate throws a particular exception when called. A constraint to be satisfied by the exception A TestSnippet delegate Verifies that a delegate throws a particular exception when called. The exception Type expected A TestDelegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate throws a particular exception when called. The exception Type expected A TestDelegate Verifies that a delegate throws a particular exception when called. Type of the expected exception A TestDelegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate throws a particular exception when called. Type of the expected exception A TestDelegate Verifies that a delegate throws an exception when called and returns it. A TestDelegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate throws an exception when called and returns it. A TestDelegate Verifies that a delegate throws an exception of a certain Type or one derived from it when called and returns it. The expected Exception Type A TestDelegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate throws an exception of a certain Type or one derived from it when called and returns it. The expected Exception Type A TestDelegate Verifies that a delegate throws an exception of a certain Type or one derived from it when called and returns it. A TestDelegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate throws an exception of a certain Type or one derived from it when called and returns it. A TestDelegate Verifies that a delegate does not throw an exception A TestDelegate The message that will be displayed on failure Arguments to be used in formatting the message Verifies that a delegate does not throw an exception. A TestDelegate Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition The message to display if the condition is false Arguments to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition A function to build the message included with the Exception Asserts that a condition is true. If the condition is false the method throws an . A lambda that returns a Boolean The message to display if the condition is false Arguments to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . A lambda that returns a Boolean Asserts that a condition is true. If the condition is false the method throws an . A lambda that returns a Boolean A function to build the message included with the Exception Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. The Type being compared. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. The Type being compared. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied The message that will be displayed on failure Arguments to be used in formatting the message Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. The Type being compared. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied A function to build the message included with the Exception Asserts that the code represented by a delegate throws an exception that satisfies the constraint provided. A TestDelegate to be executed A ThrowsConstraint used in the test Asserts that the code represented by a delegate throws an exception that satisfies the constraint provided. A TestDelegate to be executed A ThrowsConstraint used in the test The message that will be displayed on failure Arguments to be used in formatting the message Asserts that the code represented by a delegate throws an exception that satisfies the constraint provided. A TestDelegate to be executed A ThrowsConstraint used in the test A function to build the message included with the Exception Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. The Type being compared. The actual value to test A Constraint to be applied Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. The Type being compared. The actual value to test A Constraint expression to be applied The message that will be displayed on failure Arguments to be used in formatting the message Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. The Type being compared. The actual value to test A Constraint expression to be applied A function to build the message included with the Exception Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. Used as a synonym for That in rare cases where a private setter causes a Visual Basic compilation error. The actual value to test A Constraint to be applied Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. Used as a synonym for That in rare cases where a private setter causes a Visual Basic compilation error. This method is provided for use by VB developers needing to test the value of properties with private setters. The actual value to test A Constraint expression to be applied The message that will be displayed on failure Arguments to be used in formatting the message We don't actually want any instances of this object, but some people like to inherit from it to add other static methods. Hence, the protected constructor disallows any instances of this object. The Equals method throws an InvalidOperationException. This is done to make sure there is no mistake by calling this function. override the default ReferenceEquals to throw an InvalidOperationException. This implementation makes sure there is no mistake in calling this function as part of Assert. Throws a with the message and arguments that are passed in. This allows a test to be cut short, with a result of success returned to NUnit. The message to initialize the with. Arguments to be used in formatting the message Throws a with the message and arguments that are passed in. This allows a test to be cut short, with a result of success returned to NUnit. The message to initialize the with. Throws a with the message and arguments that are passed in. This allows a test to be cut short, with a result of success returned to NUnit. Throws an with the message and arguments that are passed in. This is used by the other Assert functions. The message to initialize the with. Arguments to be used in formatting the message Throws an with the message that is passed in. This is used by the other Assert functions. The message to initialize the with. Throws an . This is used by the other Assert functions. Throws an with the message and arguments that are passed in. This causes the test to be reported as ignored. The message to initialize the with. Arguments to be used in formatting the message Throws an with the message that is passed in. This causes the test to be reported as ignored. The message to initialize the with. Throws an . This causes the test to be reported as ignored. Throws an with the message and arguments that are passed in. This causes the test to be reported as inconclusive. The message to initialize the with. Arguments to be used in formatting the message Throws an with the message that is passed in. This causes the test to be reported as inconclusive. The message to initialize the with. Throws an . This causes the test to be reported as Inconclusive. Asserts that an object is contained in a list. The expected object The list to be examined The message to display in case of failure Array of objects to be used in formatting the message Asserts that an object is contained in a list. The expected object The list to be examined Verifies that the first int is greater than the second int. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first int is greater than the second int. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is greater than or equal to the second value. If it is not, then an is thrown. The first value, expected to be greater The second value, expected to be less Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater The message to display in case of failure Array of objects to be used in formatting the message Verifies that the first value is less than or equal to the second value. If it is not, then an is thrown. The first value, expected to be less The second value, expected to be greater Verifies that two doubles are equal considering a delta. If the expected value is infinity then the delta value is ignored. If they are not equal then an is thrown. The expected value The actual value The maximum acceptable difference between the the expected and the actual The message to display in case of failure Array of objects to be used in formatting the message Verifies that two doubles are equal considering a delta. If the expected value is infinity then the delta value is ignored. If they are not equal then an is thrown. The expected value The actual value The maximum acceptable difference between the the expected and the actual Verifies that two doubles are equal considering a delta. If the expected value is infinity then the delta value is ignored. If they are not equal then an is thrown. The expected value The actual value The maximum acceptable difference between the the expected and the actual The message to display in case of failure Array of objects to be used in formatting the message Verifies that two doubles are equal considering a delta. If the expected value is infinity then the delta value is ignored. If they are not equal then an is thrown. The expected value The actual value The maximum acceptable difference between the the expected and the actual Verifies that two objects are equal. Two objects are considered equal if both are null, or if both have the same value. NUnit has special semantics for some object types. If they are not equal an is thrown. The value that is expected The actual value The message to display in case of failure Array of objects to be used in formatting the message Verifies that two objects are equal. Two objects are considered equal if both are null, or if both have the same value. NUnit has special semantics for some object types. If they are not equal an is thrown. The value that is expected The actual value Verifies that two objects are not equal. Two objects are considered equal if both are null, or if both have the same value. NUnit has special semantics for some object types. If they are equal an is thrown. The value that is expected The actual value The message to display in case of failure Array of objects to be used in formatting the message Verifies that two objects are not equal. Two objects are considered equal if both are null, or if both have the same value. NUnit has special semantics for some object types. If they are equal an is thrown. The value that is expected The actual value Asserts that two objects refer to the same object. If they are not the same an is thrown. The expected object The actual object The message to display in case of failure Array of objects to be used in formatting the message Asserts that two objects refer to the same object. If they are not the same an is thrown. The expected object The actual object Asserts that two objects do not refer to the same object. If they are the same an is thrown. The expected object The actual object The message to display in case of failure Array of objects to be used in formatting the message Asserts that two objects do not refer to the same object. If they are the same an is thrown. The expected object The actual object Helper for Assert.AreEqual(double expected, double actual, ...) allowing code generation to work consistently. The expected value The actual value The maximum acceptable difference between the the expected and the actual The message to display in case of failure Array of objects to be used in formatting the message Represents a constraint that succeeds if all the members of a collection match a base constraint. Abstract base for operators that indicate how to apply a constraint to items in a collection. PrefixOperator takes a single constraint and modifies it's action in some way. Reduce produces a constraint from the operator and any arguments. It takes the arguments from the constraint stack and pushes the resulting constraint on it. Returns the constraint created by applying this prefix to another constraint. Constructs a CollectionOperator Returns a constraint that will apply the argument to the members of a collection, succeeding if they all succeed. FileExistsConstraint is used to determine if a file exists FileOrDirectoryExistsConstraint is used to determine if a file or directory exists Initializes a new instance of the class that will check files and directories. Initializes a new instance of the class that will only check files if ignoreDirectories is true. if set to true [ignore directories]. Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult If true, the constraint will only check if files exist, not directories If true, the constraint will only check if directories exist, not files The Description of what this constraint tests, for use in messages and in the ConstraintResult. Initializes a new instance of the class. The Description of what this constraint tests, for use in messages and in the ConstraintResult. TestAssemblyDirectoryResolveAttribute is used to mark a test assembly as needing a special assembly resolution hook that will explicitly search the test assembly's directory for dependent assemblies. This works around a conflict between mixed-mode assembly initialization and tests running in their own AppDomain in some cases. Helper methods for inspecting a type by reflection. Many of these methods take ICustomAttributeProvider as an argument to avoid duplication, even though certain attributes can only appear on specific types of members, like MethodInfo or Type. In the case where a type is being examined for the presence of an attribute, interface or named member, the Reflect methods operate with the full name of the member being sought. This removes the necessity of the caller having a reference to the assembly that defines the item being sought and allows the NUnit core to inspect assemblies that reference an older version of the NUnit framework. Examine a fixture type and return an array of methods having a particular attribute. The array is order with base methods first. The type to examine The attribute Type to look for Specifies whether to search the fixture type inheritance chain The array of methods found Examine a fixture type and return true if it has a method with a particular attribute. The type to examine The attribute Type to look for True if found, otherwise false Invoke the default constructor on a Type The Type to be constructed An instance of the Type Invoke a constructor on a Type with arguments The Type to be constructed Arguments to the constructor An instance of the Type Returns an array of types from an array of objects. Used because the compact framework doesn't support Type.GetTypeArray() An array of objects An array of Types Invoke a parameterless method returning void on an object. A MethodInfo for the method to be invoked The object on which to invoke the method Invoke a method, converting any TargetInvocationException to an NUnitException. A MethodInfo for the method to be invoked The object on which to invoke the method The argument list for the method The return value from the invoked method Constructor delegate, makes it possible to use a factory to create objects InvalidTestFixtureException is thrown when an appropriate test fixture constructor using the provided arguments cannot be found. Initializes a new instance of the class. Initializes a new instance of the class. The message. Initializes a new instance of the class. The message. The inner. Serialization Constructor Class to build ether a parameterized or a normal NUnitTestMethod. There are four cases that the builder must deal with: 1. The method needs no params and none are provided 2. The method needs params and they are provided 3. The method needs no params but they are provided in error 4. The method needs params but they are not provided This could have been done using two different builders, but it turned out to be simpler to have just one. The BuildFrom method takes a different branch depending on whether any parameters are provided, but all four cases are dealt with in lower-level methods The ITestCaseBuilder interface is exposed by a class that knows how to build a test case from certain methods. This interface is not the same as the ITestCaseBuilder interface in NUnit 2.x. We have reused the name because the two products don't interoperate at all. Examine the method and determine if it is suitable for this builder to use in building a TestCase to be included in the suite being populated. Note that returning false will cause the method to be ignored in loading the tests. If it is desired to load the method but label it as non-runnable, ignored, etc., then this method must return true. The test method to examine The suite being populated True is the builder can use this method Build a TestCase from the provided MethodInfo for inclusion in the suite being constructed. The method to be used as a test case The test suite being populated, or null A TestCase or null Determines if the method can be used to build an NUnit test test method of some kind. The method must normally be marked with an identifying attribute for this to be true. Note that this method does not check that the signature of the method for validity. If we did that here, any test methods with invalid signatures would be passed over in silence in the test run. Since we want such methods to be reported, the check for validity is made in BuildFrom rather than here. An IMethodInfo for the method being used as a test method True if the builder can create a test case from this method Build a Test from the provided MethodInfo. Depending on whether the method takes arguments and on the availability of test case data, this method may return a single test or a group of tests contained in a ParameterizedMethodSuite. The method for which a test is to be built A Test representing one or more method invocations Determines if the method can be used to build an NUnit test test method of some kind. The method must normally be marked with an identifying attribute for this to be true. Note that this method does not check that the signature of the method for validity. If we did that here, any test methods with invalid signatures would be passed over in silence in the test run. Since we want such methods to be reported, the check for validity is made in BuildFrom rather than here. An IMethodInfo for the method being used as a test method The test suite being built, to which the new test would be added True if the builder can create a test case from this method Build a Test from the provided MethodInfo. Depending on whether the method takes arguments and on the availability of test case data, this method may return a single test or a group of tests contained in a ParameterizedMethodSuite. The method for which a test is to be built The test fixture being populated, or null A Test representing one or more method invocations Builds a ParameterizedMethodSuite containing individual test cases. The method for which a test is to be built. The list of test cases to include. A ParameterizedMethodSuite populated with test cases Build a simple, non-parameterized TestMethod for this method. The MethodInfo for which a test is to be built The test suite for which the method is being built A TestMethod. Abstract base class for operators that are able to reduce to a constraint whether or not another syntactic element follows. NUnitEqualityComparer encapsulates NUnit's handling of equality tests between objects. If true, all string comparisons will ignore case If true, arrays will be treated as collections, allowing those of different dimensions to be compared Comparison objects used in comparisons for some constraints. List of points at which a failure occurred. Compares two objects for equality within a tolerance. Helper method to compare two arrays Method to compare two DirectoryInfo objects first directory to compare second directory to compare true if equivalent, false if not Returns the default NUnitEqualityComparer Gets and sets a flag indicating whether case should be ignored in determining equality. Gets and sets a flag indicating that arrays should be compared as collections, without regard to their shape. Gets the list of external comparers to be used to test for equality. They are applied to members of collections, in place of NUnit's own logic. Gets the list of failure points for the last Match performed. The list consists of objects to be interpreted by the caller. This generally means that the caller may only make use of objects it has placed on the list at a particular depthy. Flags the comparer to include property in comparison of two values. Using this modifier does not allow to use the modifier. FailurePoint class represents one point of failure in an equality test. The location of the failure The expected value The actual value Indicates whether the expected value is valid Indicates whether the actual value is valid NullConstraint tests that the actual value is null Initializes a new instance of the class. Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult CollectionSubsetConstraint is used to determine whether one collection is a subset of another Construct a CollectionSubsetConstraint The collection that the actual value is expected to be a subset of Test whether the actual collection is a subset of the expected collection provided. Flag the constraint to use the supplied predicate function The comparison function to use. Self. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. AndConstraint succeeds only if both members succeed. BinaryConstraint is the abstract base of all constraints that combine two other constraints in some fashion. The first constraint being combined The second constraint being combined Construct a BinaryConstraint from two other constraints The first constraint The second constraint Create an AndConstraint from two other constraints The first constraint The second constraint Apply both member constraints to an actual value, succeeding succeeding only if both of them succeed. The actual value True if the constraints both succeeded Gets text describing a constraint Contain the result of matching a against an actual value. Constructs a for a particular . The Constraint to which this result applies. The actual value to which the Constraint was applied. Constructs a for a particular . The Constraint to which this result applies. The actual value to which the Constraint was applied. The status of the new ConstraintResult. Constructs a for a particular . The Constraint to which this result applies. The actual value to which the Constraint was applied. If true, applies a status of Success to the result, otherwise Failure. Write the failure message to the MessageWriter provided as an argument. The default implementation simply passes the result and the actual value to the writer, which then displays the constraint description and the value. Constraints that need to provide additional details, such as where the error occured can override this. The MessageWriter on which to display the message Write the actual value for a failing constraint test to a MessageWriter. The default implementation simply writes the raw value of actual, leaving it to the writer to perform any formatting. The writer on which the actual value is displayed The actual value that was passed to the method. Gets and sets the ResultStatus for this result. True if actual value meets the Constraint criteria otherwise false. Display friendly name of the constraint. Description of the constraint may be affected by the state the constraint had when was performed against the actual value. Write the actual value for a failing constraint test to a MessageWriter. The default implementation simply writes the raw value of actual, leaving it to the writer to perform any formatting. The writer on which the actual value is displayed Attribute used to identify a method that is called after all the tests in a fixture have run. The method is guaranteed to be called, even if an exception is thrown. Attribute used to identify a method that is called once after all the child tests have run. The method is guaranteed to be called, even if an exception is thrown. PlatformAttribute is used to mark a test fixture or an individual method as applying to a particular platform only. Constructor with no platforms specified, for use with named property syntax. Constructor taking one or more platforms Comma-delimited list of platforms Causes a test to be skipped if this PlatformAttribute is not satisfied. The test to modify Attribute used to mark a test that is to be ignored. Ignored tests result in a warning message when the tests are run. Constructs the attribute giving a reason for ignoring the test GetActionsFromAttributeProvider The reason for ignoring the test Modifies a test by marking it as Ignored. The test to modify The date in the future to stop ignoring the test as a string in UTC time. For example for a date and time, "2014-12-25 08:10:00Z" or for just a date, "2014-12-25". If just a date is given, the Ignore will expire at midnight UTC. Once the ignore until date has passed, the test will be marked as runnable. Tests with an ignore until date will have an IgnoreUntilDate property set which will appear in the test results. The string does not contain a valid string representation of a date and time. The IApplyToContext interface is implemented by attributes that want to make changes to the execution context before a test is run. Apply changes to the execution context The execution context A SimpleWorkItem represents a single test case and is marked as completed immediately upon execution. This class is also used for skipped or ignored test suites. Construct a simple work item for a test. The test to be executed The filter used to select this test Method that performs actually performs the work. ContextSettingsCommand applies specified changes to the TestExecutionContext prior to running a test. No special action is needed after the test runs, since the prior context will be restored automatically. Initializes a new instance of the class. The RunState enum indicates whether a test can be executed. The test is not runnable. The test is runnable. The test can only be run explicitly The test has been skipped. This value may appear on a Test when certain attributes are used to skip the test. The test has been ignored. May appear on a Test, when the IgnoreAttribute is used. Helper class with properties and methods that supply a number of constraints used in Asserts. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a new ContainsConstraint. This constraint will, in turn, make use of the appropriate second-level constraint, depending on the type of the actual argument. This overload is only used if the item sought is a string, since any other type implies that we are looking for a collection member. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a ConstraintExpression that negates any following constraint. Returns a constraint that succeeds if the value is a file or directory and it exists. AssemblyHelper provides static methods for working with assemblies. Gets the path from which an assembly was loaded. For builds where this is not possible, returns the name of the assembly. The assembly. The path. Gets the path to the directory from which an assembly was loaded. The assembly. The path. Gets the AssemblyName of an assembly. The assembly An AssemblyName Loads an assembly given a string, which may be the path to the assembly or the AssemblyName Gets the assembly path from code base. Public for testing purposes The code base. FrameworkController provides a facade for use in loading, browsing and running tests without requiring a reference to the NUnit framework. All calls are encapsulated in constructors for this class and its nested classes, which only require the types of the Common Type System as arguments. The controller supports four actions: Load, Explore, Count and Run. They are intended to be called by a driver, which should allow for proper sequencing of calls. Load must be called before any of the other actions. The driver may support other actions, such as reload on run, by combining these calls. A MarshalByRefObject that lives forever Obtains a lifetime service object to control the lifetime policy for this instance. Construct a FrameworkController using the default builder and runner. The AssemblyName or path to the test assembly A prefix used for all test ids created under this controller. A Dictionary of settings to use in loading and running the tests Construct a FrameworkController using the default builder and runner. The test assembly A prefix used for all test ids created under this controller. A Dictionary of settings to use in loading and running the tests Construct a FrameworkController, specifying the types to be used for the runner and builder. This constructor is provided for purposes of development. The full AssemblyName or the path to the test assembly A prefix used for all test ids created under this controller. A Dictionary of settings to use in loading and running the tests The Type of the test runner The Type of the test builder Construct a FrameworkController, specifying the types to be used for the runner and builder. This constructor is provided for purposes of development. The test assembly A prefix used for all test ids created under this controller. A Dictionary of settings to use in loading and running the tests The Type of the test runner The Type of the test builder Loads the tests in the assembly Returns info about the tests in an assembly A string containing the XML representation of the filter to use The XML result of exploring the tests Runs the tests in an assembly A string containing the XML representation of the filter to use The XML result of the test run Runs the tests in an assembly syncronously reporting back the test results through the callback or through the return value The callback that receives the test results A string containing the XML representation of the filter to use The XML result of the test run Runs the tests in an assembly asyncronously reporting back the test results through the callback The callback that receives the test results A string containing the XML representation of the filter to use Stops the test run True to force the stop, false for a cooperative stop Counts the number of test cases in the loaded TestSuite A string containing the XML representation of the filter to use The number of tests Inserts environment element Target node The new node Inserts settings element Target node Settings dictionary The new node Gets the ITestAssemblyBuilder used by this controller instance. The builder. Gets the ITestAssemblyRunner used by this controller instance. The runner. Gets the AssemblyName or the path for which this FrameworkController was created Gets the Assembly for which this Gets a dictionary of settings for the FrameworkController A shim of the .NET interface for platforms that do not support it. Used to indicate that a control can be the target of a callback event on the server. Processes a callback event that targets a control. Returns the results of a callback event that targets a control. FrameworkControllerAction is the base class for all actions performed against a FrameworkController. LoadTestsAction loads a test into the FrameworkController LoadTestsAction loads the tests in an assembly. The controller. The callback handler. ExploreTestsAction returns info about the tests in an assembly Initializes a new instance of the class. The controller for which this action is being performed. Filter used to control which tests are included (NYI) The callback handler. CountTestsAction counts the number of test cases in the loaded TestSuite held by the FrameworkController. Construct a CountsTestAction and perform the count of test cases. A FrameworkController holding the TestSuite whose cases are to be counted A string containing the XML representation of the filter to use A callback handler used to report results RunTestsAction runs the loaded TestSuite held by the FrameworkController. Construct a RunTestsAction and run all tests in the loaded TestSuite. A FrameworkController holding the TestSuite to run A string containing the XML representation of the filter to use A callback handler used to report results RunAsyncAction initiates an asynchronous test run, returning immediately Construct a RunAsyncAction and run all tests in the loaded TestSuite. A FrameworkController holding the TestSuite to run A string containing the XML representation of the filter to use A callback handler used to report results StopRunAction stops an ongoing run. Construct a StopRunAction and stop any ongoing run. If no run is in process, no error is raised. The FrameworkController for which a run is to be stopped. True the stop should be forced, false for a cooperative stop. >A callback handler used to report results A forced stop will cause threads and processes to be killed as needed. ExceptionTypeConstraint is a special version of ExactTypeConstraint used to provided detailed info about the exception thrown in an error message. ExactTypeConstraint is used to test that an object is of the exact type provided in the constructor Construct an ExactTypeConstraint for a given Type The expected Type. Apply the constraint to an actual value, returning true if it succeeds The actual argument True if the constraint succeeds, otherwise false. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. Constructs an ExceptionTypeConstraint Applies the constraint to an actual value, returning a ConstraintResult. The value to be tested A ConstraintResult TestProgressReporter translates ITestListener events into the async callbacks that are used to inform the client software about the progress of a test run. Initializes a new instance of the class. The callback handler to be used for reporting progress. Called when a test has just started The test that is starting Called when a test has finished. Sends a result summary to the callback. to The result of the test Called when a test produces output for immediate display A TestOutput object containing the text to display Returns the parent test item for the targer test item if it exists parent test item Makes a string safe for use as an attribute, replacing characters characters that can't be used with their corresponding xml representations. The string to be used A new string with the _values replaced Operator used to test for the presence of a named Property on an object and optionally apply further tests to the value of that property. Constructs a PropOperator for a particular named property Reduce produces a constraint from the operator and any arguments. It takes the arguments from the constraint stack and pushes the resulting constraint on it. Gets the name of the property to which the operator applies NaNConstraint tests that the actual value is a double or float NaN Test that the actual value is an NaN The Description of what this constraint tests, for use in messages and in the ConstraintResult. CollectionContainsConstraint is used to test whether a collection contains an expected object as a member. Construct a CollectionContainsConstraint Test whether the expected item is contained in the collection Flag the constraint to use the supplied predicate function The comparison function to use. Self. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. Gets the expected object Attribute used to mark a class that contains one-time SetUp and/or TearDown methods that apply to all the tests in a namespace or an assembly. Attribute used to mark a class that contains one-time SetUp and/or TearDown methods that apply to all the tests in a namespace or an assembly. Attribute used to mark a class that contains one-time SetUp and/or TearDown methods that apply to all the tests in a namespace or an assembly. RepeatAttribute may be applied to test case in order to run it multiple times. Construct a RepeatAttribute The number of times to run the test Wrap a command and return the result. The command to be wrapped The wrapped command The test command for the RepeatAttribute Initializes a new instance of the class. The inner command. The number of repetitions Runs the test, saving a TestResult in the supplied TestExecutionContext. The context in which the test should run. A TestResult A simplified implementation of .NET 4 CountdownEvent for use in earlier versions of .NET. Only the methods used by NUnit are implemented. Construct a CountdownEvent The initial count Decrement the count by one Block the thread until the count reaches zero Gets the initial count established for the CountdownEvent Gets the current count remaining for the CountdownEvent TheoryResultCommand adjusts the result of a Theory so that it fails if all the results were inconclusive. Constructs a TheoryResultCommand The command to be wrapped by this one Overridden to call the inner command and adjust the result in case all chlid results were inconclusive. NUnitTestCaseBuilder is a utility class used by attributes that build test cases. Constructs an Builds a single NUnitTestMethod, either as a child of the fixture or as one of a set of test cases under a ParameterizedTestMethodSuite. The MethodInfo from which to construct the TestMethod The suite or fixture to which the new test will be added The ParameterSet to be used, or null Helper method that checks the signature of a TestMethod and any supplied parameters to determine if the test is valid. Currently, NUnitTestMethods are required to be public, non-abstract methods, either static or instance, returning void. They may take arguments but the _values must be provided or the TestMethod is not considered runnable. Methods not meeting these criteria will be marked as non-runnable and the method will return false in that case. The TestMethod to be checked. If it is found to be non-runnable, it will be modified. Parameters to be used for this test, or null True if the method signature is valid, false if not The return value is no longer used internally, but is retained for testing purposes. The TestStatus enum indicates the result of running a test The test was inconclusive The test has skipped The test succeeded The test failed TestNameGenerator is able to create test names according to a coded pattern. Default pattern used to generate names Construct a TestNameGenerator Construct a TestNameGenerator The pattern used by this generator. Get the display name for a TestMethod and it's arguments A TestMethod The display name Get the display name for a TestMethod and it's arguments A TestMethod Arguments to be used The display name The EqualConstraintResult class is tailored for formatting and displaying the result of an EqualConstraint. Construct an EqualConstraintResult Write a failure message. Overridden to provide custom failure messages for EqualConstraint. The MessageWriter to write to Display the failure information for two collections that did not match. The MessageWriter on which to display The expected collection. The actual collection The depth of this failure in a set of nested collections Displays a single line showing the types and sizes of the expected and actual collections or arrays. If both are identical, the value is only shown once. The MessageWriter on which to display The expected collection or array The actual collection or array The indentation level for the message line Displays a single line showing the point in the expected and actual arrays at which the comparison failed. If the arrays have different structures or dimensions, both _values are shown. The MessageWriter on which to display The expected array The actual array Index of the failure point in the underlying collections The indentation level for the message line Display the failure information for two IEnumerables that did not match. The MessageWriter on which to display The expected enumeration. The actual enumeration The depth of this failure in a set of nested collections Provides NUnit specific extensions to aid in Reflection across multiple frameworks This version of the class supplies GetTypeInfo() on platforms that don't support it. GetTypeInfo gives access to most of the Type information we take for granted on .NET Core and Windows Runtime. Rather than #ifdef different code for different platforms, it is easiest to just code all platforms as if they worked this way, thus the simple passthrough. Extensions for Assembly that are not available in pre-4.5 .NET releases An easy way to get a single custom attribute from an assembly The attribute Type The assembly An attribute of Type T Type extensions that apply to all target frameworks Determines if the given array is castable/matches the array. Determines if one type can be implicitly converted from another This class is used as a flag when we get a parameter list for a method/constructor, but we do not know one of the types because null was passed in. The TestCaseData class represents a set of arguments and other parameter info to be used for a parameterized test case. It is derived from TestCaseParameters and adds a fluent syntax for use in initializing the test case. The TestCaseParameters class encapsulates method arguments and other selected parameters needed for constructing a parameterized test case. TestParameters is the abstract base class for all classes that know how to provide data for constructing a test. Default Constructor creates an empty parameter set Construct a parameter set with a list of arguments Construct a non-runnable ParameterSet, specifying the provider exception that made it invalid. Construct a ParameterSet from an object implementing ITestData Applies ParameterSet _values to the test itself. A test. The RunState for this set of parameters. The arguments to be used in running the test, which must match the method signature. A name to be used for this test case in lieu of the standard generated name containing the argument list. Gets the property dictionary for this test The original arguments provided by the user, used for display purposes. The expected result to be returned Default Constructor creates an empty parameter set Construct a non-runnable ParameterSet, specifying the provider exception that made it invalid. Construct a parameter set with a list of arguments Construct a ParameterSet from an object implementing ITestCaseData The expected result of the test, which must match the method return type. Gets a value indicating whether an expected result was specified. Initializes a new instance of the class. The arguments. Initializes a new instance of the class. The argument. Initializes a new instance of the class. The first argument. The second argument. Initializes a new instance of the class. The first argument. The second argument. The third argument. Sets the expected result for the test The expected result A modified TestCaseData Sets the name of the test case The modified TestCaseData instance Sets the description for the test case being constructed. The description. The modified TestCaseData instance. Applies a category to the test Applies a named property to the test Applies a named property to the test Applies a named property to the test Marks the test case as explicit. Marks the test case as explicit, specifying the reason. Ignores this TestCase, specifying the reason. The reason. Gets or sets the current test The time the current test started execution The time the current test started in Ticks Gets or sets the current test result Gets a TextWriter that will send output to the current test result. The current test object - that is the user fixture object on which tests are being executed. Get or set the working directory Get or set indicator that run should stop on the first error Gets an enum indicating whether a stop has been requested. The current WorkItemDispatcher. Made public for use by nunitlite.tests The ParallelScope to be used by tests running in this context. For builds with out the parallel feature, it has no effect. The unique name of the worker that spawned the context. For builds with out the parallel feature, it is null. Gets the RandomGenerator specific to this Test Gets or sets the test case timeout value Gets a list of ITestActions set by upstream tests Saves or restores the CurrentCulture Saves or restores the CurrentUICulture The current head of the ValueFormatter chain, copied from MsgUtils.ValueFormatter If true, all tests must run on the same thread. No new thread may be spawned. Helper class used to save and restore certain static or singleton settings in the environment that affect tests or which might be changed by the user tests. An internal class is used to hold settings and a stack of these objects is pushed and popped as Save and Restore are called. Link to a prior saved context Indicates that a stop has been requested The event listener currently receiving notifications The number of assertions for the current test The current culture The current UI culture The current test result The current Principal. Initializes a new instance of the class. Initializes a new instance of the class. An existing instance of TestExecutionContext. Get the current context or return null if none is found. Clear the current context. This is provided to prevent "leakage" of the CallContext containing the current context back to any runners. Record any changes in the environment made by the test code in the execution context so it will be passed on to lower level tests. Set up the execution environment to match a context. Note that we may be running on the same thread where the context was initially created or on a different thread. Increments the assert count by one. Increments the assert count by a specified amount. Adds a new ValueFormatterFactory to the chain of formatters The new factory Obtain lifetime service object Gets and sets the current context. Gets or sets the current test The time the current test started execution The time the current test started in Ticks Gets or sets the current test result Gets a TextWriter that will send output to the current test result. The current test object - that is the user fixture object on which tests are being executed. Get or set the working directory Get or set indicator that run should stop on the first error Gets an enum indicating whether a stop has been requested. The current test event listener The current WorkItemDispatcher. Made public for use by nunitlite.tests The ParallelScope to be used by tests running in this context. For builds with out the parallel feature, it has no effect. The unique name of the worker that spawned the context. For builds with out the parallel feature, it is null. Gets the RandomGenerator specific to this Test Gets the assert count. The assert count. Gets or sets the test case timeout value Gets a list of ITestActions set by upstream tests Saves or restores the CurrentCulture Saves or restores the CurrentUICulture Gets or sets the current for the Thread. The current head of the ValueFormatter chain, copied from MsgUtils.ValueFormatter If true, all tests must run on the same thread. No new thread may be spawned. Thrown when a test executes inconclusively. Abstract base for Exceptions that terminate a test and provide a ResultState. The error message that explains the reason for the exception The error message that explains the reason for the exception The exception that caused the current exception Serialization Constructor Gets the ResultState provided by this exception The error message that explains the reason for the exception The error message that explains the reason for the exception The exception that caused the current exception Serialization Constructor Gets the ResultState provided by this exception Helper class with properties and methods that supply a number of constraints used in Asserts. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a new DictionaryContainsKeyConstraint checking for the presence of a particular key in the dictionary. Returns a new DictionaryContainsValueConstraint checking for the presence of a particular value in the dictionary. Returns a constraint that succeeds if the actual value contains the substring supplied as an argument. EqualConstraint is able to compare an actual value with the expected value provided in its constructor. Two objects are considered equal if both are null, or if both have the same value. NUnit has special semantics for some object types. NUnitEqualityComparer used to test equality. Initializes a new instance of the class. The expected value. Flag the constraint to use a tolerance when determining equality. Tolerance value to be used Self. Flag the constraint to use the supplied IComparer object. The IComparer object to use. Self. Flag the constraint to use the supplied IComparer object. The IComparer object to use. Self. Flag the constraint to use the supplied Comparison object. The IComparer object to use. Self. Flag the constraint to use the supplied IEqualityComparer object. The IComparer object to use. Self. Flag the constraint to use the supplied IEqualityComparer object. The IComparer object to use. Self. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Gets the tolerance for this comparison. The tolerance. Gets a value indicating whether to compare case insensitive. true if comparing case insensitive; otherwise, false. Gets a value indicating whether or not to clip strings. true if set to clip strings otherwise, false. Gets the failure points. The failure points. Flag the constraint to ignore case and return self. Flag the constraint to suppress string clipping and return self. Flag the constraint to compare arrays as collections and return self. Flags the constraint to include property in comparison of two values. Using this modifier does not allow to use the constraint modifier. Switches the .Within() modifier to interpret its tolerance as a distance in representable _values (see remarks). Self. Ulp stands for "unit in the last place" and describes the minimum amount a given value can change. For any integers, an ulp is 1 whole digit. For floating point _values, the accuracy of which is better for smaller numbers and worse for larger numbers, an ulp depends on the size of the number. Using ulps for comparison of floating point results instead of fixed tolerances is safer because it will automatically compensate for the added inaccuracy of larger numbers. Switches the .Within() modifier to interpret its tolerance as a percentage that the actual _values is allowed to deviate from the expected value. Self Causes the tolerance to be interpreted as a TimeSpan in days. Self Causes the tolerance to be interpreted as a TimeSpan in hours. Self Causes the tolerance to be interpreted as a TimeSpan in minutes. Self Causes the tolerance to be interpreted as a TimeSpan in seconds. Self Causes the tolerance to be interpreted as a TimeSpan in milliseconds. Self Causes the tolerance to be interpreted as a TimeSpan in clock ticks. Self The Description of what this constraint tests, for use in messages and in the ConstraintResult. Applies a delay to the match so that a match can be evaluated in the future. Creates a new DelayedConstraint The inner constraint to decorate The time interval after which the match is performed If the value of is less than 0 Creates a new DelayedConstraint The inner constraint to decorate The time interval after which the match is performed, in milliseconds The time interval used for polling, in milliseconds If the value of is less than 0 Test whether the constraint is satisfied by a given value The value to be tested True for if the base constraint fails, false if it succeeds Test whether the constraint is satisfied by a delegate The delegate whose value is to be tested A ConstraintResult Test whether the constraint is satisfied by a given reference. Overridden to wait for the specified delay period before calling the base constraint with the dereferenced value. A reference to the value to be tested True for success, false for failure Returns the string representation of the constraint. Adjusts a Timestamp by a given TimeSpan Returns the difference between two Timestamps as a TimeSpan Gets text describing a constraint CollectionOrderedConstraint is used to test whether a collection is ordered. Construct a CollectionOrderedConstraint Modifies the constraint to use an and returns self. Modifies the constraint to use an and returns self. Modifies the constraint to use a and returns self. Modifies the constraint to test ordering by the value of a specified property and returns self. Test whether the collection is ordered Returns the string representation of the constraint. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. If used performs a default ascending comparison If used performs a reverse comparison Then signals a break between two ordering steps The Description of what this constraint tests, for use in messages and in the ConstraintResult. An OrderingStep represents one stage of the sort Attribute used to provide descriptive text about a test case or fixture. Construct a description Attribute The text of the description InvalidTestFixtureException is thrown when an appropriate test fixture constructor using the provided arguments cannot be found. Initializes a new instance of the class. Initializes a new instance of the class. The message. Initializes a new instance of the class. The message. The inner. Serialization Constructor A CompositeWorkItem represents a test suite and encapsulates the execution of the suite as well as all its child tests. A count of how many tests in the work item have a value for the Order Property Construct a CompositeWorkItem for executing a test suite using a filter to select child tests. The TestSuite to be executed A filter used to select child tests Method that actually performs the work. Overridden in CompositeWorkItem to do setup, run all child items and then do teardown. Sorts tests under this suite. Cancel (abort or stop) a CompositeWorkItem and all of its children true if the CompositeWorkItem and all of its children should be aborted, false if it should allow all currently running tests to complete List of Child WorkItems Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other. A signed integer that indicates the relative values of and , as shown in the following table.Value Meaning Less than zero is less than .Zero equals .Greater than zero is greater than . The first object to compare.The second object to compare. The ISimpleTestBuilder interface is exposed by a class that knows how to build a single TestMethod from a suitable MethodInfo Types. In general, it is exposed by an attribute, but may be implemented in a helper class used by the attribute in some cases. Build a TestMethod from the provided MethodInfo. The method to be used as a test The TestSuite to which the method will be added A TestMethod object The TypeWrapper class wraps a Type so it may be used in a platform-independent manner. Construct a TypeWrapper for a specified Type. Returns true if the Type wrapped is T Get the display name for this type Get the display name for an object of this type, constructed with the specified args. Returns a new ITypeInfo representing an instance of this generic Type using the supplied Type arguments Returns a Type representing a generic type definition from which this Type can be constructed. Returns an array of custom attributes of the specified type applied to this type Returns a value indicating whether the type has an attribute of the specified type. Returns a flag indicating whether this type has a method with an attribute of the specified type. Returns an array of IMethodInfos for methods of this Type that match the specified flags. Gets the public constructor taking the specified argument Types Returns a value indicating whether this Type has a public constructor taking the specified argument Types. Construct an object of this Type, using the specified arguments. Override ToString() so that error messages in NUnit's own tests make sense Gets the underlying Type on which this TypeWrapper is based. Gets the base type of this type as an ITypeInfo Gets the Name of the Type Gets the FullName of the Type Gets the assembly in which the type is declared Gets the namespace of the Type Gets a value indicating whether the type is abstract. Gets a value indicating whether the Type is a generic Type Gets a value indicating whether the Type has generic parameters that have not been replaced by specific Types. Gets a value indicating whether the Type is a generic Type definition Gets a value indicating whether the type is sealed. Gets a value indicating whether this type represents a static class. DictionaryContainsValueConstraint is used to test whether a dictionary contains an expected object as a value. Construct a DictionaryContainsValueConstraint Test whether the expected value is contained in the dictionary The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. TestCaseSourceAttribute indicates the source to be used to provide test fixture instances for a test class. Error message string is public so the tests can use it Construct with the name of the method, property or field that will provide data The name of a static method, property or field that will provide data. Construct with a Type and name The Type that will provide data The name of a static method, property or field that will provide data. Construct with a Type The type that will provide data Construct one or more TestFixtures from a given Type, using available parameter data. The TypeInfo for which fixures are to be constructed. One or more TestFixtures as TestSuite Returns a set of ITestFixtureData items for use as arguments to a parameterized test fixture. The type for which data is needed. The name of a the method, property or fiend to be used as a source A Type to be used as a source Gets or sets the category associated with every fixture created from this attribute. May be a single category or a comma-separated list. Attribute used to identify a method that is called once to perform setup before any child tests are run. Provides the Author of a test or test fixture. Initializes a new instance of the class. The name of the author. Initializes a new instance of the class. The name of the author. The email address of the author. The different targets a test action attribute can be applied to Default target, which is determined by where the action attribute is attached Target a individual test case Target a suite of test cases TestListener provides an implementation of ITestListener that does nothing. It is used only through its NULL property. Called when a test has just started The test that is starting Called when a test case has finished The result of the test Called when a test produces output for immediate display A TestOutput object containing the text to display Construct a new TestListener - private so it may not be used. Get a listener that does nothing PlatformHelper class is used by the PlatformAttribute class to determine whether a platform is supported. Comma-delimited list of all supported OS platform constants Comma-delimited list of all supported Runtime platform constants Default constructor uses the operating system and common language runtime of the system. Construct a PlatformHelper for a particular operating system and common language runtime. Used in testing. OperatingSystem to be used RuntimeFramework to be used Test to determine if one of a collection of platforms is being used currently. Tests to determine if the current platform is supported based on a platform attribute. The attribute to examine Tests to determine if the current platform is supported based on a platform attribute. The attribute to examine Test to determine if the a particular platform or comma- delimited set of platforms is in use. Name of the platform or comma-separated list of platform ids True if the platform is in use on the system Return the last failure reason. Results are not defined if called before IsSupported( Attribute ) is called. DefaultTestAssemblyBuilder loads a single assembly and builds a TestSuite containing test fixtures present in the assembly. The default suite builder used by the test assembly builder. Initializes a new instance of the class. Build a suite of tests from a provided assembly The assembly from which tests are to be built A dictionary of options to use in building the suite A TestSuite containing the tests found in the assembly Build a suite of tests given the filename of an assembly The filename of the assembly from which tests are to be built A dictionary of options to use in building the suite A TestSuite containing the tests found in the assembly Helper class with properties and methods that supply a number of constraints used in Asserts. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding only if a specified number of them succeed. Returns a new PropertyConstraintExpression, which will either test for the existence of the named property on the object being tested or apply any following constraint to that property. Returns a new AttributeConstraint checking for the presence of a particular attribute on an object. Returns a new AttributeConstraint checking for the presence of a particular attribute on an object. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a ConstraintExpression that negates any following constraint. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them succeed. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if at least one of them succeeds. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them fail. Returns a new ConstraintExpression, which will apply the following constraint to the Length property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the Count property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the Message property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the InnerException property of the object being tested. EmptyConstraint tests a whether a string or collection is empty, postponing the decision about which test is applied until the type of the actual argument is known. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. ComparisonAdapter class centralizes all comparisons of _values in NUnit, adapting to the use of any provided , or . Returns a ComparisonAdapter that wraps an Returns a ComparisonAdapter that wraps an Returns a ComparisonAdapter that wraps a Compares two objects Gets the default ComparisonAdapter, which wraps an NUnitComparer object. Construct a ComparisonAdapter for an Compares two objects Construct a default ComparisonAdapter ComparerAdapter extends and allows use of an or to actually perform the comparison. Construct a ComparisonAdapter for an Compare a Type T to an object Construct a ComparisonAdapter for a Compare a Type T to an object AssignableFromConstraint is used to test that an object can be assigned from a given Type. Construct an AssignableFromConstraint for the type provided Apply the constraint to an actual value, returning true if it succeeds The actual argument True if the constraint succeeds, otherwise false. Marks a test to use a Sequential join of any argument data provided. Arguments will be combined into test cases, taking the next value of each argument until all are used. Default constructor RangeAttribute is used to supply a range of _values to an individual parameter of a parameterized test. Construct a range of ints using default step of 1 Construct a range of ints specifying the step size Construct a range of unsigned ints using default step of 1 Construct a range of unsigned ints specifying the step size Construct a range of longs using a default step of 1 Construct a range of longs Construct a range of unsigned longs using default step of 1 Construct a range of unsigned longs specifying the step size Construct a range of doubles Construct a range of floats Used to mark a field, property or method providing a set of datapoints to be used in executing any theories within the same fixture that require an argument of the Type provided. The data source may provide an array of the required Type or an . Synonymous with DatapointsAttribute. StackFilter class is used to remove internal NUnit entries from a stack trace so that the resulting trace provides better information about the test. Filters a raw stack trace and returns the result. The original stack trace A filtered stack trace A utility class to create TestCommands Gets the command to be executed before any of the child tests are run. A TestCommand Gets the command to be executed after all of the child tests are run. A TestCommand Creates a test command for use in running this test. Creates a command for skipping a test. The result returned will depend on the test RunState. Builds the set up tear down list. Type of the fixture. Type of the set up attribute. Type of the tear down attribute. A list of SetUpTearDownItems The ParameterWrapper class wraps a ParameterInfo so that it may be used in a platform-independent manner. The IParameterInfo interface is an abstraction of a .NET parameter. Gets a value indicating whether the parameter is optional Gets an IMethodInfo representing the method for which this is a parameter Gets the underlying .NET ParameterInfo Gets the Type of the parameter Construct a ParameterWrapper for a given method and parameter Returns an array of custom attributes of the specified type applied to this method Gets a value indicating whether one or more attributes of the specified type are defined on the parameter. Gets a value indicating whether the parameter is optional Gets an IMethodInfo representing the method for which this is a parameter. Gets the underlying ParameterInfo Gets the Type of the parameter A trace listener that writes to a separate file per domain and process using it. Construct an InternalTraceWriter that writes to a file. Path to the file to use Construct an InternalTraceWriter that writes to a TextWriter provided by the caller. Writes a character to the text string or stream. The character to write to the text stream. Writes a string to the text string or stream. The string to write. Writes a string followed by a line terminator to the text string or stream. The string to write. If is null, only the line terminator is written. Releases the unmanaged resources used by the and optionally releases the managed resources. true to release both managed and unmanaged resources; false to release only unmanaged resources. Clears all buffers for the current writer and causes any buffered data to be written to the underlying device. Returns the character encoding in which the output is written. The character encoding in which the output is written. FullName filter selects tests based on their FullName Construct a MethodNameFilter for a single name The name the filter will recognize. Match a test against a single value. Gets the element name Element name Provides a platform-independent methods for getting attributes for use by AttributeConstraint and AttributeExistsConstraint. Gets the custom attributes from the given object. Portable libraries do not have an ICustomAttributeProvider, so we need to cast to each of it's direct subtypes and try to get attributes off those instead. The actual. Type of the attribute. if set to true [inherit]. A list of the given attribute on the given object. The SpecialValue enum is used to represent TestCase arguments that cannot be used as arguments to an Attribute. Null represents a null value, which cannot be used as an argument to an attriute under .NET 1.x TypeHelper provides static methods that operate on Types. A special value, which is used to indicate that BestCommonType() method was unable to find a common type for the specified arguments. Gets the display name for a Type as used by NUnit. The Type for which a display name is needed. The display name for the Type Gets the display name for a Type as used by NUnit. The Type for which a display name is needed. The arglist provided. The display name for the Type Returns the best fit for a common type to be used in matching actual arguments to a methods Type parameters. The first type. The second type. Either type1 or type2, depending on which is more general. Determines whether the specified type is numeric. The type to be examined. true if the specified type is numeric; otherwise, false. Convert an argument list to the required parameter types. Currently, only widening numeric conversions are performed. An array of args to be converted A ParameterInfo[] whose types will be used as targets Determines whether this instance can deduce type args for a generic type from the supplied arguments. The type to be examined. The arglist. The type args to be used. true if this the provided args give sufficient information to determine the type args to be used; otherwise, false. Gets the _values for an enumeration, using Enum.GetTypes where available, otherwise through reflection. Gets the ids of the _values for an enumeration, using Enum.GetNames where available, otherwise through reflection. ThreadUtility provides a set of static methods convenient for working with threads. Do our best to Kill a thread The thread to kill Do our best to kill a thread, passing state info The thread to kill Info for the ThreadAbortException handler TestFixture is a surrogate for a user test fixture class, containing one or more tests. Any ITest that implements this interface is at a level that the implementing class should be disposed at the end of the test run Initializes a new instance of the class. Type of the fixture. Predicate constraint wraps a Predicate in a constraint, returning success if the predicate is true. Construct a PredicateConstraint from a predicate Determines whether the predicate succeeds when applied to the actual value. Gets text describing a constraint NotConstraint negates the effect of some other constraint Initializes a new instance of the class. The base constraint to be negated. Test whether the constraint is satisfied by a given value The value to be tested True for if the base constraint fails, false if it succeeds Custom value formatter function The value Custom value formatter factory function The next formatter function ValueFormatter If the given formatter is unable to handle a certain format, it must call the next formatter in the chain Static methods used in creating messages Static string used when strings are clipped Formatting strings used for expected and actual _values Add a formatter to the chain of responsibility. Formats text to represent a generalized value. The value The formatted text Formats text for a collection value, starting at a particular point, to a max length The collection containing elements to write. The starting point of the elements to write The maximum number of elements to write Returns the representation of a type as used in NUnitLite. This is the same as Type.ToString() except for arrays, which are displayed with their declared sizes. Converts any control characters in a string to their escaped representation. The string to be converted The converted string Converts any null characters in a string to their escaped representation. The string to be converted The converted string Return the a string representation for a set of indices into an array Array of indices for which a string is needed Get an array of indices representing the point in a collection or array corresponding to a single int index into the collection. The collection to which the indices apply Index in the collection Array of indices Clip a string to a given length, starting at a particular offset, returning the clipped string with ellipses representing the removed parts The string to be clipped The maximum permitted length of the result string The point at which to start clipping The clipped string Clip the expected and actual strings in a coordinated fashion, so that they may be displayed together. Shows the position two strings start to differ. Comparison starts at the start index. The expected string The actual string The index in the strings at which comparison should start Boolean indicating whether case should be ignored -1 if no mismatch found, or the index where mismatch found Current head of chain of value formatters. Public for testing. Adding this attribute to a method within a class makes the method callable from the NUnit test runner. There is a property called Description which is optional which you can provide a more detailed test description. This class cannot be inherited. [TestFixture] public class Fixture { [Test] public void MethodToTest() {} [Test(Description = "more detailed description")] public void TestDescriptionMethod() {} } Construct the attribute, specifying a combining strategy and source of parameter data. Enumeration indicating whether the tests are running normally or being cancelled. Running normally with no stop requested A graceful stop has been requested A forced stop has been requested The TestCaseParameters class encapsulates method arguments and other selected parameters needed for constructing a parameterized test case. Default Constructor creates an empty parameter set Construct a non-runnable ParameterSet, specifying the provider exception that made it invalid. Construct a parameter set with a list of arguments Construct a ParameterSet from an object implementing ITestCaseData Type arguments used to create a generic fixture instance Provides methods to support legacy string comparison methods. Compares two strings for equality, ignoring case if requested. The first string. The second string.. if set to true, the case of the letters in the strings is ignored. Zero if the strings are equivalent, a negative number if strA is sorted first, a positive number if strB is sorted first Compares two strings for equality, ignoring case if requested. The first string. The second string.. if set to true, the case of the letters in the strings is ignored. True if the strings are equivalent, false if not. OneTimeSetUpCommand runs any one-time setup methods for a suite, constructing the user test object if necessary. Constructs a OneTimeSetUpCommand for a suite The suite to which the command applies A SetUpTearDownList for use by the command A List of TestActionItems to be run after Setup Overridden to run the one-time setup for a suite. The TestExecutionContext to be used. A TestResult The TestOutput class holds a unit of output from a test to a specific output stream Construct with text, ouput destination type and the name of the test that produced the output. Text to be output Name of the stream or channel to which the text should be written FullName of test that produced the output Return string representation of the object for debugging Convert the TestOutput object to an XML string Get the text Get the output type Get the name of the test that created the output The IMethodInfo class is used to encapsulate information about a method in a platform-independent manner. Gets the parameters of the method. Returns the Type arguments of a generic method or the Type parameters of a generic method definition. Replaces the type parameters of the method with the array of types provided and returns a new IMethodInfo. The type arguments to be used A new IMethodInfo with the type arguments replaced Invokes the method, converting any TargetInvocationException to an NUnitException. The object on which to invoke the method The argument list for the method The return value from the invoked method Gets the Type from which this method was reflected. Gets the MethodInfo for this method. Gets the name of the method. Gets a value indicating whether the method is abstract. Gets a value indicating whether the method is public. Gets a value indicating whether the method contains unassigned generic type parameters. Gets a value indicating whether the method is a generic method. Gets a value indicating whether the MethodInfo represents the definition of a generic method. Gets the return Type of the method. ThrowsExceptionConstraint tests that an exception has been thrown, without any further tests. Executes the code and returns success if an exception is thrown. A delegate representing the code to be tested True if an exception is thrown, otherwise false Returns the ActualValueDelegate itself as the value to be tested. A delegate representing the code to be tested The delegate itself The Description of what this constraint tests, for use in messages and in the ConstraintResult. LevelOfParallelismAttribute is used to set the number of worker threads that may be allocated by the framework for running tests. Construct a LevelOfParallelismAttribute. The number of worker threads to be created by the framework. RepeatAttribute may be applied to test case in order to run it multiple times. Construct a RepeatAttribute The number of times to run the test Wrap a command and return the result. The command to be wrapped The wrapped command The test command for the RetryAttribute Initializes a new instance of the class. The inner command. The number of repetitions Runs the test, saving a TestResult in the supplied TestExecutionContext. The context in which the test should run. A TestResult Represents the result of running a single test case. Construct a TestCaseResult based on a TestMethod A TestMethod to which the result applies. Gets the number of test cases that failed when running the test and all its children. Gets the number of test cases that passed when running the test and all its children. Gets the number of test cases that were skipped when running the test and all its children. Gets the number of test cases that were inconclusive when running the test and all its children. Indicates whether this result has any child results. Gets the collection of child results. TestParameters class holds any named parameters supplied to the test run Gets a flag indicating whether a parameter with the specified name exists.N Name of the parameter True if it exists, otherwise false Get method is a simple alternative to the indexer Name of the paramter Value of the parameter or null if not present Get the value of a parameter or a default string Name of the parameter Default value of the parameter Value of the parameter or default value if not present Get the value of a parameter or return a default The return Type Name of the parameter Default value of the parameter Value of the parameter or default value if not present Adds a parameter to the list Name of the parameter Value of the parameter Gets the number of test parameters Gets a collection of the test parameter names Indexer provides access to the internal dictionary Name of the parameter Value of the parameter or null if not present ParameterDataSourceProvider supplies individual argument _values for single parameters using attributes implementing IParameterDataSource. Determine whether any data is available for a parameter. A ParameterInfo representing one argument to a parameterized test True if any data is available, otherwise false. Return an IEnumerable providing data for use with the supplied parameter. An IParameterInfo representing one argument to a parameterized test An IEnumerable providing the required data Thrown when an assertion failed. The error message that explains the reason for the exception The exception that caused the current exception Serialization Constructor Gets the ResultState provided by this exception OrConstraint succeeds if either member succeeds Create an OrConstraint from two other constraints The first constraint The second constraint Apply the member constraints to an actual value, succeeding succeeding as soon as one of them succeeds. The actual value True if either constraint succeeded Gets text describing a constraint Operator that tests for the presence of a particular attribute on a type and optionally applies further tests to the attribute. Construct an AttributeOperator for a particular Type The Type of attribute tested Reduce produces a constraint from the operator and any arguments. It takes the arguments from the constraint stack and pushes the resulting constraint on it. MessageWriter is the abstract base for classes that write constraint descriptions and messages in some form. The class has separate methods for writing various components of a message, allowing implementations to tailor the presentation as needed. Construct a MessageWriter given a culture Method to write single line message with optional args, usually written to precede the general failure message. The message to be written Any arguments used in formatting the message Method to write single line message with optional args, usually written to precede the general failure message, at a givel indentation level. The indentation level of the message The message to be written Any arguments used in formatting the message Display Expected and Actual lines for a constraint. This is called by MessageWriter's default implementation of WriteMessageTo and provides the generic two-line display. The failing constraint result Display Expected and Actual lines for given _values. This method may be called by constraints that need more control over the display of actual and expected _values than is provided by the default implementation. The expected value The actual value causing the failure Display Expected and Actual lines for given _values, including a tolerance value on the Expected line. The expected value The actual value causing the failure The tolerance within which the test was made Display the expected and actual string _values on separate lines. If the mismatch parameter is >=0, an additional line is displayed line containing a caret that points to the mismatch point. The expected string value The actual string value The point at which the strings don't match or -1 If true, case is ignored in locating the point where the strings differ If true, the strings should be clipped to fit the line Writes the text for an actual value. The actual value. Writes the text for a generalized value. The value. Writes the text for a collection value, starting at a particular point, to a max length The collection containing elements to write. The starting point of the elements to write The maximum number of elements to write Abstract method to get the max line length Tests whether a value is less than the value supplied to its constructor Abstract base class for constraints that compare _values to determine if one is greater than, equal to or less than the other. The value against which a comparison is to be made If true, less than returns success if true, equal returns success if true, greater than returns success ComparisonAdapter to be used in making the comparison Initializes a new instance of the class. The value against which to make a comparison. if set to true less succeeds. if set to true equal succeeds. if set to true greater succeeds. String used in describing the constraint. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Modifies the constraint to use an and returns self The comparer used for comparison tests A constraint modified to use the given comparer Modifies the constraint to use an and returns self The comparer used for comparison tests A constraint modified to use the given comparer Modifies the constraint to use a and returns self The comparer used for comparison tests A constraint modified to use the given comparer Initializes a new instance of the class. The expected value. EmptyStringConstraint tests whether a string is empty. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. EmptyDirectoryConstraint is used to test that a directory is empty Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. ConstraintBuilder maintains the stacks that are used in processing a ConstraintExpression. An OperatorStack is used to hold operators that are waiting for their operands to be reorganized. a ConstraintStack holds input constraints as well as the results of each operator applied. Initializes a new instance of the class. Appends the specified operator to the expression by first reducing the operator stack and then pushing the new operator on the stack. The operator to push. Appends the specified constraint to the expression by pushing it on the constraint stack. The constraint to push. Sets the top operator right context. The right context. Reduces the operator stack until the topmost item precedence is greater than or equal to the target precedence. The target precedence. Resolves this instance, returning a Constraint. If the Builder is not currently in a resolvable state, an exception is thrown. The resolved constraint Gets a value indicating whether this instance is resolvable. true if this instance is resolvable; otherwise, false. OperatorStack is a type-safe stack for holding ConstraintOperators Initializes a new instance of the class. The ConstraintBuilder using this stack. Pushes the specified operator onto the stack. The operator to put onto the stack. Pops the topmost operator from the stack. The topmost operator on the stack Gets a value indicating whether this is empty. true if empty; otherwise, false. Gets the topmost operator without modifying the stack. ConstraintStack is a type-safe stack for holding Constraints Initializes a new instance of the class. The ConstraintBuilder using this stack. Pushes the specified constraint. As a side effect, the constraint's Builder field is set to the ConstraintBuilder owning this stack. The constraint to put onto the stack Pops this topmost constraint from the stack. As a side effect, the constraint's Builder field is set to null. The topmost contraint on the stack Gets a value indicating whether this is empty. true if empty; otherwise, false. CollectionEquivalentConstraint is used to determine whether two collections are equivalent. Construct a CollectionEquivalentConstraint Test whether two collections are equivalent Flag the constraint to use the supplied predicate function The comparison function to use. Self. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. AttributeExistsConstraint tests for the presence of a specified attribute on a Type. Constructs an AttributeExistsConstraint for a specific attribute Type Tests whether the object provides the expected attribute. A Type, MethodInfo, or other ICustomAttributeProvider True if the expected attribute is present, otherwise false The Description of what this constraint tests, for use in messages and in the ConstraintResult. Marks a test that must run on a separate thread. Construct a RequiresThreadAttribute Construct a RequiresThreadAttribute, specifying the apartment ExplicitAttribute marks a test or test fixture so that it will only be run if explicitly executed from the gui or command line or if it is included by use of a filter. The test will not be run simply because an enclosing suite is run. Default constructor Constructor with a reason The reason test is marked explicit Modifies a test by marking it as explicit. The test to modify OneTimeTearDownCommand performs any teardown actions specified for a suite and calls Dispose on the user test object, if any. Construct a OneTimeTearDownCommand The test suite to which the command applies A SetUpTearDownList for use by the command A List of TestActionItems to be run before teardown. Overridden to run the teardown methods specified on the test. The TestExecutionContext to be used. A TestResult Class that can build a tree of automatic namespace suites from a group of fixtures. NamespaceDictionary of all test suites we have created to represent namespaces. Used to locate namespace parent suites for fixtures. The root of the test suite being created by this builder. Initializes a new instance of the class. The root suite. Adds the specified fixtures to the tree. The fixtures to be added. Adds the specified fixture to the tree. The fixture to be added. Gets the root entry in the tree created by the NamespaceTreeBuilder. The root suite. Built-in SuiteBuilder for all types of test classes. The ISuiteBuilder interface is exposed by a class that knows how to build a suite from one or more Types. Examine the type and determine if it is suitable for this builder to use in building a TestSuite. Note that returning false will cause the type to be ignored in loading the tests. If it is desired to load the suite but label it as non-runnable, ignored, etc., then this method must return true. The type of the fixture to be used True if the type can be used to build a TestSuite Build a TestSuite from type provided. The type of the fixture to be used A TestSuite Checks to see if the provided Type is a fixture. To be considered a fixture, it must be a non-abstract class with one or more attributes implementing the IFixtureBuilder interface or one or more methods marked as tests. The fixture type to check True if the fixture can be built, false if not Build a TestSuite from TypeInfo provided. The fixture type to build A TestSuite built from that type We look for attributes implementing IFixtureBuilder at one level of inheritance at a time. Attributes on base classes are not used unless there are no fixture builder attributes at all on the derived class. This is by design. The type being examined for attributes A list of the attributes found. Provide actions to execute before and after tests. When implemented by an attribute, this interface implemented to provide actions to execute before and after tests. Executed before each test is run The test that is going to be run. Executed after each test is run The test that has just been run. Provides the target for the action attribute The target for the action attribute Executed before each test is run The test that is going to be run. Executed after each test is run The test that has just been run. Provides the target for the action attribute Marks a test that must run in a particular threading apartment state, causing it to run in a separate thread if necessary. Construct an ApartmentAttribute The apartment state that this test must be run under. You must pass in a valid apartment state. The Iz class is a synonym for Is intended for use in VB, which regards Is as a keyword. Helper class with properties and methods that supply a number of constraints used in Asserts. Returns a constraint that tests two items for equality Returns a constraint that tests that two references are the same object Returns a constraint that tests whether the actual value is greater than the supplied argument Returns a constraint that tests whether the actual value is greater than or equal to the supplied argument Returns a constraint that tests whether the actual value is greater than or equal to the supplied argument Returns a constraint that tests whether the actual value is less than the supplied argument Returns a constraint that tests whether the actual value is less than or equal to the supplied argument Returns a constraint that tests whether the actual value is less than or equal to the supplied argument Returns a constraint that tests whether the actual value is of the exact type supplied as an argument. Returns a constraint that tests whether the actual value is of the exact type supplied as an argument. Returns a constraint that tests whether the actual value is of the type supplied as an argument or a derived type. Returns a constraint that tests whether the actual value is of the type supplied as an argument or a derived type. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable to the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable to the type supplied as an argument. Returns a constraint that tests whether the actual value is a collection containing the same elements as the collection supplied as an argument. Returns a constraint that tests whether the actual value is a subset of the collection supplied as an argument. Returns a constraint that tests whether the actual value is a superset of the collection supplied as an argument. Returns a constraint that succeeds if the actual value contains the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that tests whether the path provided is the same as an expected path after canonicalization. Returns a constraint that tests whether the path provided is a subpath of the expected path after canonicalization. Returns a constraint that tests whether the path provided is the same path or under an expected path after canonicalization. Returns a constraint that tests whether the actual value falls inclusively within a specified range. from must be less than or equal to true Inclusive beginning of the range. Must be less than or equal to to. Inclusive end of the range. Must be greater than or equal to from. Returns a ConstraintExpression that negates any following constraint. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them succeed. Returns a constraint that tests for null Returns a constraint that tests for True Returns a constraint that tests for False Returns a constraint that tests for a positive value Returns a constraint that tests for a negative value Returns a constraint that tests for equality with zero Returns a constraint that tests for NaN Returns a constraint that tests for empty Returns a constraint that tests whether a collection contains all unique items. Returns a constraint that tests whether an object graph is serializable in binary format. Returns a constraint that tests whether an object graph is serializable in xml format. Returns a constraint that tests whether a collection is ordered Objects implementing this interface are used to wrap the TestMethodCommand itself. They apply after SetUp has been run and before TearDown. The CommandStage enumeration represents the defined stages of execution for a series of TestCommands. The int _values of the enum are used to apply decorators in the proper order. Lower _values are applied first and are therefore "closer" to the actual test execution. No CommandStage is defined for actual invocation of the test or for creation of the context. Execution may be imagined as proceeding from the bottom of the list upwards, with cleanup after the test running in the opposite order. Use an application-defined default value. Make adjustments needed before and after running the raw test - that is, after any SetUp has run and before TearDown. Run SetUp and TearDown for the test. This stage is used internally by NUnit and should not normally appear in user-defined decorators. Make adjustments needed before and after running the entire test - including SetUp and TearDown. ThrowsConstraint is used to test the exception thrown by a delegate by applying a constraint to it. Initializes a new instance of the class, using a constraint to be applied to the exception. A constraint to apply to the caught exception. Executes the code of the delegate and captures any exception. If a non-null base constraint was provided, it applies that constraint to the exception. A delegate representing the code to be tested True if an exception is thrown and the constraint succeeds, otherwise false Converts an ActualValueDelegate to a TestDelegate before calling the primary overload. Get the actual exception thrown - used by Assert.Throws. Gets text describing a constraint Write the actual value for a failing constraint test to a MessageWriter. This override only handles the special message used when an exception is expected but none is thrown. The writer on which the actual value is displayed Summary description for SamePathConstraint. Initializes a new instance of the class. The expected path Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. Operator that requires both it's arguments to succeed Construct an AndOperator Apply the operator to produce an AndConstraint Provides static methods to express the assumptions that must be met for a test to give a meaningful result. If an assumption is not met, the test should produce an inconclusive result. The Equals method throws an InvalidOperationException. This is done to make sure there is no mistake by calling this function. The left object. The right object. Not applicable override the default ReferenceEquals to throw an InvalidOperationException. This implementation makes sure there is no mistake in calling this function as part of Assert. The left object. The right object. Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an InconclusiveException on failure. The Type being compared. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an InconclusiveException on failure. The Type being compared. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied The message that will be displayed on failure Arguments to be used in formatting the message Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an InconclusiveException on failure. The Type being compared. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied A function to build the message included with the Exception Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition The message to display if the condition is false Arguments to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition Asserts that a condition is true. If the condition is false the method throws an . The evaluated condition A function to build the message included with the Exception Asserts that a condition is true. If the condition is false the method throws an . A lambda that returns a Boolean The message to display if the condition is false Arguments to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . A lambda that returns a Boolean Asserts that a condition is true. If the condition is false the method throws an . A lambda that returns a Boolean A function to build the message included with the Exception Asserts that the code represented by a delegate throws an exception that satisfies the constraint provided. A TestDelegate to be executed A ThrowsConstraint used in the test Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an InconclusiveException on failure. The Type being compared. The actual value to test A Constraint to be applied Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an InconclusiveException on failure. The Type being compared. The actual value to test A Constraint expression to be applied The message that will be displayed on failure Arguments to be used in formatting the message Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an InconclusiveException on failure. The Type being compared. The actual value to test A Constraint to be applied A function to build the message included with the Exception TODO: Documentation needed for class Initializes a new instance of the class. The test being skipped. Overridden to simply set the CurrentResult to the appropriate Skipped state. The execution context for the test A TestResult The TextCapture class intercepts console output and writes it to the current execution context, if one is present on the thread. If no execution context is found, the output is written to a default destination, normally the original destination of the intercepted output. Construct a TextCapture object The default destination for non-intercepted output Writes a single character The char to write Writes a string The string to write Writes a string followed by a line terminator The string to write Gets the Encoding in use by this TextWriter SimpleWorkItemDispatcher handles execution of WorkItems by directly executing them. It is provided so that a dispatcher is always available in the context, thereby simplifying the code needed to run child tests. An IWorkItemDispatcher handles execution of work items. Dispatch a single work item for execution. The first work item dispatched is saved as the top-level work item and used when stopping the run. The item to dispatch Cancel the ongoing run completely. If no run is in process, the call has no effect. true if the IWorkItemDispatcher should abort all currently running WorkItems, false if it should allow all currently running WorkItems to complete Dispatch a single work item for execution. The first work item dispatched is saved as the top-level work item and a thread is created on which to run it. Subsequent calls come from the top level item or its descendants on the proper thread. The item to dispatch Cancel (abort or stop) the ongoing run. If no run is in process, the call has no effect. true if the run should be aborted, false if it should allow its currently running test to complete Asserts on Directories The Equals method throws an InvalidOperationException. This is done to make sure there is no mistake by calling this function. override the default ReferenceEquals to throw an InvalidOperationException. This implementation makes sure there is no mistake in calling this function as part of Assert. Verifies that two directories are equal. Two directories are considered equal if both are null, or if both point to the same directory. If they are not equal an is thrown. A directory containing the value that is expected A directory containing the actual value The message to display if the directories are not equal Arguments to be used in formatting the message Verifies that two directories are equal. Two directories are considered equal if both are null, or if both point to the same directory. If they are not equal an is thrown. A directory containing the value that is expected A directory containing the actual value Asserts that two directories are not equal. If they are equal an is thrown. A directory containing the value that is expected A directory containing the actual value The message to display if directories are not equal Arguments to be used in formatting the message Asserts that two directories are not equal. If they are equal an is thrown. A directory containing the value that is expected A directory containing the actual value Asserts that the directory exists. If it does not exist an is thrown. A directory containing the actual value The message to display if directories are not equal Arguments to be used in formatting the message Asserts that the directory exists. If it does not exist an is thrown. A directory containing the actual value Asserts that the directory exists. If it does not exist an is thrown. The path to a directory containing the actual value The message to display if directories are not equal Arguments to be used in formatting the message Asserts that the directory exists. If it does not exist an is thrown. The path to a directory containing the actual value Asserts that the directory does not exist. If it does exist an is thrown. A directory containing the actual value The message to display if directories are not equal Arguments to be used in formatting the message Asserts that the directory does not exist. If it does exist an is thrown. A directory containing the actual value Asserts that the directory does not exist. If it does exist an is thrown. The path to a directory containing the actual value The message to display if directories are not equal Arguments to be used in formatting the message Asserts that the directory does not exist. If it does exist an is thrown. The path to a directory containing the actual value TestName filter selects tests based on their Name Construct a TestNameFilter for a single name The name the filter will recognize. Match a test against a single value. Gets the element name Element name The ParameterDataProvider class implements IParameterDataProvider and hosts one or more individual providers. Construct with a collection of individual providers Determine whether any data is available for a parameter. An IParameterInfo representing one argument to a parameterized test True if any data is available, otherwise false. Return an IEnumerable providing data for use with the supplied parameter. An IParameterInfo representing one argument to a parameterized test An IEnumerable providing the required data ExactCountConstraint applies another constraint to each item in a collection, succeeding only if a specified number of items succeed. Construct an ExactCountConstraint on top of an existing constraint Apply the item constraint to each item in the collection, succeeding only if the expected number of items pass. Thrown when an assertion failed. The error message that explains the reason for the exception The error message that explains the reason for the exception The exception that caused the current exception Serialization Constructor Gets the ResultState provided by this exception XmlSerializableConstraint tests whether an object is serializable in xml format. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Returns the string representation of this constraint Gets text describing a constraint Helper routines for working with floating point numbers The floating point comparison code is based on this excellent article: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm "ULP" means Unit in the Last Place and in the context of this library refers to the distance between two adjacent floating point numbers. IEEE floating point numbers can only represent a finite subset of natural numbers, with greater accuracy for smaller numbers and lower accuracy for very large numbers. If a comparison is allowed "2 ulps" of deviation, that means the _values are allowed to deviate by up to 2 adjacent floating point _values, which might be as low as 0.0000001 for small numbers or as high as 10.0 for large numbers. Compares two floating point _values for equality First floating point value to be compared Second floating point value t be compared Maximum number of representable floating point _values that are allowed to be between the left and the right floating point _values True if both numbers are equal or close to being equal Floating point _values can only represent a finite subset of natural numbers. For example, the _values 2.00000000 and 2.00000024 can be stored in a float, but nothing inbetween them. This comparison will count how many possible floating point _values are between the left and the right number. If the number of possible _values between both numbers is less than or equal to maxUlps, then the numbers are considered as being equal. Implementation partially follows the code outlined here: http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ Compares two double precision floating point _values for equality First double precision floating point value to be compared Second double precision floating point value t be compared Maximum number of representable double precision floating point _values that are allowed to be between the left and the right double precision floating point _values True if both numbers are equal or close to being equal Double precision floating point _values can only represent a limited series of natural numbers. For example, the _values 2.0000000000000000 and 2.0000000000000004 can be stored in a double, but nothing inbetween them. This comparison will count how many possible double precision floating point _values are between the left and the right number. If the number of possible _values between both numbers is less than or equal to maxUlps, then the numbers are considered as being equal. Implementation partially follows the code outlined here: http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ Reinterprets the memory contents of a floating point value as an integer value Floating point value whose memory contents to reinterpret The memory contents of the floating point value interpreted as an integer Reinterprets the memory contents of a double precision floating point value as an integer value Double precision floating point value whose memory contents to reinterpret The memory contents of the double precision floating point value interpreted as an integer Reinterprets the memory contents of an integer as a floating point value Integer value whose memory contents to reinterpret The memory contents of the integer value interpreted as a floating point value Reinterprets the memory contents of an integer value as a double precision floating point value Integer whose memory contents to reinterpret The memory contents of the integer interpreted as a double precision floating point value Union of a floating point variable and an integer The union's value as a floating point variable The union's value as an integer The union's value as an unsigned integer Union of a double precision floating point variable and a long The union's value as a double precision floating point variable The union's value as a long The union's value as an unsigned long EqualityAdapter class handles all equality comparisons that use an , or a . Compares two objects, returning true if they are equal Returns true if the two objects can be compared by this adapter. The base adapter cannot handle IEnumerables except for strings. Returns an that wraps an . Returns an that wraps an . Returns an EqualityAdapter that uses a predicate function for items comparison. Returns an that wraps an . Returns an that wraps an . Returns an that wraps a . that wraps an . Returns true if the two objects can be compared by this adapter. The base adapter cannot handle IEnumerables except for strings. Compares two objects, returning true if they are equal Returns true if the two objects can be compared by this adapter. Generic adapter requires objects of the specified type. that wraps an . EmptyCollectionConstraint tests whether a collection is empty. Check that the collection is empty The Description of what this constraint tests, for use in messages and in the ConstraintResult. Helper class with properties and methods that supply a number of constraints used in Asserts. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding only if a specified number of them succeed. Returns a new PropertyConstraintExpression, which will either test for the existence of the named property on the object being tested or apply any following constraint to that property. Returns a new AttributeConstraint checking for the presence of a particular attribute on an object. Returns a new AttributeConstraint checking for the presence of a particular attribute on an object. Returns a constraint that tests two items for equality Returns a constraint that tests that two references are the same object Returns a constraint that tests whether the actual value is greater than the supplied argument Returns a constraint that tests whether the actual value is greater than or equal to the supplied argument Returns a constraint that tests whether the actual value is greater than or equal to the supplied argument Returns a constraint that tests whether the actual value is less than the supplied argument Returns a constraint that tests whether the actual value is less than or equal to the supplied argument Returns a constraint that tests whether the actual value is less than or equal to the supplied argument Returns a constraint that tests whether the actual value is of the exact type supplied as an argument. Returns a constraint that tests whether the actual value is of the exact type supplied as an argument. Returns a constraint that tests whether the actual value is of the type supplied as an argument or a derived type. Returns a constraint that tests whether the actual value is of the type supplied as an argument or a derived type. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is a collection containing the same elements as the collection supplied as an argument. Returns a constraint that tests whether the actual value is a subset of the collection supplied as an argument. Returns a constraint that tests whether the actual value is a superset of the collection supplied as an argument. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a new ContainsConstraint. This constraint will, in turn, make use of the appropriate second-level constraint, depending on the type of the actual argument. This overload is only used if the item sought is a string, since any other type implies that we are looking for a collection member. Returns a constraint that succeeds if the actual value contains the substring supplied as an argument. Returns a constraint that succeeds if the actual value contains the substring supplied as an argument. Returns a constraint that fails if the actual value contains the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that fails if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that fails if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that fails if the actual value matches the pattern supplied as an argument. Returns a constraint that tests whether the path provided is the same as an expected path after canonicalization. Returns a constraint that tests whether the path provided is a subpath of the expected path after canonicalization. Returns a constraint that tests whether the path provided is the same path or under an expected path after canonicalization. Returns a constraint that tests whether the actual value falls within a specified range. Returns a ConstraintExpression that negates any following constraint. Returns a ConstraintExpression that negates any following constraint. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them succeed. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if at least one of them succeeds. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them fail. Returns a new ConstraintExpression, which will apply the following constraint to the Length property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the Count property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the Message property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the InnerException property of the object being tested. Returns a constraint that tests for null Returns a constraint that tests for True Returns a constraint that tests for False Returns a constraint that tests for a positive value Returns a constraint that tests for a negative value Returns a constraint that tests for equality with zero Returns a constraint that tests for NaN Returns a constraint that tests for empty Returns a constraint that tests whether a collection contains all unique items. Returns a constraint that tests whether an object graph is serializable in binary format. Returns a constraint that tests whether an object graph is serializable in xml format. Returns a constraint that tests whether a collection is ordered BinarySerializableConstraint tests whether an object is serializable in binary format. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Returns the string representation The Description of what this constraint tests, for use in messages and in the ConstraintResult. Used on a method, marks the test with a timeout value in milliseconds. The test will be run in a separate thread and is cancelled if the timeout is exceeded. Used on a class or assembly, sets the default timeout for all contained test methods. Construct a TimeoutAttribute given a time in milliseconds The timeout value in milliseconds Adding this attribute to a method within a class makes the method callable from the NUnit test runner. There is a property called Description which is optional which you can provide a more detailed test description. This class cannot be inherited. [TestFixture] public class Fixture { [Test] public void MethodToTest() {} [Test(Description = "more detailed description")] public void TestDescriptionMethod() {} } Modifies a test by adding a description, if not already set. The test to modify Construct a TestMethod from a given method. The method for which a test is to be constructed. The suite to which the test will be added. A TestMethod Descriptive text for this test The author of this test The type that this test is testing Gets or sets the expected result. The result. Returns true if an expected result has been set Summary description for SetUICultureAttribute. Construct given the name of a culture Marks a test that must run in the STA, causing it to run in a separate thread if necessary. Construct a RequiresSTAAttribute Used to mark a field, property or method providing a set of datapoints to be used in executing any theories within the same fixture that require an argument of the Type provided. The data source may provide an array of the required Type or an . Synonymous with DatapointSourceAttribute. TestActionItem represents a single execution of an ITestAction. It is used to track whether the BeforeTest method has been called and suppress calling the AfterTest method if it has not. Construct a TestActionItem The ITestAction to be included Run the BeforeTest method of the action and remember that it has been run. The test to which the action applies Run the AfterTest action, but only if the BeforeTest action was actually run. The test to which the action applies InternalTraceLevel is an enumeration controlling the level of detailed presented in the internal log. Use the default settings as specified by the user. Do not display any trace messages Display Error messages only Display Warning level and higher messages Display informational and higher messages Display debug messages and higher - i.e. all messages Display debug messages and higher - i.e. all messages The ParallelScope enumeration permits specifying the degree to which a test and its descendants may be run in parallel. No Parallelism is permitted The test itself may be run in parallel with others at the same level Descendants of the test may be run in parallel with one another Descendants of the test down to the level of TestFixtures may be run in parallel ListMapper is used to transform a collection used as an actual argument producing another collection to be used in the assertion. Construct a ListMapper based on a collection The collection to be transformed Produces a collection containing all the _values of a property The collection of property _values The List class is a helper class with properties and methods that supply a number of constraints used with lists and collections. List.Map returns a ListMapper, which can be used to map the original collection to another collection. TestAssembly is a TestSuite that represents the execution of tests in a managed assembly. Initializes a new instance of the class specifying the Assembly and the path from which it was loaded. The assembly this test represents. The path used to load the assembly. Initializes a new instance of the class for a path which could not be loaded. The path used to load the assembly. Gets the Assembly represented by this instance. Gets the name used for the top-level element in the XML representation of this test SetUpFixture extends TestSuite and supports Setup and TearDown methods. Initializes a new instance of the class. The type. TrueConstraint tests that the actual value is true Initializes a new instance of the class. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Tolerance class generalizes the notion of a tolerance within which an equality test succeeds. Normally, it is used with numeric types, but it can be used with any type that supports taking a difference between two objects and comparing that difference to a value. Constructs a linear tolerance of a specified amount Constructs a tolerance given an amount and Tests that the current Tolerance is linear with a numeric value, throwing an exception if it is not. Returns a default Tolerance object, equivalent to specifying an exact match unless is set, in which case, the will be used. Returns an empty Tolerance object, equivalent to specifying an exact match even if is set. Gets the for the current Tolerance Gets the value of the current Tolerance instance. Returns a new tolerance, using the current amount as a percentage. Returns a new tolerance, using the current amount in Ulps Returns a new tolerance with a as the amount, using the current amount as a number of days. Returns a new tolerance with a as the amount, using the current amount as a number of hours. Returns a new tolerance with a as the amount, using the current amount as a number of minutes. Returns a new tolerance with a as the amount, using the current amount as a number of seconds. Returns a new tolerance with a as the amount, using the current amount as a number of milliseconds. Returns a new tolerance with a as the amount, using the current amount as a number of clock ticks. Returns true if the current tolerance has not been set or is using the . StartsWithConstraint can test whether a string starts with an expected substring. Initializes a new instance of the class. The expected string Test whether the constraint is matched by the actual value. This is a template method, which calls the IsMatch method of the derived class. Operator that tests that an exception is thrown and optionally applies further tests to the exception. Construct a ThrowsOperator Reduce produces a constraint from the operator and any arguments. It takes the arguments from the constraint stack and pushes the resulting constraint on it. ConstraintExpression represents a compound constraint in the process of being constructed from a series of syntactic elements. Individual elements are appended to the expression as they are reorganized. When a constraint is appended, it is returned as the value of the operation so that modifiers may be applied. However, any partially built expression is attached to the constraint for later resolution. When an operator is appended, the partial expression is returned. If it's a self-resolving operator, then a ResolvableConstraintExpression is returned. The ConstraintBuilder holding the elements recognized so far Initializes a new instance of the class. Initializes a new instance of the class passing in a ConstraintBuilder, which may be pre-populated. The builder. Returns a string representation of the expression as it currently stands. This should only be used for testing, since it has the side-effect of resolving the expression. Appends an operator to the expression and returns the resulting expression itself. Appends a self-resolving operator to the expression and returns a new ResolvableConstraintExpression. Appends a constraint to the expression and returns that constraint, which is associated with the current state of the expression being built. Note that the constraint is not reduced at this time. For example, if there is a NotOperator on the stack we don't reduce and return a NotConstraint. The original constraint must be returned because it may support modifiers that are yet to be applied. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding only if a specified number of them succeed. Returns a new PropertyConstraintExpression, which will either test for the existence of the named property on the object being tested or apply any following constraint to that property. Returns a new AttributeConstraint checking for the presence of a particular attribute on an object. Returns a new AttributeConstraint checking for the presence of a particular attribute on an object. Returns the constraint provided as an argument - used to allow custom custom constraints to easily participate in the syntax. Returns the constraint provided as an argument - used to allow custom custom constraints to easily participate in the syntax. Returns a constraint that tests two items for equality Returns a constraint that tests that two references are the same object Returns a constraint that tests whether the actual value is greater than the supplied argument Returns a constraint that tests whether the actual value is greater than or equal to the supplied argument Returns a constraint that tests whether the actual value is greater than or equal to the supplied argument Returns a constraint that tests whether the actual value is less than the supplied argument Returns a constraint that tests whether the actual value is less than or equal to the supplied argument Returns a constraint that tests whether the actual value is less than or equal to the supplied argument Returns a constraint that tests whether the actual value is of the exact type supplied as an argument. Returns a constraint that tests whether the actual value is of the exact type supplied as an argument. Returns a constraint that tests whether the actual value is of the type supplied as an argument or a derived type. Returns a constraint that tests whether the actual value is of the type supplied as an argument or a derived type. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is assignable from the type supplied as an argument. Returns a constraint that tests whether the actual value is a collection containing the same elements as the collection supplied as an argument. Returns a constraint that tests whether the actual value is a subset of the collection supplied as an argument. Returns a constraint that tests whether the actual value is a superset of the collection supplied as an argument. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a new CollectionContainsConstraint checking for the presence of a particular object in the collection. Returns a new ContainsConstraint. This constraint will, in turn, make use of the appropriate second-level constraint, depending on the type of the actual argument. This overload is only used if the item sought is a string, since any other type implies that we are looking for a collection member. Returns a new ContainsConstraint. This constraint will, in turn, make use of the appropriate second-level constraint, depending on the type of the actual argument. This overload is only used if the item sought is a string, since any other type implies that we are looking for a collection member. Returns a constraint that succeeds if the actual value contains the substring supplied as an argument. Returns a constraint that succeeds if the actual value contains the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value starts with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value ends with the substring supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that succeeds if the actual value matches the regular expression supplied as an argument. Returns a constraint that tests whether the path provided is the same as an expected path after canonicalization. Returns a constraint that tests whether the path provided is the a subpath of the expected path after canonicalization. Returns a constraint that tests whether the path provided is the same path or under an expected path after canonicalization. Returns a constraint that tests whether the actual value falls within a specified range. Returns a ConstraintExpression that negates any following constraint. Returns a ConstraintExpression that negates any following constraint. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them succeed. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if at least one of them succeeds. Returns a ConstraintExpression, which will apply the following constraint to all members of a collection, succeeding if all of them fail. Returns a new ConstraintExpression, which will apply the following constraint to the Length property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the Count property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the Message property of the object being tested. Returns a new ConstraintExpression, which will apply the following constraint to the InnerException property of the object being tested. With is currently a NOP - reserved for future use. Returns a constraint that tests for null Returns a constraint that tests for True Returns a constraint that tests for False Returns a constraint that tests for a positive value Returns a constraint that tests for a negative value Returns a constraint that tests if item is equal to zero Returns a constraint that tests for NaN Returns a constraint that tests for empty Returns a constraint that tests whether a collection contains all unique items. Returns a constraint that tests whether an object graph is serializable in binary format. Returns a constraint that tests whether an object graph is serializable in xml format. Returns a constraint that tests whether a collection is ordered Returns a constraint that succeeds if the value is a file or directory and it exists. Attribute used to apply a category to a test The name of the category Construct attribute for a given category based on a name. The name may not contain the characters ',', '+', '-' or '!'. However, this is not checked in the constructor since it would cause an error to arise at as the test was loaded without giving a clear indication of where the problem is located. The error is handled in NUnitFramework.cs by marking the test as not runnable. The name of the category Protected constructor uses the Type name as the name of the category. Modifies a test by adding a category to it. The test to modify The name of the category IdFilter selects tests based on their id Construct an IdFilter for a single value The id the filter will recognize. Match a test against a single value. Gets the element name Element name Represents a constraint that succeeds if none of the members of a collection match a base constraint. Returns a constraint that will apply the argument to the members of a collection, succeeding if none of them succeed. Indicates which class the test or test fixture is testing Initializes a new instance of the class. The type that is being tested. Initializes a new instance of the class. The type that is being tested. Defines the order that the test will run in Defines the order that the test will run in Defines the order that the test will run in Modifies a test as defined for the specific attribute. The test to modify SingleThreadedAttribute applies to a test fixture and indicates that all the child tests must be run on the same thread as the OneTimeSetUp and OneTimeTearDown. It sets a flag in the TestExecutionContext and forces all tests to be run sequentially on the current thread. Any ParallelScope setting is ignored. Apply changes to the TestExecutionContext The TestExecutionContext FrameworkPackageSettings is a static class containing constant values that are used as keys in setting up a TestPackage. These values are used in the framework, and set in the runner. Setting values may be a string, int or bool. Flag (bool) indicating whether tests are being debugged. Flag (bool) indicating whether to pause execution of tests to allow the user to attache a debugger. The InternalTraceLevel for this run. Values are: "Default", "Off", "Error", "Warning", "Info", "Debug", "Verbose". Default is "Off". "Debug" and "Verbose" are synonyms. Full path of the directory to be used for work and result files. This path is provided to tests by the frameowrk TestContext. Integer value in milliseconds for the default timeout value for test cases. If not specified, there is no timeout except as specified by attributes on the tests themselves. A TextWriter to which the internal trace will be sent. A list of tests to be loaded. The number of test threads to run for the assembly. If set to 1, a single queue is used. If set to 0, tests are executed directly, without queuing. The random seed to be used for this assembly. If specified as the value reported from a prior run, the framework should generate identical random values for tests as were used for that run, provided that no change has been made to the test assembly. Default is a random value itself. If true, execution stops after the first error or failure. If true, use of the event queue is suppressed and test events are synchronous. The default naming pattern used in generating test names Parameters to be passed on to the test Represents a constraint that succeeds if the specified count of members of a collection match a base constraint. Construct an ExactCountOperator for a specified count The expected count Returns a constraint that will apply the argument to the members of a collection, succeeding if none of them succeed. ParameterizedFixtureSuite serves as a container for the set of test fixtures created from a given Type using various parameters. Initializes a new instance of the class. The ITypeInfo for the type that represents the suite. Gets a string representing the type of test ReusableConstraint wraps a constraint expression after resolving it so that it can be reused consistently. Construct a ReusableConstraint from a constraint expression The expression to be resolved and reused Converts a constraint to a ReusableConstraint The constraint to be converted A ReusableConstraint Returns a that represents this instance. A that represents this instance. Return the top-level constraint for this expression PropertyExistsConstraint tests that a named property exists on the object provided through Match. Originally, PropertyConstraint provided this feature in addition to making optional tests on the value of the property. The two constraints are now separate. Initializes a new instance of the class. The name of the property. Test whether the property exists for a given object The object to be tested True for success, false for failure Returns the string representation of the constraint. The Description of what this constraint tests, for use in messages and in the ConstraintResult. PropertyConstraint extracts a named property and uses its value as the actual value for a chained constraint. Initializes a new instance of the class. The name. The constraint to apply to the property. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Returns the string representation of the constraint. Represents a constraint that simply wraps the constraint provided as an argument, without any further functionality, but which modifies the order of evaluation because of its precedence. Constructor for the WithOperator Returns a constraint that wraps its argument NUnitComparer encapsulates NUnit's default behavior in comparing two objects. Compares two objects Returns the default NUnitComparer. Tests whether a value is less than or equal to the value supplied to its constructor Initializes a new instance of the class. The expected value. Attribute used to identify a method that is called before any tests in a fixture are run. Used to mark a field for use as a datapoint when executing a theory within the same fixture that requires an argument of the field's Type. AssertionHelper is an optional base class for user tests, allowing the use of shorter ids for constraints and asserts and avoiding conflict with the definition of , from which it inherits much of its behavior, in certain mock object frameworks. Asserts that a condition is true. If the condition is false the method throws an . Works Identically to . The evaluated condition The message to display if the condition is false Arguments to be used in formatting the message Asserts that a condition is true. If the condition is false the method throws an . Works Identically to . The evaluated condition Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. A Constraint expression to be applied An ActualValueDelegate returning the value to be tested Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. An ActualValueDelegate returning the value to be tested A Constraint expression to be applied The message that will be displayed on failure Arguments to be used in formatting the message Asserts that the code represented by a delegate throws an exception that satisfies the constraint provided. A TestDelegate to be executed A ThrowsConstraint used in the test Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. A Constraint to be applied The actual value to test Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. A Constraint expression to be applied The actual value to test The message that will be displayed on failure Arguments to be used in formatting the message Returns a ListMapper based on a collection. The original collection TextMessageWriter writes constraint descriptions and messages in displayable form as a text stream. It tailors the display of individual message components to form the standard message format of NUnit assertion failure messages. Prefix used for the expected value line of a message Prefix used for the actual value line of a message Length of a message prefix Construct a TextMessageWriter Construct a TextMessageWriter, specifying a user message and optional formatting arguments. Method to write single line message with optional args, usually written to precede the general failure message, at a given indentation level. The indentation level of the message The message to be written Any arguments used in formatting the message Display Expected and Actual lines for a constraint. This is called by MessageWriter's default implementation of WriteMessageTo and provides the generic two-line display. The result of the constraint that failed Display Expected and Actual lines for given _values. This method may be called by constraints that need more control over the display of actual and expected _values than is provided by the default implementation. The expected value The actual value causing the failure Display Expected and Actual lines for given _values, including a tolerance value on the expected line. The expected value The actual value causing the failure The tolerance within which the test was made Display the expected and actual string _values on separate lines. If the mismatch parameter is >=0, an additional line is displayed line containing a caret that points to the mismatch point. The expected string value The actual string value The point at which the strings don't match or -1 If true, case is ignored in string comparisons If true, clip the strings to fit the max line length Writes the text for an actual value. The actual value. Writes the text for a generalized value. The value. Writes the text for a collection value, starting at a particular point, to a max length The collection containing elements to write. The starting point of the elements to write The maximum number of elements to write Write the generic 'Expected' line for a constraint The constraint that failed Write the generic 'Expected' line for a given value The expected value Write the generic 'Expected' line for a given value and tolerance. The expected value The tolerance within which the test was made Write the generic 'Actual' line for a constraint The ConstraintResult for which the actual value is to be written Write the generic 'Actual' line for a given value The actual value causing a failure Gets or sets the maximum line length for this writer EventListenerTextWriter sends text output to the currently active ITestEventListener in the form of a TestOutput object. If no event listener is active in the contet, or if there is no context, the output is forwarded to the supplied default writer. Construct an EventListenerTextWriter The name of the stream to use for events The default writer to use if no listener is available Write a single char Write a string Write a string followed by a newline Get the Encoding for this TextWriter CollectionSupersetConstraint is used to determine whether one collection is a superset of another Construct a CollectionSupersetConstraint The collection that the actual value is expected to be a superset of Test whether the actual collection is a superset of the expected collection provided. Flag the constraint to use the supplied predicate function The comparison function to use. Self. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. ParameterizedMethodSuite holds a collection of individual TestMethods with their arguments applied. Construct from a MethodInfo Gets a string representing the type of test OSPlatform represents a particular operating system platform Platform ID for Unix as defined by Microsoft .NET 2.0 and greater Platform ID for Unix as defined by Mono Platform ID for XBox as defined by .NET and Mono, but not CF Platform ID for MacOSX as defined by .NET and Mono, but not CF Gets the actual OS Version, not the incorrect value that might be returned for Win 8.1 and Win 10 If an application is not manifested as Windows 8.1 or Windows 10, the version returned from Environment.OSVersion will not be 6.3 and 10.0 respectively, but will be 6.2 and 6.3. The correct value can be found in the registry. The original version The correct OS version Construct from a platform ID and version Construct from a platform ID, version and product type Get the OSPlatform under which we are currently running Get the platform ID of this instance Get the Version of this instance Get the Product Type of this instance Return true if this is a windows platform Return true if this is a Unix or Linux platform Return true if the platform is Win32S Return true if the platform is Win32Windows Return true if the platform is Win32NT Return true if the platform is Windows CE Return true if the platform is Xbox Return true if the platform is MacOSX Return true if the platform is Windows 95 Return true if the platform is Windows 98 Return true if the platform is Windows ME Return true if the platform is NT 3 Return true if the platform is NT 4 Return true if the platform is NT 5 Return true if the platform is Windows 2000 Return true if the platform is Windows XP Return true if the platform is Windows 2003 Server Return true if the platform is NT 6 Return true if the platform is NT 6.0 Return true if the platform is NT 6.1 Return true if the platform is NT 6.2 Return true if the platform is NT 6.3 Return true if the platform is Vista Return true if the platform is Windows 2008 Server (original or R2) Return true if the platform is Windows 2008 Server (original) Return true if the platform is Windows 2008 Server R2 Return true if the platform is Windows 2012 Server (original or R2) Return true if the platform is Windows 2012 Server (original) Return true if the platform is Windows 2012 Server R2 Return true if the platform is Windows 7 Return true if the platform is Windows 8 Return true if the platform is Windows 8.1 Return true if the platform is Windows 10 Return true if the platform is Windows Server. This is named Windows Server 10 to distinguish it from previous versions of Windows Server. Product Type Enumeration used for Windows Product type is unknown or unspecified Product type is Workstation Product type is Domain Controller Product type is Server Combines multiple filters so that a test must pass one of them in order to pass this filter. Constructs an empty OrFilter Constructs an AndFilter from an array of filters Checks whether the OrFilter is matched by a test The test to be matched True if any of the component filters pass, otherwise false Checks whether the OrFilter is matched by a test The test to be matched True if any of the component filters match, otherwise false Checks whether the OrFilter is explicit matched by a test The test to be matched True if any of the component filters explicit match, otherwise false Gets the element name Element name InstanceOfTypeConstraint is used to test that an object is of the same type provided or derived from it. Construct an InstanceOfTypeConstraint for the type provided The expected Type Apply the constraint to an actual value, returning true if it succeeds The actual argument True if the constraint succeeds, otherwise false. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. Tests whether a value is greater than the value supplied to its constructor Initializes a new instance of the class. The expected value. DictionaryContainsKeyConstraint is used to test whether a dictionary contains an expected object as a key. Construct a DictionaryContainsKeyConstraint Test whether the expected key is contained in the dictionary The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. The Description of what this constraint tests, for use in messages and in the ConstraintResult. ContainsConstraint tests a whether a string contains a substring or a collection contains an object. It postpones the decision of which test to use until the type of the actual argument is known. This allows testing whether a string is contained in a collection or as a substring of another string using the same syntax. Initializes a new instance of the class. The _expected. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. Flag the constraint to ignore case and return self. CollectionTally counts (tallies) the number of occurrences of each object in one or more enumerations. Construct a CollectionTally object from a comparer and a collection Try to remove an object from the tally The object to remove True if successful, false if the object was not found Try to remove a set of objects from the tally The objects to remove True if successful, false if any object was not found The number of objects remaining in the tally AllItemsConstraint applies another constraint to each item in a collection, succeeding if they all succeed. Construct an AllItemsConstraint on top of an existing constraint Apply the item constraint to each item in the collection, failing if any item fails. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. A set of Assert methods operating on one or more collections The Equals method throws an InvalidOperationException. This is done to make sure there is no mistake by calling this function. override the default ReferenceEquals to throw an InvalidOperationException. This implementation makes sure there is no mistake in calling this function as part of Assert. Asserts that all items contained in collection are of the type specified by expectedType. IEnumerable containing objects to be considered System.Type that all objects in collection must be instances of Asserts that all items contained in collection are of the type specified by expectedType. IEnumerable containing objects to be considered System.Type that all objects in collection must be instances of The message that will be displayed on failure Arguments to be used in formatting the message Asserts that all items contained in collection are not equal to null. IEnumerable containing objects to be considered Asserts that all items contained in collection are not equal to null. IEnumerable of objects to be considered The message that will be displayed on failure Arguments to be used in formatting the message Ensures that every object contained in collection exists within the collection once and only once. IEnumerable of objects to be considered Ensures that every object contained in collection exists within the collection once and only once. IEnumerable of objects to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that expected and actual are exactly equal. The collections must have the same count, and contain the exact same objects in the same order. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered Asserts that expected and actual are exactly equal. The collections must have the same count, and contain the exact same objects in the same order. If comparer is not null then it will be used to compare the objects. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The IComparer to use in comparing objects from each IEnumerable Asserts that expected and actual are exactly equal. The collections must have the same count, and contain the exact same objects in the same order. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that expected and actual are exactly equal. The collections must have the same count, and contain the exact same objects in the same order. If comparer is not null then it will be used to compare the objects. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The IComparer to use in comparing objects from each IEnumerable The message that will be displayed on failure Arguments to be used in formatting the message Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that expected and actual are not exactly equal. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered Asserts that expected and actual are not exactly equal. If comparer is not null then it will be used to compare the objects. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The IComparer to use in comparing objects from each IEnumerable Asserts that expected and actual are not exactly equal. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that expected and actual are not exactly equal. If comparer is not null then it will be used to compare the objects. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The IComparer to use in comparing objects from each IEnumerable The message that will be displayed on failure Arguments to be used in formatting the message Asserts that expected and actual are not equivalent. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered Asserts that expected and actual are not equivalent. The first IEnumerable of objects to be considered The second IEnumerable of objects to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that collection contains actual as an item. IEnumerable of objects to be considered Object to be found within collection Asserts that collection contains actual as an item. IEnumerable of objects to be considered Object to be found within collection The message that will be displayed on failure Arguments to be used in formatting the message Asserts that collection does not contain actual as an item. IEnumerable of objects to be considered Object that cannot exist within collection Asserts that collection does not contain actual as an item. IEnumerable of objects to be considered Object that cannot exist within collection The message that will be displayed on failure Arguments to be used in formatting the message Asserts that the superset does not contain the subset The IEnumerable subset to be considered The IEnumerable superset to be considered Asserts that the superset does not contain the subset The IEnumerable subset to be considered The IEnumerable superset to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that the superset contains the subset. The IEnumerable subset to be considered The IEnumerable superset to be considered Asserts that the superset contains the subset. The IEnumerable subset to be considered The IEnumerable superset to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that the subset does not contain the superset The IEnumerable superset to be considered The IEnumerable subset to be considered Asserts that the subset does not contain the superset The IEnumerable superset to be considered The IEnumerable subset to be considered The message that will be displayed on failure Arguments to be used in formatting the message Asserts that the subset contains the superset. The IEnumerable superset to be considered The IEnumerable subset to be considered Asserts that the subset contains the superset. The IEnumerable superset to be considered The IEnumerable subset to be considered The message that will be displayed on failure Arguments to be used in formatting the message Assert that an array, list or other collection is empty An array, list or other collection implementing IEnumerable The message to be displayed on failure Arguments to be used in formatting the message Assert that an array,list or other collection is empty An array, list or other collection implementing IEnumerable Assert that an array, list or other collection is empty An array, list or other collection implementing IEnumerable The message to be displayed on failure Arguments to be used in formatting the message Assert that an array,list or other collection is empty An array, list or other collection implementing IEnumerable Assert that an array, list or other collection is ordered An array, list or other collection implementing IEnumerable The message to be displayed on failure Arguments to be used in formatting the message Assert that an array, list or other collection is ordered An array, list or other collection implementing IEnumerable Assert that an array, list or other collection is ordered An array, list or other collection implementing IEnumerable A custom comparer to perform the comparisons The message to be displayed on failure Arguments to be used in formatting the message Assert that an array, list or other collection is ordered An array, list or other collection implementing IEnumerable A custom comparer to perform the comparisons TestCaseSourceAttribute indicates the source to be used to provide test cases for a test method. Construct with the name of the method, property or field that will provide data The name of a static method, property or field that will provide data. Construct with a Type and name The Type that will provide data The name of a static method, property or field that will provide data. A set of parameters passed to the method, works only if the Source Name is a method. If the source name is a field or property has no effect. Construct with a Type and name The Type that will provide data The name of a static method, property or field that will provide data. Construct with a Type The type that will provide data Construct one or more TestMethods from a given MethodInfo, using available parameter data. The IMethod for which tests are to be constructed. The suite to which the tests will be added. One or more TestMethods Returns a set of ITestCaseDataItems for use as arguments to a parameterized test method. The method for which data is needed. A set of parameters passed to the method, works only if the Source Name is a method. If the source name is a field or property has no effect. The name of a the method, property or fiend to be used as a source A Type to be used as a source Gets or sets the category associated with every fixture created from this attribute. May be a single category or a comma-separated list. TestMethodCommand is the lowest level concrete command used to run actual test cases. Initializes a new instance of the class. The test. Runs the test, saving a TestResult in the execution context, as well as returning it. If the test has an expected result, it is asserts on that value. Since failed tests and errors throw an exception, this command must be wrapped in an outer command, will handle that exception and records the failure. This role is usually played by the SetUpTearDown command. The execution context SetUpTearDownCommand runs any SetUp methods for a suite, runs the test and then runs any TearDown methods. Initializes a new instance of the class. The inner command. Runs the test, saving a TestResult in the supplied TestExecutionContext. The context in which the test should run. A TestResult SetUpTearDownItem holds the setup and teardown methods for a single level of the inheritance hierarchy. Construct a SetUpTearDownNode A list of setup methods for this level A list teardown methods for this level Run SetUp on this level. The execution context to use for running. Run TearDown for this level. Returns true if this level has any methods at all. This flag is used to discard levels that do nothing. Class used to guard against unexpected argument values or operations by throwing an appropriate exception. Throws an exception if an argument is null The value to be tested The name of the argument Throws an exception if a string argument is null or empty The value to be tested The name of the argument Throws an ArgumentOutOfRangeException if the specified condition is not met. The condition that must be met The exception message to be used The name of the argument Throws an ArgumentException if the specified condition is not met. The condition that must be met The exception message to be used The name of the argument Throws an InvalidOperationException if the specified condition is not met. The condition that must be met The exception message to be used SubPathConstraint tests that the actual path is under the expected path Initializes a new instance of the class. The expected path Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. ParallelizableAttribute is used to mark tests that may be run in parallel. Construct a ParallelizableAttribute using default ParallelScope.Self. Construct a ParallelizableAttribute with a specified scope. The ParallelScope associated with this attribute. Modify the context to be used for child tests The current TestExecutionContext Helper class with properties and methods that supply constraints that operate on exceptions. Creates a constraint specifying the exact type of exception expected Creates a constraint specifying the exact type of exception expected Creates a constraint specifying the type of exception expected Creates a constraint specifying the type of exception expected Creates a constraint specifying an expected exception Creates a constraint specifying an exception with a given InnerException Creates a constraint specifying an expected TargetInvocationException Creates a constraint specifying an expected ArgumentException Creates a constraint specifying an expected ArgumentNUllException Creates a constraint specifying an expected InvalidOperationException Creates a constraint specifying that no exception is thrown Enumeration identifying a common language runtime implementation. Any supported runtime framework Microsoft .NET Framework Microsoft .NET Compact Framework Microsoft Shared Source CLI Mono Silverlight MonoTouch RuntimeFramework represents a particular version of a common language runtime implementation. DefaultVersion is an empty Version, used to indicate that NUnit should select the CLR version to use for the test. Construct from a runtime type and version. If the version has two parts, it is taken as a framework version. If it has three or more, it is taken as a CLR version. In either case, the other version is deduced based on the runtime type and provided version. The runtime type of the framework The version of the framework Parses a string representing a RuntimeFramework. The string may be just a RuntimeType name or just a Version or a hyphenated RuntimeType-Version or a Version prefixed by 'versionString'. Overridden to return the short name of the framework Returns true if the current framework matches the one supplied as an argument. Two frameworks match if their runtime types are the same or either one is RuntimeType.Any and all specified version components are equal. Negative (i.e. unspecified) version components are ignored. The RuntimeFramework to be matched. True on match, otherwise false Static method to return a RuntimeFramework object for the framework that is currently in use. The type of this runtime framework The framework version for this runtime framework The CLR version for this runtime framework Return true if any CLR version may be used in matching this RuntimeFramework object. Returns the Display name for this framework CategoryFilter is able to select or exclude tests based on their categories. Construct a CategoryFilter using a single category name A category name Check whether the filter matches a test The test to be matched Gets the element name Element name GlobalSettings is a place for setting default values used by the framework in performing asserts. Anything set through this class applies to the entire test run. It should not normally be used from within a test, since it is not thread-safe. Default tolerance for floating point equality Asserts on Files The Equals method throws an InvalidOperationException. This is done to make sure there is no mistake by calling this function. override the default ReferenceEquals to throw an InvalidOperationException. This implementation makes sure there is no mistake in calling this function as part of Assert. Verifies that two Streams are equal. Two Streams are considered equal if both are null, or if both have the same value byte for byte. If they are not equal an is thrown. The expected Stream The actual Stream The message to display if Streams are not equal Arguments to be used in formatting the message Verifies that two Streams are equal. Two Streams are considered equal if both are null, or if both have the same value byte for byte. If they are not equal an is thrown. The expected Stream The actual Stream Verifies that two files are equal. Two files are considered equal if both are null, or if both have the same value byte for byte. If they are not equal an is thrown. A file containing the value that is expected A file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Verifies that two files are equal. Two files are considered equal if both are null, or if both have the same value byte for byte. If they are not equal an is thrown. A file containing the value that is expected A file containing the actual value Verifies that two files are equal. Two files are considered equal if both are null, or if both have the same value byte for byte. If they are not equal an is thrown. The path to a file containing the value that is expected The path to a file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Verifies that two files are equal. Two files are considered equal if both are null, or if both have the same value byte for byte. If they are not equal an is thrown. The path to a file containing the value that is expected The path to a file containing the actual value Asserts that two Streams are not equal. If they are equal an is thrown. The expected Stream The actual Stream The message to be displayed when the two Stream are the same. Arguments to be used in formatting the message Asserts that two Streams are not equal. If they are equal an is thrown. The expected Stream The actual Stream Asserts that two files are not equal. If they are equal an is thrown. A file containing the value that is expected A file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Asserts that two files are not equal. If they are equal an is thrown. A file containing the value that is expected A file containing the actual value Asserts that two files are not equal. If they are equal an is thrown. The path to a file containing the value that is expected The path to a file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Asserts that two files are not equal. If they are equal an is thrown. The path to a file containing the value that is expected The path to a file containing the actual value Asserts that the file exists. If it does not exist an is thrown. A file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Asserts that the file exists. If it does not exist an is thrown. A file containing the actual value Asserts that the file exists. If it does not exist an is thrown. The path to a file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Asserts that the file exists. If it does not exist an is thrown. The path to a file containing the actual value Asserts that the file does not exist. If it does exist an is thrown. A file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Asserts that the file does not exist. If it does exist an is thrown. A file containing the actual value Asserts that the file does not exist. If it does exist an is thrown. The path to a file containing the actual value The message to display if Streams are not equal Arguments to be used in formatting the message Asserts that the file does not exist. If it does exist an is thrown. The path to a file containing the actual value Thrown when an assertion failed. The error message that explains the reason for the exception The exception that caused the current exception Serialization Constructor Gets the ResultState provided by this exception SomeItemsConstraint applies another constraint to each item in a collection, succeeding if any of them succeeds. Construct a SomeItemsConstraint on top of an existing constraint Apply the item constraint to each item in the collection, succeeding if any item succeeds. The display name of this Constraint for use by ToString(). The default value is the name of the constraint with trailing "Constraint" removed. Derived classes may set this to another name in their constructors. SameAsConstraint tests whether an object is identical to the object passed to its constructor Initializes a new instance of the class. The expected object. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure The Description of what this constraint tests, for use in messages and in the ConstraintResult. RegexConstraint can test whether a string matches the pattern provided. Initializes a new instance of the class. The pattern. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure ConstraintStatus represents the status of a ConstraintResult returned by a Constraint being applied to an actual value. The status has not yet been set The constraint succeeded The constraint failed An error occured in applying the constraint (reserved for future use) Attribute used to identify a method that is called immediately after each test is run. The method is guaranteed to be called, even if an exception is thrown. Marks a test to use a combinatorial join of any argument data provided. Since this is the default, the attribute is optional. Default constructor The PropertyNames class provides static constants for the standard property ids that NUnit uses on tests. The FriendlyName of the AppDomain in which the assembly is running The selected strategy for joining parameter data into test cases The process ID of the executing assembly The stack trace from any data provider that threw an exception. The reason a test was not run The author of the tests The ApartmentState required for running the test The categories applying to a test The Description of a test The number of threads to be used in running tests The maximum time in ms, above which the test is considered to have failed The ParallelScope associated with a test The number of times the test should be repeated Indicates that the test should be run on a separate thread The culture to be set for a test The UI culture to be set for a test The type that is under test The timeout value for the test The test will be ignored until the given date The optional Order the test will run in The MethodWrapper class wraps a MethodInfo so that it may be used in a platform-independent manner. Construct a MethodWrapper for a Type and a MethodInfo. Construct a MethodInfo for a given Type and method name. Gets the parameters of the method. Returns the Type arguments of a generic method or the Type parameters of a generic method definition. Replaces the type parameters of the method with the array of types provided and returns a new IMethodInfo. The type arguments to be used A new IMethodInfo with the type arguments replaced Returns an array of custom attributes of the specified type applied to this method Gets a value indicating whether one or more attributes of the spcified type are defined on the method. Invokes the method, converting any TargetInvocationException to an NUnitException. The object on which to invoke the method The argument list for the method The return value from the invoked method Override ToString() so that error messages in NUnit's own tests make sense Gets the Type from which this method was reflected. Gets the MethodInfo for this method. Gets the name of the method. Gets a value indicating whether the method is abstract. Gets a value indicating whether the method is public. Gets a value indicating whether the method contains unassigned generic type parameters. Gets a value indicating whether the method is a generic method. Gets a value indicating whether the MethodInfo represents the definition of a generic method. Gets the return Type of the method. Represents a constraint that succeeds if any of the members of a collection match a base constraint. Returns a constraint that will apply the argument to the members of a collection, succeeding if any of them succeed. The TestMethod class represents a Test implemented as a method. The ParameterSet used to create this test method Initializes a new instance of the class. The method to be used as a test. Initializes a new instance of the class. The method to be used as a test. The suite or fixture to which the new test will be added Overridden to return a TestCaseResult. A TestResult for this test. Returns a TNode representing the current result after adding it as a child of the supplied parent node. The parent node. If true, descendant results are included Gets a bool indicating whether the current test has any descendant tests. Gets this test's child tests A list of child tests Gets the name used for the top-level element in the XML representation of this test Returns the name of the method RangeConstraint tests whether two _values are within a specified range. Initializes a new instance of the class. from must be less than or equal to true Inclusive beginning of the range. Must be less than or equal to to. Inclusive end of the range. Must be greater than or equal to from. Test whether the constraint is satisfied by a given value The value to be tested True for success, false for failure Modifies the constraint to use an and returns self. Modifies the constraint to use an and returns self. Modifies the constraint to use a and returns self. Gets text describing a constraint Tests whether a value is greater than or equal to the value supplied to its constructor Initializes a new instance of the class. The expected value. Delegate used to delay evaluation of the actual value to be used in evaluating a constraint AttributeConstraint tests that a specified attribute is present on a Type or other provider and that the value of the attribute satisfies some other constraint. Constructs an AttributeConstraint for a specified attribute Type and base constraint. Determines whether the Type or other provider has the expected attribute and if its value matches the additional constraint specified. Returns a string representation of the constraint. ValueSourceAttribute indicates the source to be used to provide data for one parameter of a test method. Construct with the name of the factory - for use with languages that don't support params arrays. The name of a static method, property or field that will provide data. Construct with a Type and name - for use with languages that don't support params arrays. The Type that will provide data The name of a static method, property or field that will provide data. Gets an enumeration of data items for use as arguments for a test method parameter. The parameter for which data is needed An enumeration containing individual data items The name of a the method, property or fiend to be used as a source A Type to be used as a source Summary description for SetCultureAttribute. Construct given the name of a culture RandomAttribute is used to supply a set of random _values to a single parameter of a parameterized test. Construct a random set of values appropriate for the Type of the parameter on which the attribute appears, specifying only the count. Construct a set of ints within a specified range Construct a set of unsigned ints within a specified range Construct a set of longs within a specified range Construct a set of unsigned longs within a specified range Construct a set of shorts within a specified range Construct a set of unsigned shorts within a specified range Construct a set of doubles within a specified range Construct a set of floats within a specified range Construct a set of bytes within a specified range Construct a set of sbytes within a specified range Get the collection of _values to be used as arguments. Delegate used by tests that execute code and capture any thrown exception. TNode represents a single node in the XML representation of a Test or TestResult. It replaces System.Xml.XmlNode and System.Xml.Linq.XElement, providing a minimal set of methods for operating on the XML in a platform-independent manner. Constructs a new instance of TNode The name of the node Constructs a new instance of TNode with a value The name of the node The text content of the node Constructs a new instance of TNode with a value The name of the node The text content of the node Flag indicating whether to use CDATA when writing the text Create a TNode from it's XML text representation The XML text to be parsed A TNode Adds a new element as a child of the current node and returns it. The element name. The newly created child element Adds a new element with a value as a child of the current node and returns it. The element name The text content of the new element The newly created child element Adds a new element with a value as a child of the current node and returns it. The value will be output using a CDATA section. The element name The text content of the new element The newly created child element Adds an attribute with a specified name and value to the XmlNode. The name of the attribute. The value of the attribute. Finds a single descendant of this node matching an xpath specification. The format of the specification is limited to what is needed by NUnit and its tests. Finds all descendants of this node matching an xpath specification. The format of the specification is limited to what is needed by NUnit and its tests. Writes the XML representation of the node to an XmlWriter Gets the name of the node Gets the value of the node Gets a flag indicating whether the value should be output using CDATA. Gets the dictionary of attributes Gets a list of child nodes Gets the first ChildNode Gets the XML representation of this node. Class used to represent a list of XmlResults Class used to represent the attributes of a node Gets or sets the value associated with the specified key. Overridden to return null if attribute is not found. The key. Value of the attribute or null The ITestAssemblyRunner interface is implemented by classes that are able to execute a suite of tests loaded from an assembly. Loads the tests found in an Assembly, returning an indication of whether or not the load succeeded. File name of the assembly to load Dictionary of options to use in loading the test An ITest representing the loaded tests Loads the tests found in an Assembly, returning an indication of whether or not the load succeeded. The assembly to load Dictionary of options to use in loading the test An ITest representing the loaded tests Count Test Cases using a filter The filter to apply The number of test cases found Run selected tests and return a test result. The test is run synchronously, and the listener interface is notified as it progresses. Interface to receive ITestListener notifications. A test filter used to select tests to be run Run selected tests asynchronously, notifying the listener interface as it progresses. Interface to receive EventListener notifications. A test filter used to select tests to be run Wait for the ongoing run to complete. Time to wait in milliseconds True if the run completed, otherwise false Signal any test run that is in process to stop. Return without error if no test is running. If true, kill any test-running threads Gets the tree of loaded tests, or null if no tests have been loaded. Gets the tree of test results, if the test run is completed, otherwise null. Indicates whether a test has been loaded Indicates whether a test is currently running Indicates whether a test run is complete Modes in which the tolerance value for a comparison can be interpreted. The tolerance was created with a value, without specifying how the value would be used. This is used to prevent setting the mode more than once and is generally changed to Linear upon execution of the test. The tolerance is used as a numeric range within which two compared _values are considered to be equal. Interprets the tolerance as the percentage by which the two compared _values my deviate from each other. Compares two _values based in their distance in representable numbers. ResolvableConstraintExpression is used to represent a compound constraint being constructed at a point where the last operator may either terminate the expression or may have additional qualifying constraints added to it. It is used, for example, for a Property element or for an Exception element, either of which may be optionally followed by constraints that apply to the property or exception. Create a new instance of ResolvableConstraintExpression Create a new instance of ResolvableConstraintExpression, passing in a pre-populated ConstraintBuilder. Resolve the current expression to a Constraint Appends an And Operator to the expression Appends an Or operator to the expression. Negates the test of the constraint it wraps. Constructs a new NotOperator Returns a NotConstraint applied to its argument. SetUpFixtureAttribute is used to identify a SetUpFixture Build a SetUpFixture from type provided. Normally called for a Type on which the attribute has been placed. The type info of the fixture to be used. A SetUpFixture object as a TestSuite. Marks a test that must run in the MTA, causing it to run in a separate thread if necessary. On methods, you may also use MTAThreadAttribute to serve the same purpose. Construct a RequiresMTAAttribute The ResultState class represents the outcome of running a test. It contains two pieces of information. The Status of the test is an enum indicating whether the test passed, failed, was skipped or was inconclusive. The Label provides a more detailed breakdown for use by client runners. Initializes a new instance of the class. The TestStatus. Initializes a new instance of the class. The TestStatus. The label. Initializes a new instance of the class. The TestStatus. The stage at which the result was produced Initializes a new instance of the class. The TestStatus. The label. The stage at which the result was produced The result is inconclusive The test has been skipped. The test has been ignored. The test was skipped because it is explicit The test succeeded The test failed The test encountered an unexpected exception The test was cancelled by the user The test was not runnable. A suite failed because one or more child tests failed or had errors A suite failed in its OneTimeSetUp A suite had an unexpected exception in its OneTimeSetUp A suite had an unexpected exception in its OneTimeDown Get a new ResultState, which is the same as the current one but with the FailureSite set to the specified value. The FailureSite to use A new ResultState Determines whether the specified , is equal to this instance. The to compare with this instance. true if the specified is equal to this instance; otherwise, false. Returns a hash code for this instance. A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. Returns a that represents this instance. A that represents this instance. Gets the TestStatus for the test. The status. Gets the label under which this test result is categorized, if any. Gets the stage of test execution in which the failure or other result took place. The FailureSite enum indicates the stage of a test in which an error or failure occurred. Failure in the test itself Failure in the SetUp method Failure in the TearDown method Failure of a parent test Failure of a child test The TestFixtureData class represents a set of arguments and other parameter info to be used for a parameterized fixture. It is derived from TestFixtureParameters and adds a fluent syntax for use in initializing the fixture. Initializes a new instance of the class. The arguments. Initializes a new instance of the class. The argument. Initializes a new instance of the class. The first argument. The second argument. Initializes a new instance of the class. The first argument. The second argument. The third argument. Marks the test fixture as explicit. Marks the test fixture as explicit, specifying the reason. Ignores this TestFixture, specifying the reason. The reason. Represents a thread-safe first-in, first-out collection of objects. Specifies the type of elements in the queue. All public and protected members of are thread-safe and may be used concurrently from multiple threads. Initializes a new instance of the class. Initializes a new instance of the class that contains elements copied from the specified collection The collection whose elements are copied to the new . The argument is null. Adds an object to the end of the . The object to add to the end of the . The value can be a null reference (Nothing in Visual Basic) for reference types. Attempts to add an object to the . The object to add to the . The value can be a null reference (Nothing in Visual Basic) for reference types. true if the object was added successfully; otherwise, false. For , this operation will always add the object to the end of the and return true. Attempts to remove and return the object at the beginning of the . When this method returns, if the operation was successful, contains the object removed. If no object was available to be removed, the value is unspecified. true if an element was removed and returned from the beginning of the successfully; otherwise, false. Attempts to return an object from the beginning of the without removing it. When this method returns, contains an object from the beginning of the or an unspecified value if the operation failed. true if and object was returned successfully; otherwise, false. Returns an enumerator that iterates through a collection. An that can be used to iterate through the collection. Returns an enumerator that iterates through the . An enumerator for the contents of the . The enumeration represents a moment-in-time snapshot of the contents of the queue. It does not reflect any updates to the collection after was called. The enumerator is safe to use concurrently with reads from and writes to the queue. Copies the elements of the to an , starting at a particular index. The one-dimensional Array that is the destination of the elements copied from the . The Array must have zero-based indexing. The zero-based index in at which copying begins. is a null reference (Nothing in Visual Basic). is less than zero. is multidimensional. -or- does not have zero-based indexing. -or- is equal to or greater than the length of the -or- The number of elements in the source is greater than the available space from to the end of the destination . -or- The type of the source cannot be cast automatically to the type of the destination . Copies the elements to an existing one-dimensional Array, starting at the specified array index. The one-dimensional Array that is the destination of the elements copied from the . The Array must have zero-based indexing. The zero-based index in at which copying begins. is a null reference (Nothing in Visual Basic). is less than zero. is equal to or greater than the length of the -or- The number of elements in the source is greater than the available space from to the end of the destination . Copies the elements stored in the to a new array. A new array containing a snapshot of elements copied from the . Attempts to remove and return an object from the . When this method returns, if the operation was successful, contains the object removed. If no object was available to be removed, the value is unspecified. true if an element was removed and returned successfully; otherwise, false. For , this operation will attempt to remove the object from the beginning of the . Gets a value indicating whether access to the is synchronized with the SyncRoot. true if access to the is synchronized with the SyncRoot; otherwise, false. For , this property always returns false. Gets an object that can be used to synchronize access to the . This property is not supported. The SyncRoot property is not supported. Gets the number of elements contained in the . The number of elements contained in the . For determining whether the collection contains any items, use of the property is recommended rather than retrieving the number of items from the property and comparing it to 0. Gets a value that indicates whether the is empty. true if the is empty; otherwise, false. For determining whether the collection contains any items, use of this property is recommended rather than retrieving the number of items from the property and comparing it to 0. However, as this collection is intended to be accessed concurrently, it may be the case that another thread will modify the collection after returns, thus invalidating the result. Implementation of ITestAssemblyRunner Initializes a new instance of the class. The builder. Loads the tests found in an Assembly File name of the assembly to load Dictionary of option settings for loading the assembly True if the load was successful Loads the tests found in an Assembly The assembly to load Dictionary of option settings for loading the assembly True if the load was successful Count Test Cases using a filter The filter to apply The number of test cases found Run selected tests and return a test result. The test is run synchronously, and the listener interface is notified as it progresses. Interface to receive EventListener notifications. A test filter used to select tests to be run Run selected tests asynchronously, notifying the listener interface as it progresses. Interface to receive EventListener notifications. A test filter used to select tests to be run RunAsync is a template method, calling various abstract and virtual methods to be overridden by derived classes. Wait for the ongoing run to complete. Time to wait in milliseconds True if the run completed, otherwise false Signal any test run that is in process to stop. Return without error if no test is running. If true, kill any tests that are currently running Initiate the test run. Create the initial TestExecutionContext used to run tests The ITestListener specified in the RunAsync call Handle the the Completed event for the top level work item The tree of tests that was loaded by the builder The test result, if a run has completed Indicates whether a test is loaded Indicates whether a test is running Indicates whether a test run is complete Our settings, specified when loading the assembly The top level WorkItem created for the assembly as a whole The TestExecutionContext for the top level WorkItem ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.xml.meta ================================================ fileFormatVersion: 2 guid: 9c7ad350fb20c854a9112cf4156d1b6e TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom.meta ================================================ fileFormatVersion: 2 guid: 2347243c7aa3e224f9282dc94e6fc3b2 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35.meta ================================================ fileFormatVersion: 2 guid: a36d8b72880a8004f96ac54ce4598ff9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/package.json ================================================ { "displayName": "Custom NUnit", "name": "com.unity.ext.nunit", "version": "1.0.0", "unity": "2019.1", "description": "Custom version of the nunit package build to work with Unity. Used by the Unity Test Framework.", "keywords": ["nunit", "unittest", "test"], "category": "Libraries", "repository": { "type": "git", "url": "git@gitlab.cds.internal.unity3d.com/upm-packages/core/com.unity.ext.nunit.git", "revision": "c8f5044ffe6adb909f9836160b0bdaa30f2d1ec9" }, "dependencies": { } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/package.json.meta ================================================ fileFormatVersion: 2 guid: 8143d3a8390f2c64685e3bc272bd9e90 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/.editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/CHANGELOG.md ================================================ # Code Editor Package for Rider ## [1.1.0] - 2019-07-02 new setting to manage list of extensions to be opened with Rider avoid breaking everything on any unhandled exception in RiderScriptEditor cctor hide Rider settings, when different Editor is selected dynamically load only newer rider plugins path detection (work on unix symlinks) speed up for project generation lots of bug fixing ## [1.0.8] - 2019-05-20 Fix NullReferenceException when External editor was pointing to non-existing Rider everything was broken by null-ref. ## [1.0.7] - 2019-05-16 Initial migration steps from rider plugin to package. Fix OSX check and opening of files. ## [1.0.6] - 2019-04-30 Ensure asset database is refreshed when generating csproj and solution files. ## [1.0.5] - 2019-04-27 Add support for generating all csproj files. ## [1.0.4] - 2019-04-18 Fix relative package paths. Fix opening editor on mac. ## [1.0.3] - 2019-04-12 Fixing null reference issue for callbacks to Asset pipeline. ## [1.0.2] - 2019-01-01 ### This is the first release of *Unity Package rider_editor*. Using the newly created api to integrate Rider with Unity. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/CHANGELOG.md.meta ================================================ fileFormatVersion: 2 guid: 8645aa9c3c74fb34ba9499e14fb332b5 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/CONTRIBUTING.md ================================================ # Contributing ## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement) By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions. ## Once you have a change ready following these ground rules. Simply make a pull request ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/CONTRIBUTING.md.meta ================================================ fileFormatVersion: 2 guid: 5e83f8baac96eaa47bdd9ca781cd2002 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Documentation~/README.md ================================================ # Code Editor Package for Rider This package is not intended to be modified by users. Nor does it provide any api intended to be included in user projects. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/LICENSE.md ================================================ MIT License Copyright (c) 2019 Unity Technologies 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: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/LICENSE.md.meta ================================================ fileFormatVersion: 2 guid: 5598b14661b5f4c43bed757f34b6d172 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Discovery.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using JetBrains.Annotations; using Microsoft.Win32; using Unity.CodeEditor; using UnityEngine; namespace Packages.Rider.Editor { public interface IDiscovery { CodeEditor.Installation[] PathCallback(); } public class Discovery : IDiscovery { public CodeEditor.Installation[] PathCallback() { return RiderPathLocator.GetAllRiderPaths() .Select(riderInfo => new CodeEditor.Installation { Path = riderInfo.Path, Name = riderInfo.Presentation }) .OrderBy(a=>a.Name) .ToArray(); } } /// /// This code is a modified version of the JetBrains resharper-unity plugin listed here: /// https://github.com/JetBrains/resharper-unity/blob/master/unity/JetBrains.Rider.Unity.Editor/EditorPlugin/RiderPathLocator.cs /// public static class RiderPathLocator { #if !(UNITY_4_7 || UNITY_5_5) [UsedImplicitly] // Used in com.unity.ide.rider public static RiderInfo[] GetAllRiderPaths() { try { switch (SystemInfo.operatingSystemFamily) { case OperatingSystemFamily.Windows: { return CollectRiderInfosWindows(); } case OperatingSystemFamily.MacOSX: { return CollectRiderInfosMac(); } case OperatingSystemFamily.Linux: { return CollectAllRiderPathsLinux(); } } } catch (Exception e) { Debug.LogException(e); } return new RiderInfo[0]; } #endif #if RIDER_EDITOR_PLUGIN // can't be used in com.unity.ide.rider internal static RiderInfo[] GetAllFoundInfos(OperatingSystemFamilyRider operatingSystemFamily) { try { switch (operatingSystemFamily) { case OperatingSystemFamilyRider.Windows: { return CollectRiderInfosWindows(); } case OperatingSystemFamilyRider.MacOSX: { return CollectRiderInfosMac(); } case OperatingSystemFamilyRider.Linux: { return CollectAllRiderPathsLinux(); } } } catch (Exception e) { Debug.LogException(e); } return new RiderInfo[0]; } internal static string[] GetAllFoundPaths(OperatingSystemFamilyRider operatingSystemFamily) { return GetAllFoundInfos(operatingSystemFamily).Select(a=>a.Path).ToArray(); } #endif private static RiderInfo[] CollectAllRiderPathsLinux() { var home = Environment.GetEnvironmentVariable("HOME"); if (string.IsNullOrEmpty(home)) return new RiderInfo[0]; //$Home/.local/share/JetBrains/Toolbox/apps/Rider/ch-0/173.3994.1125/bin/rider.sh //$Home/.local/share/JetBrains/Toolbox/apps/Rider/ch-0/.channel.settings.json var toolboxRiderRootPath = Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider"); var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider.sh", false) .Select(a => new RiderInfo(a, true)).ToList(); //$Home/.local/share/applications/jetbrains-rider.desktop var shortcut = new FileInfo(Path.Combine(home, @".local/share/applications/jetbrains-rider.desktop")); if (shortcut.Exists) { var lines = File.ReadAllLines(shortcut.FullName); foreach (var line in lines) { if (!line.StartsWith("Exec=\"")) continue; var path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault(); if (string.IsNullOrEmpty(path)) continue; if (paths.Any(a => a.Path == path)) // avoid adding similar build as from toolbox continue; paths.Add(new RiderInfo(path, false)); } } // snap install var snapInstallPath = "/snap/rider/current/bin/rider.sh"; if (new FileInfo(snapInstallPath).Exists) paths.Add(new RiderInfo(snapInstallPath, false)); return paths.ToArray(); } private static RiderInfo[] CollectRiderInfosMac() { // "/Applications/*Rider*.app" var folder = new DirectoryInfo("/Applications"); if (!folder.Exists) return new RiderInfo[0]; var results = folder.GetDirectories("*Rider*.app") .Select(a => new RiderInfo(a.FullName, false)) .ToList(); // /Users/user/Library/Application Support/JetBrains/Toolbox/apps/Rider/ch-1/181.3870.267/Rider EAP.app var home = Environment.GetEnvironmentVariable("HOME"); if (!string.IsNullOrEmpty(home)) { var toolboxRiderRootPath = Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider"); var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "", "Rider*.app", true) .Select(a => new RiderInfo(a, true)); results.AddRange(paths); } return results.ToArray(); } internal static string GetBuildNumber(string path) { var file = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt())); if (!file.Exists) return string.Empty; var text = File.ReadAllText(file.FullName); if (text.Length > 3) return text.Substring(3); return string.Empty; } private static RiderInfo[] CollectRiderInfosWindows() { var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); var toolboxRiderRootPath = Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider"); var installPathsToolbox = CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider64.exe", false).ToList(); var installInfosToolbox = installPathsToolbox .Select(a => new RiderInfo(a, true)).ToList(); var installPaths = new List(); const string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; CollectPathsFromRegistry(registryKey, installPaths); const string wowRegistryKey = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"; CollectPathsFromRegistry(wowRegistryKey, installPaths); var installInfos = installPaths .Select(a => new RiderInfo(a, false)).ToList(); installInfos.AddRange(installInfosToolbox); return installInfos.ToArray(); } private static string GetRelativePathToBuildTxt() { switch (SystemInfo.operatingSystemFamily) { case OperatingSystemFamily.Windows: case OperatingSystemFamily.Linux: return "../../build.txt"; case OperatingSystemFamily.MacOSX: return "Contents/Resources/build.txt"; } throw new Exception("Unknown OS"); } private static void CollectPathsFromRegistry(string registryKey, List installPaths) { using (var key = Registry.LocalMachine.OpenSubKey(registryKey)) { if (key == null) return; foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider"))) { using (var subkey = key.OpenSubKey(subkeyName)) { var folderObject = subkey?.GetValue("InstallLocation"); if (folderObject == null) continue; var folder = folderObject.ToString(); var possiblePath = Path.Combine(folder, @"bin\rider64.exe"); if (File.Exists(possiblePath)) installPaths.Add(possiblePath); } } } } private static string[] CollectPathsFromToolbox(string toolboxRiderRootPath, string dirName, string searchPattern, bool isMac) { if (!Directory.Exists(toolboxRiderRootPath)) return new string[0]; var channelDirs = Directory.GetDirectories(toolboxRiderRootPath); var paths = channelDirs.SelectMany(channelDir => { try { // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D var historyFile = Path.Combine(channelDir, ".history.json"); if (File.Exists(historyFile)) { var json = File.ReadAllText(historyFile); var build = ToolboxHistory.GetLatestBuildFromJson(json); if (build != null) { var buildDir = Path.Combine(channelDir, build); var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir); if (executablePaths.Any()) return executablePaths; } } var channelFile = Path.Combine(channelDir, ".channel.settings.json"); if (File.Exists(channelFile)) { var json = File.ReadAllText(channelFile).Replace("active-application", "active_application"); var build = ToolboxInstallData.GetLatestBuildFromJson(json); if (build != null) { var buildDir = Path.Combine(channelDir, build); var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir); if (executablePaths.Any()) return executablePaths; } } // changes in toolbox json files format may brake the logic above, so return all found Rider installations return Directory.GetDirectories(channelDir) .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir)); } catch (Exception e) { // do not write to Debug.Log, just log it. Logger.Warn($"Failed to get RiderPath from {channelDir}", e); } return new string[0]; }) .Where(c => !string.IsNullOrEmpty(c)) .ToArray(); return paths; } private static string[] GetExecutablePaths(string dirName, string searchPattern, bool isMac, string buildDir) { var folder = new DirectoryInfo(Path.Combine(buildDir, dirName)); if (!folder.Exists) return new string[0]; if (!isMac) return new[] {Path.Combine(folder.FullName, searchPattern)}.Where(File.Exists).ToArray(); return folder.GetDirectories(searchPattern).Select(f => f.FullName) .Where(Directory.Exists).ToArray(); } // Disable the "field is never assigned" compiler warning. We never assign it, but Unity does. // Note that Unity disable this warning in the generated C# projects #pragma warning disable 0649 [Serializable] class ToolboxHistory { public List history; [CanBeNull] public static string GetLatestBuildFromJson(string json) { try { #if UNITY_4_7 || UNITY_5_5 return JsonConvert.DeserializeObject(json).history.LastOrDefault()?.item.build; #else return JsonUtility.FromJson(json).history.LastOrDefault()?.item.build; #endif } catch (Exception) { Logger.Warn($"Failed to get latest build from json {json}"); } return null; } } [Serializable] class ItemNode { public BuildNode item; } [Serializable] class BuildNode { public string build; } // ReSharper disable once ClassNeverInstantiated.Global [Serializable] class ToolboxInstallData { // ReSharper disable once InconsistentNaming public ActiveApplication active_application; [CanBeNull] public static string GetLatestBuildFromJson(string json) { try { #if UNITY_4_7 || UNITY_5_5 var toolbox = JsonConvert.DeserializeObject(json); #else var toolbox = JsonUtility.FromJson(json); #endif var builds = toolbox.active_application.builds; if (builds != null && builds.Any()) return builds.First(); } catch (Exception) { Logger.Warn($"Failed to get latest build from json {json}"); } return null; } } [Serializable] class ActiveApplication { // ReSharper disable once InconsistentNaming public List builds; } #pragma warning restore 0649 public struct RiderInfo { public string Presentation; public string BuildVersion; public string Path; public RiderInfo(string path, bool isToolbox) { BuildVersion = GetBuildNumber(path); Path = new FileInfo(path).FullName; // normalize separators var presentation = "Rider " + BuildVersion; if (isToolbox) presentation += " (JetBrains Toolbox)"; Presentation = presentation; } } private static class Logger { internal static void Warn(string message, Exception e = null) { #if RIDER_EDITOR_PLUGIN // can't be used in com.unity.ide.rider Log.GetLog(typeof(RiderPathLocator).Name).Warn(message); if (e != null) Log.GetLog(typeof(RiderPathLocator).Name).Warn(e); #else Debug.LogError(message); if (e != null) Debug.LogException(e); #endif } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Discovery.cs.meta ================================================ fileFormatVersion: 2 guid: dab656c79e1985c40b31faebcda44442 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/EditorPluginInterop.cs ================================================ using System; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using UnityEngine; namespace Packages.Rider.Editor { public static class EditorPluginInterop { private static string ourEntryPointTypeName = "JetBrains.Rider.Unity.Editor.PluginEntryPoint"; private static void DisableSyncSolutionOnceCallBack() { // RiderScriptableSingleton.Instance.CsprojProcessedOnce = true; // Otherwise EditorPlugin regenerates all on every AppDomain reload var assembly = GetEditorPluginAssembly(); if (assembly == null) return; var type = assembly.GetType("JetBrains.Rider.Unity.Editor.Utils.RiderScriptableSingleton"); if (type == null) return; var baseType = type.BaseType; if (baseType == null) return; var instance = baseType.GetProperty("Instance"); if (instance == null) return; var instanceVal = instance.GetValue(null); var member = type.GetProperty("CsprojProcessedOnce"); if (member==null) return; member.SetValue(instanceVal, true); } public static string LogPath { get { try { var assembly = GetEditorPluginAssembly(); if (assembly == null) return null; var type = assembly.GetType(ourEntryPointTypeName); if (type == null) return null; var field = type.GetField("LogPath", BindingFlags.NonPublic | BindingFlags.Static); if (field == null) return null; return field.GetValue(null) as string; } catch (Exception) { Debug.Log("Unable to do OpenFile to Rider from dll, fallback to com.unity.ide.rider implementation."); } return null; } } public static bool OpenFileDllImplementation(string path, int line, int column) { var openResult = false; // reflection for fast OpenFileLineCol, when Rider is started and protocol connection is established try { var assembly = GetEditorPluginAssembly(); if (assembly == null) return false; var type = assembly.GetType(ourEntryPointTypeName); if (type == null) return false; var field = type.GetField("OpenAssetHandler", BindingFlags.NonPublic | BindingFlags.Static); if (field == null) return false; var handlerInstance = field.GetValue(null); var method = handlerInstance.GetType() .GetMethod("OnOpenedAsset", new[] {typeof(string), typeof(int), typeof(int)}); if (method == null) return false; var assetFilePath = path; if (!string.IsNullOrEmpty(path)) assetFilePath = Path.GetFullPath(path); openResult = (bool) method.Invoke(handlerInstance, new object[] {assetFilePath, line, column}); } catch (Exception e) { Debug.Log("Unable to do OpenFile to Rider from dll, fallback to com.unity.ide.rider implementation."); Debug.LogException(e); } return openResult; } public static Assembly GetEditorPluginAssembly() { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var assembly = assemblies.FirstOrDefault(a => a.GetName().Name.Equals("JetBrains.Rider.Unity.Editor.Plugin.Full.Repacked")); return assembly; } public static bool EditorPluginIsLoadedFromAssets() { var currentDir = Directory.GetCurrentDirectory(); var assembly = GetEditorPluginAssembly(); if (assembly == null) return false; var location = assembly.Location; return location.StartsWith(currentDir, StringComparison.InvariantCultureIgnoreCase); } internal static void InitEntryPoint() { try { DisableSyncSolutionOnceCallBack(); // is require for Rider prior to 2019.2 var type = GetEditorPluginAssembly().GetType("JetBrains.Rider.Unity.Editor.AfterUnity56.EntryPoint"); if (type == null) type = GetEditorPluginAssembly().GetType("JetBrains.Rider.Unity.Editor.UnitTesting.EntryPoint"); // oldRider RuntimeHelpers.RunClassConstructor(type.TypeHandle); } catch (TypeInitializationException ex) { Debug.LogException(ex); if (ex.InnerException != null) Debug.LogException(ex.InnerException); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/EditorPluginInterop.cs.meta ================================================ fileFormatVersion: 2 guid: f9bd02a3a916be64c9b47b1305149423 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/LoggingLevel.cs ================================================ namespace Packages.Rider.Editor { public enum LoggingLevel { /// /// Do not use it in logging. Only in config to disable logging. /// OFF, /// For errors that lead to application failure FATAL, /// For errors that must be shown in Exception Browser ERROR, /// Suspicious situations but not errors WARN, /// Regular level for important events INFO, /// Additional info for debbuging VERBOSE, /// Methods & callstacks tracing, more than verbose TRACE, } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/LoggingLevel.cs.meta ================================================ fileFormatVersion: 2 guid: 71bb46b59a9a7a346bbab1e185c723df MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/PluginSettings.cs ================================================ using System.Reflection; using Unity.CodeEditor; using UnityEditor; using UnityEngine; namespace Packages.Rider.Editor { public class PluginSettings { public static LoggingLevel SelectedLoggingLevel { get => (LoggingLevel) EditorPrefs.GetInt("Rider_SelectedLoggingLevel", 0); set { EditorPrefs.SetInt("Rider_SelectedLoggingLevel", (int) value); } } public static bool OverrideLangVersion { get { return EditorPrefs.GetBool("Rider_OverrideLangVersion", false); } private set { EditorPrefs.SetBool("Rider_OverrideLangVersion", value);; } } public static string LangVersion { get { return EditorPrefs.GetString("Rider_LangVersion", "4"); } private set { EditorPrefs.SetString("Rider_LangVersion", value); } } public static bool LogEventsCollectorEnabled { get { return EditorPrefs.GetBool("Rider_LogEventsCollectorEnabled", true); } private set { EditorPrefs.SetBool("Rider_LogEventsCollectorEnabled", value); } } private static GUIStyle ourVersionInfoStyle = new GUIStyle() { normal = new GUIStyleState() { textColor = new Color(0, 0, 0, .6f), }, margin = new RectOffset(4, 4, 4, 4), }; /// /// Preferences menu layout /// /// /// Contains all 3 toggles: Enable/Disable; Debug On/Off; Writing Launch File On/Off /// [SettingsProvider] private static SettingsProvider RiderPreferencesItem() { if (!RiderScriptEditor.IsRiderInstallation(RiderScriptEditor.CurrentEditor)) return null; if (!RiderScriptEditor.ShouldLoadEditorPlugin(RiderScriptEditor.CurrentEditor)) return null; var provider = new SettingsProvider("Preferences/Rider", SettingsScope.User) { label = "Rider", keywords = new[] { "Rider" }, guiHandler = (searchContext) => { EditorGUIUtility.labelWidth = 200f; EditorGUILayout.BeginVertical(); GUILayout.BeginVertical(); LogEventsCollectorEnabled = EditorGUILayout.Toggle(new GUIContent("Pass Console to Rider:"), LogEventsCollectorEnabled); GUILayout.EndVertical(); OverrideLangVersion = EditorGUILayout.Toggle(new GUIContent("Override LangVersion:"), OverrideLangVersion); if (OverrideLangVersion) { var workaroundUrl = "https://gist.github.com/van800/875ce55eaf88d65b105d010d7b38a8d4"; var workaroundText = "Use this workaround if overriding doesn't work."; var helpLangVersion = @"Avoid overriding, unless there is no particular need."; LangVersion = EditorGUILayout.TextField( new GUIContent("LangVersion:", helpLangVersion), LangVersion); LinkButton(caption: workaroundText, url: workaroundUrl); EditorGUILayout.HelpBox(helpLangVersion, MessageType.None); } GUILayout.Label(""); if (!string.IsNullOrEmpty(EditorPluginInterop.LogPath)) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Log file:"); var previous = GUI.enabled; GUI.enabled = previous && SelectedLoggingLevel != LoggingLevel.OFF; var button = GUILayout.Button(new GUIContent("Open log")); if (button) { //UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(PluginEntryPoint.LogPath, 0); // works much faster than the commented code, when Rider is already started CodeEditor.CurrentEditor.OpenProject(EditorPluginInterop.LogPath, 0, 0); } GUI.enabled = previous; GUILayout.EndHorizontal(); } var loggingMsg = @"Sets the amount of Rider Debug output. If you are about to report an issue, please select Verbose logging level and attach Unity console output to the issue."; SelectedLoggingLevel = (LoggingLevel) EditorGUILayout.EnumPopup(new GUIContent("Logging Level:", loggingMsg), SelectedLoggingLevel); EditorGUILayout.HelpBox(loggingMsg, MessageType.None); var githubRepo = "https://github.com/JetBrains/resharper-unity"; var caption = $"{githubRepo}"; LinkButton(caption: caption, url: githubRepo); GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); var version = Assembly.GetExecutingAssembly().GetName().Version; GUILayout.Label("Plugin version: " + version, ourVersionInfoStyle); GUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } }; return provider; } private static void LinkButton(string caption, string url) { var style = GUI.skin.label; style.richText = true; var bClicked = GUILayout.Button(caption, style); var rect = GUILayoutUtility.GetLastRect(); rect.width = style.CalcSize(new GUIContent(caption)).x; EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link); if (bClicked) Application.OpenURL(url); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/PluginSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 1bfe12aa306c0c74db4f4f1a1a0ae5ce MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/ProjectGeneration.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using Packages.Rider.Editor.Util; using UnityEditor; using UnityEditor.Compilation; using UnityEditor.PackageManager; using UnityEditorInternal; using UnityEngine; namespace Packages.Rider.Editor { public interface IGenerator { bool SyncIfNeeded(IEnumerable affectedFiles, IEnumerable reimportedFiles); void Sync(); bool HasSolutionBeenGenerated(); string SolutionFile(); string ProjectDirectory { get; } void GenerateAll(bool generateAll); } public interface IAssemblyNameProvider { string GetAssemblyNameFromScriptPath(string path); IEnumerable GetAllAssemblies(Func shouldFileBePartOfSolution); IEnumerable GetAllAssetPaths(); UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath); } public struct TestSettings { public bool ShouldSync; public Dictionary SyncPath; } class AssemblyNameProvider : IAssemblyNameProvider { public string GetAssemblyNameFromScriptPath(string path) { return CompilationPipeline.GetAssemblyNameFromScriptPath(path); } public IEnumerable GetAllAssemblies(Func shouldFileBePartOfSolution) { return CompilationPipeline.GetAssemblies() .Where(i => 0 < i.sourceFiles.Length && i.sourceFiles.Any(shouldFileBePartOfSolution)); } public IEnumerable GetAllAssetPaths() { return AssetDatabase.GetAllAssetPaths(); } public UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath) { return UnityEditor.PackageManager.PackageInfo.FindForAssetPath(assetPath); } } public class ProjectGeneration : IGenerator { enum ScriptingLanguage { None, CSharp } public static readonly string MSBuildNamespaceUri = "http://schemas.microsoft.com/developer/msbuild/2003"; const string k_WindowsNewline = "\r\n"; /// /// Map source extensions to ScriptingLanguages /// static readonly Dictionary k_BuiltinSupportedExtensions = new Dictionary { {"cs", ScriptingLanguage.CSharp}, {"uxml", ScriptingLanguage.None}, {"uss", ScriptingLanguage.None}, {"shader", ScriptingLanguage.None}, {"compute", ScriptingLanguage.None}, {"cginc", ScriptingLanguage.None}, {"hlsl", ScriptingLanguage.None}, {"glslinc", ScriptingLanguage.None} }; string m_SolutionProjectEntryTemplate = string.Join("\r\n", @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""", @"EndProject").Replace(" ", "\t"); string m_SolutionProjectConfigurationTemplate = string.Join("\r\n", @" {{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", @" {{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU", @" {{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU", @" {{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU").Replace(" ", "\t"); static readonly string[] k_ReimportSyncExtensions = {".dll", ".asmdef"}; /// /// Map ScriptingLanguages to project extensions /// /*static readonly Dictionary k_ProjectExtensions = new Dictionary { { ScriptingLanguage.CSharp, ".csproj" }, { ScriptingLanguage.None, ".csproj" }, };*/ static readonly Regex k_ScriptReferenceExpression = new Regex( @"^Library.ScriptAssemblies.(?(?.*)\.dll$)", RegexOptions.Compiled | RegexOptions.IgnoreCase); string[] m_ProjectSupportedExtensions = new string[0]; bool m_ShouldGenerateAll; public string ProjectDirectory { get; } public void GenerateAll(bool generateAll) { m_ShouldGenerateAll = generateAll; } public TestSettings Settings { get; set; } readonly string m_ProjectName; readonly IAssemblyNameProvider m_AssemblyNameProvider; const string k_ToolsVersion = "4.0"; const string k_ProductVersion = "10.0.20506"; const string k_BaseDirectory = "."; const string k_TargetFrameworkVersion = "v4.7.1"; const string k_TargetLanguageVersion = "latest"; public ProjectGeneration() : this(Directory.GetParent(Application.dataPath).FullName, new AssemblyNameProvider()) { } public ProjectGeneration(string tempDirectory) : this(tempDirectory, new AssemblyNameProvider()) { } public ProjectGeneration(string tempDirectory, IAssemblyNameProvider assemblyNameProvider) { Settings = new TestSettings {ShouldSync = true}; ProjectDirectory = tempDirectory.Replace('\\', '/'); m_ProjectName = Path.GetFileName(ProjectDirectory); m_AssemblyNameProvider = assemblyNameProvider; } /// /// Syncs the scripting solution if any affected files are relevant. /// /// /// Whether the solution was synced. /// /// /// A set of files whose status has changed /// /// /// A set of files that got reimported /// public bool SyncIfNeeded(IEnumerable affectedFiles, IEnumerable reimportedFiles) { SetupProjectSupportedExtensions(); if (HasFilesBeenModified(affectedFiles, reimportedFiles)) { Sync(); return true; } return false; } bool HasFilesBeenModified(IEnumerable affectedFiles, IEnumerable reimportedFiles) { return affectedFiles.Any(ShouldFileBePartOfSolution) || reimportedFiles.Any(ShouldSyncOnReimportedAsset); } static bool ShouldSyncOnReimportedAsset(string asset) { return k_ReimportSyncExtensions.Contains(new FileInfo(asset).Extension); } public void Sync() { SetupProjectSupportedExtensions(); var types = GetAssetPostprocessorTypes(); bool externalCodeAlreadyGeneratedProjects = OnPreGeneratingCSProjectFiles(types); if (!externalCodeAlreadyGeneratedProjects) { GenerateAndWriteSolutionAndProjects(types); } OnGeneratedCSProjectFiles(types); } public bool HasSolutionBeenGenerated() { return File.Exists(SolutionFile()); } void SetupProjectSupportedExtensions() { m_ProjectSupportedExtensions = EditorSettings.projectGenerationUserExtensions; } bool ShouldFileBePartOfSolution(string file) { string extension = Path.GetExtension(file); // Exclude files coming from packages except if they are internalized. if (!m_ShouldGenerateAll && IsInternalizedPackagePath(file)) { return false; } // Dll's are not scripts but still need to be included.. if (extension == ".dll") return true; if (file.ToLower().EndsWith(".asmdef")) return true; return IsSupportedExtension(extension); } bool IsSupportedExtension(string extension) { extension = extension.TrimStart('.'); if (k_BuiltinSupportedExtensions.ContainsKey(extension)) return true; if (m_ProjectSupportedExtensions.Contains(extension)) return true; return false; } static ScriptingLanguage ScriptingLanguageFor(Assembly island) { return ScriptingLanguageFor(GetExtensionOfSourceFiles(island.sourceFiles)); } static string GetExtensionOfSourceFiles(string[] files) { return files.Length > 0 ? GetExtensionOfSourceFile(files[0]) : "NA"; } static string GetExtensionOfSourceFile(string file) { var ext = Path.GetExtension(file).ToLower(); ext = ext.Substring(1); //strip dot return ext; } static ScriptingLanguage ScriptingLanguageFor(string extension) { return k_BuiltinSupportedExtensions.TryGetValue(extension.TrimStart('.'), out var result) ? result : ScriptingLanguage.None; } public void GenerateAndWriteSolutionAndProjects(Type[] types) { // Only synchronize islands that have associated source files and ones that we actually want in the project. // This also filters out DLLs coming from .asmdef files in packages. var assemblies = m_AssemblyNameProvider.GetAllAssemblies(ShouldFileBePartOfSolution); var allAssetProjectParts = GenerateAllAssetProjectParts(); var monoIslands = assemblies.ToList(); SyncSolution(monoIslands, types); var allProjectIslands = RelevantIslandsForMode(monoIslands).ToList(); foreach (Assembly assembly in allProjectIslands) { var responseFileData = ParseResponseFileData(assembly); SyncProject(assembly, allAssetProjectParts, responseFileData, allProjectIslands, types); } } IEnumerable ParseResponseFileData(Assembly assembly) { var systemReferenceDirectories = CompilationPipeline.GetSystemAssemblyDirectories(assembly.compilerOptions.ApiCompatibilityLevel); Dictionary responseFilesData = assembly.compilerOptions.ResponseFiles.ToDictionary( x => x, x => CompilationPipeline.ParseResponseFile( Path.Combine(ProjectDirectory, x), ProjectDirectory, systemReferenceDirectories )); Dictionary responseFilesWithErrors = responseFilesData.Where(x => x.Value.Errors.Any()) .ToDictionary(x => x.Key, x => x.Value); if (responseFilesWithErrors.Any()) { foreach (var error in responseFilesWithErrors) foreach (var valueError in error.Value.Errors) { Debug.LogError($"{error.Key} Parse Error : {valueError}"); } } return responseFilesData.Select(x => x.Value); } Dictionary GenerateAllAssetProjectParts() { Dictionary stringBuilders = new Dictionary(); foreach (string asset in m_AssemblyNameProvider.GetAllAssetPaths()) { // Exclude files coming from packages except if they are internalized. if (!m_ShouldGenerateAll && IsInternalizedPackagePath(asset)) { continue; } string extension = Path.GetExtension(asset); if (IsSupportedExtension(extension) && ScriptingLanguage.None == ScriptingLanguageFor(extension)) { // Find assembly the asset belongs to by adding script extension and using compilation pipeline. var assemblyName = m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset + ".cs"); if (string.IsNullOrEmpty(assemblyName)) { continue; } assemblyName = FileSystemUtil.FileNameWithoutExtension(assemblyName); if (!stringBuilders.TryGetValue(assemblyName, out var projectBuilder)) { projectBuilder = new StringBuilder(); stringBuilders[assemblyName] = projectBuilder; } projectBuilder.Append(" ") .Append(k_WindowsNewline); } } var result = new Dictionary(); foreach (var entry in stringBuilders) result[entry.Key] = entry.Value.ToString(); return result; } bool IsInternalizedPackagePath(string file) { if (string.IsNullOrWhiteSpace(file)) { return false; } var packageInfo = m_AssemblyNameProvider.FindForAssetPath(file); if (packageInfo == null) { return false; } var packageSource = packageInfo.source; return packageSource != PackageSource.Embedded && packageSource != PackageSource.Local; } void SyncProject( Assembly island, Dictionary allAssetsProjectParts, IEnumerable responseFilesData, List allProjectIslands, Type[] types) { SyncProjectFileIfNotChanged(ProjectFile(island), ProjectText(island, allAssetsProjectParts, responseFilesData, allProjectIslands), types); } void SyncProjectFileIfNotChanged(string path, string newContents, Type[] types) { if (Path.GetExtension(path) == ".csproj") { newContents = OnGeneratedCSProject(path, newContents, types); } SyncFileIfNotChanged(path, newContents); } void SyncSolutionFileIfNotChanged(string path, string newContents, Type[] types) { newContents = OnGeneratedSlnSolution(path, newContents, types); SyncFileIfNotChanged(path, newContents); } static List SafeGetTypes(System.Reflection.Assembly a) { List ret; try { ret = a.GetTypes().ToList(); } catch (System.Reflection.ReflectionTypeLoadException rtl) { ret = rtl.Types.ToList(); } catch (Exception) { return new List(); } return ret.Where(r => r != null).ToList(); } static void OnGeneratedCSProjectFiles(Type[] types) { var args = new object[0]; foreach (var type in types) { var method = type.GetMethod("OnGeneratedCSProjectFiles", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); if (method == null) { continue; } method.Invoke(null, args); } } public static Type[] GetAssetPostprocessorTypes() { return TypeCache.GetTypesDerivedFrom().ToArray(); // doesn't find types from EditorPlugin, which is fine } static bool OnPreGeneratingCSProjectFiles(Type[] types) { bool result = false; foreach (var type in types) { var args = new object[0]; var method = type.GetMethod("OnPreGeneratingCSProjectFiles", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); if (method == null) { continue; } var returnValue = method.Invoke(null, args); if (method.ReturnType == typeof(bool)) { result |= (bool) returnValue; } } return result; } static string OnGeneratedCSProject(string path, string content, Type[] types) { foreach (var type in types) { var args = new[] {path, content}; var method = type.GetMethod("OnGeneratedCSProject", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); if (method == null) { continue; } var returnValue = method.Invoke(null, args); if (method.ReturnType == typeof(string)) { content = (string) returnValue; } } return content; } static string OnGeneratedSlnSolution(string path, string content, Type[] types) { foreach (var type in types) { var args = new[] {path, content}; var method = type.GetMethod("OnGeneratedSlnSolution", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); if (method == null) { continue; } var returnValue = method.Invoke(null, args); if (method.ReturnType == typeof(string)) { content = (string) returnValue; } } return content; } void SyncFileIfNotChanged(string filename, string newContents) { if (File.Exists(filename) && newContents == File.ReadAllText(filename)) { return; } if (Settings.ShouldSync) { File.WriteAllText(filename, newContents, Encoding.UTF8); } else { var utf8 = Encoding.UTF8; byte[] utfBytes = utf8.GetBytes(newContents); Settings.SyncPath[filename] = utf8.GetString(utfBytes, 0, utfBytes.Length); } } string ProjectText(Assembly assembly, Dictionary allAssetsProjectParts, IEnumerable responseFilesData, List allProjectIslands) { var projectBuilder = new StringBuilder(ProjectHeader(assembly, responseFilesData)); var references = new List(); var projectReferences = new List(); foreach (string file in assembly.sourceFiles) { if (!ShouldFileBePartOfSolution(file)) continue; var extension = Path.GetExtension(file).ToLower(); var fullFile = EscapedRelativePathFor(file); if (".dll" != extension) { projectBuilder.Append(" ").Append(k_WindowsNewline); } else { references.Add(fullFile); } } var assemblyName = FileSystemUtil.FileNameWithoutExtension(assembly.outputPath); // Append additional non-script files that should be included in project generation. if (allAssetsProjectParts.TryGetValue(assemblyName, out var additionalAssetsForProject)) projectBuilder.Append(additionalAssetsForProject); var islandRefs = references.Union(assembly.allReferences); foreach (string reference in islandRefs) { if (reference.EndsWith("/UnityEditor.dll", StringComparison.Ordinal) || reference.EndsWith("/UnityEngine.dll", StringComparison.Ordinal) || reference.EndsWith("\\UnityEditor.dll", StringComparison.Ordinal) || reference.EndsWith("\\UnityEngine.dll", StringComparison.Ordinal)) continue; var match = k_ScriptReferenceExpression.Match(reference); if (match.Success) { // assume csharp language // Add a reference to a project except if it's a reference to a script assembly // that we are not generating a project for. This will be the case for assemblies // coming from .assembly.json files in non-internalized packages. var dllName = match.Groups["dllname"].Value; if (allProjectIslands.Any(i => Path.GetFileName(i.outputPath) == dllName)) { projectReferences.Add(match); continue; } } string fullReference = Path.IsPathRooted(reference) ? reference : Path.Combine(ProjectDirectory, reference); AppendReference(fullReference, projectBuilder); } var responseRefs = responseFilesData.SelectMany(x => x.FullPathReferences.Select(r => r)); foreach (var reference in responseRefs) { AppendReference(reference, projectBuilder); } if (0 < projectReferences.Count) { projectBuilder.AppendLine(" "); projectBuilder.AppendLine(" "); foreach (Match reference in projectReferences) { var referencedProject = reference.Groups["project"].Value; projectBuilder.Append(" ").Append(k_WindowsNewline); projectBuilder.Append(" {") .Append(ProjectGuid(Path.Combine("Temp", reference.Groups["project"].Value + ".dll"))).Append("}") .Append(k_WindowsNewline); projectBuilder.Append(" ").Append(referencedProject).Append("").Append(k_WindowsNewline); projectBuilder.AppendLine(" "); } } projectBuilder.Append(ProjectFooter()); return projectBuilder.ToString(); } static void AppendReference(string fullReference, StringBuilder projectBuilder) { //replace \ with / and \\ with / var escapedFullPath = SecurityElement.Escape(fullReference); escapedFullPath = escapedFullPath.Replace("\\\\", "/").Replace("\\", "/"); projectBuilder.Append(" ").Append(k_WindowsNewline); projectBuilder.Append(" ").Append(escapedFullPath).Append("").Append(k_WindowsNewline); projectBuilder.Append(" ").Append(k_WindowsNewline); } public string ProjectFile(Assembly assembly) { return Path.Combine(ProjectDirectory, $"{FileSystemUtil.FileNameWithoutExtension(assembly.outputPath)}.csproj"); } public string SolutionFile() { return Path.Combine(ProjectDirectory, $"{m_ProjectName}.sln"); } string ProjectHeader( Assembly island, IEnumerable responseFilesData ) { var arguments = new object[] { k_ToolsVersion, k_ProductVersion, ProjectGuid(island.outputPath), InternalEditorUtility.GetEngineAssemblyPath(), InternalEditorUtility.GetEditorAssemblyPath(), string.Join(";", new[] {"DEBUG", "TRACE"}.Concat(EditorUserBuildSettings.activeScriptCompilationDefines).Concat(island.defines) .Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray()), MSBuildNamespaceUri, FileSystemUtil.FileNameWithoutExtension(island.outputPath), EditorSettings.projectGenerationRootNamespace, k_TargetFrameworkVersion, PluginSettings.OverrideLangVersion?PluginSettings.LangVersion:k_TargetLanguageVersion, k_BaseDirectory, island.compilerOptions.AllowUnsafeCode | responseFilesData.Any(x => x.Unsafe) }; try { return string.Format(GetProjectHeaderTemplate(), arguments); } catch (Exception) { throw new NotSupportedException( "Failed creating c# project because the c# project header did not have the correct amount of arguments, which is " + arguments.Length); } } static string GetSolutionText() { return string.Join("\r\n", @"", @"Microsoft Visual Studio Solution File, Format Version {0}", @"# Visual Studio {1}", @"{2}", @"Global", @" GlobalSection(SolutionConfigurationPlatforms) = preSolution", @" Debug|Any CPU = Debug|Any CPU", @" Release|Any CPU = Release|Any CPU", @" EndGlobalSection", @" GlobalSection(ProjectConfigurationPlatforms) = postSolution", @"{3}", @" EndGlobalSection", @" GlobalSection(SolutionProperties) = preSolution", @" HideSolutionNode = FALSE", @" EndGlobalSection", @"EndGlobal", @"").Replace(" ", "\t"); } static string GetProjectFooterTemplate() { return string.Join("\r\n", @" ", @" ", @" ", @"", @""); } static string GetProjectHeaderTemplate() { var header = new[] { @"", @"", @" ", @" {10}", @" <_TargetFrameworkDirectories>non_empty_path_generated_by_unity.rider.package", @" <_FullFrameworkReferenceAssemblyPaths>non_empty_path_generated_by_unity.rider.package", @" true", @" ", @" ", @" Debug", @" AnyCPU", @" {1}", @" 2.0", @" {8}", @" {{{2}}}", @" Library", @" Properties", @" {7}", @" {9}", @" 512", @" {11}", @" ", @" ", @" true", @" full", @" false", @" Temp\bin\Debug\", @" {5}", @" prompt", @" 4", @" 0169", @" {12}", @" ", @" ", @" pdbonly", @" true", @" Temp\bin\Release\", @" prompt", @" 4", @" 0169", @" {12}", @" " }; var forceExplicitReferences = new[] { @" ", @" true", @" true", @" false", @" false", @" false", @" " }; var itemGroupStart = new[] { @" " }; var footer = new[] { @" ", @" {3}", @" ", @" ", @" {4}", @" ", @" ", @" ", @"" }; var text = header.Concat(forceExplicitReferences).Concat(itemGroupStart).Concat(footer).ToArray(); return string.Join("\r\n", text); } void SyncSolution(IEnumerable islands, Type[] types) { SyncSolutionFileIfNotChanged(SolutionFile(), SolutionText(islands), types); } string SolutionText(IEnumerable islands) { var fileversion = "11.00"; var vsversion = "2010"; var relevantIslands = RelevantIslandsForMode(islands); string projectEntries = GetProjectEntries(relevantIslands); string projectConfigurations = string.Join(k_WindowsNewline, relevantIslands.Select(i => GetProjectActiveConfigurations(ProjectGuid(i.outputPath))).ToArray()); return string.Format(GetSolutionText(), fileversion, vsversion, projectEntries, projectConfigurations); } static IEnumerable RelevantIslandsForMode(IEnumerable islands) { IEnumerable relevantIslands = islands.Where(i => ScriptingLanguage.CSharp == ScriptingLanguageFor(i)); return relevantIslands; } /// /// Get a Project("{guid}") = "MyProject", "MyProject.unityproj", "{projectguid}" /// entry for each relevant language /// string GetProjectEntries(IEnumerable islands) { var projectEntries = islands.Select(i => string.Format( m_SolutionProjectEntryTemplate, SolutionGuid(i), FileSystemUtil.FileNameWithoutExtension(i.outputPath), Path.GetFileName(ProjectFile(i)), ProjectGuid(i.outputPath) )); return string.Join(k_WindowsNewline, projectEntries.ToArray()); } /// /// Generate the active configuration string for a given project guid /// string GetProjectActiveConfigurations(string projectGuid) { return string.Format( m_SolutionProjectConfigurationTemplate, projectGuid); } string EscapedRelativePathFor(string file) { var projectDir = ProjectDirectory.Replace('/', '\\'); file = file.Replace('/', '\\'); var path = SkipPathPrefix(file, projectDir); var packageInfo = m_AssemblyNameProvider.FindForAssetPath(path.Replace('\\', '/')); if (packageInfo != null) { // We have to normalize the path, because the PackageManagerRemapper assumes // dir seperators will be os specific. var absolutePath = Path.GetFullPath(NormalizePath(path)).Replace('/', '\\'); path = SkipPathPrefix(absolutePath, projectDir); } return SecurityElement.Escape(path); } static string SkipPathPrefix(string path, string prefix) { if (path.Replace("\\", "/").StartsWith($"{prefix}/")) return path.Substring(prefix.Length + 1); return path; } static string NormalizePath(string path) { if (Path.DirectorySeparatorChar == '\\') return path.Replace('/', Path.DirectorySeparatorChar); return path.Replace('\\', Path.DirectorySeparatorChar); } string ProjectGuid(string assembly) { return SolutionGuidGenerator.GuidForProject(m_ProjectName + FileSystemUtil.FileNameWithoutExtension(assembly)); } string SolutionGuid(Assembly island) { return SolutionGuidGenerator.GuidForSolution(m_ProjectName, GetExtensionOfSourceFiles(island.sourceFiles)); } static string ProjectFooter() { return GetProjectFooterTemplate(); } static string GetProjectExtension() { return ".csproj"; } } public static class SolutionGuidGenerator { public static string GuidForProject(string projectName) { return ComputeGuidHashFor(projectName + "salt"); } public static string GuidForSolution(string projectName, string sourceFileExtension) { if (sourceFileExtension.ToLower() == "cs") // GUID for a C# class library: http://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; return ComputeGuidHashFor(projectName); } static string ComputeGuidHashFor(string input) { var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(input)); return HashAsGuid(HashToString(hash)); } static string HashAsGuid(string hash) { var guid = hash.Substring(0, 8) + "-" + hash.Substring(8, 4) + "-" + hash.Substring(12, 4) + "-" + hash.Substring(16, 4) + "-" + hash.Substring(20, 12); return guid.ToUpper(); } static string HashToString(byte[] bs) { var sb = new StringBuilder(); foreach (byte b in bs) sb.Append(b.ToString("x2")); return sb.ToString(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/ProjectGeneration.cs.meta ================================================ fileFormatVersion: 2 guid: 8df45492ff0815a488744d61efcecba7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/RiderInitializer.cs ================================================ using System; using System.IO; using System.Linq; using System.Reflection; using UnityEngine; namespace Packages.Rider.Editor { internal class RiderInitializer { public void Initialize(string editorPath) { if (EditorPluginInterop.EditorPluginIsLoadedFromAssets()) { Debug.LogError($"Please delete {EditorPluginInterop.GetEditorPluginAssembly().Location}. Unity 2019.2+ loads it directly from Rider installation. To disable this, open Rider's settings, search and uncheck 'Automatically install and update Rider's Unity editor plugin'."); return; } var dllName = "JetBrains.Rider.Unity.Editor.Plugin.Full.Repacked.dll"; var relPath = "../../plugins/rider-unity/EditorPlugin"; if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX) relPath = "Contents/plugins/rider-unity/EditorPlugin"; var dllFile = new FileInfo(Path.Combine(Path.Combine(editorPath, relPath), dllName)); if (dllFile.Exists) { // doesn't lock assembly on disk var bytes = File.ReadAllBytes(dllFile.FullName); var pdbFile = new FileInfo(Path.ChangeExtension(dllFile.FullName, ".pdb")); if (pdbFile.Exists) { AppDomain.CurrentDomain.Load(bytes, File.ReadAllBytes(pdbFile.FullName)); } else { AppDomain.CurrentDomain.Load(bytes); // AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(dllFile.FullName)); // use this for external source debug } EditorPluginInterop.InitEntryPoint(); } else { Debug.Log((object) ($"Unable to find Rider EditorPlugin {dllFile.FullName} for Unity ")); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/RiderInitializer.cs.meta ================================================ fileFormatVersion: 2 guid: f5a0cc9645f0e2d4fb816156dcf3f4dd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/RiderScriptEditor.cs ================================================ using System; using System.Diagnostics; using System.IO; using System.Linq; using Packages.Rider.Editor.Util; using Unity.CodeEditor; using UnityEditor; using UnityEngine; using Debug = UnityEngine.Debug; namespace Packages.Rider.Editor { [InitializeOnLoad] public class RiderScriptEditor : IExternalCodeEditor { IDiscovery m_Discoverability; IGenerator m_ProjectGeneration; RiderInitializer m_Initiliazer = new RiderInitializer(); static RiderScriptEditor() { try { var projectGeneration = new ProjectGeneration(); var editor = new RiderScriptEditor(new Discovery(), projectGeneration); CodeEditor.Register(editor); var path = GetEditorRealPath(CodeEditor.CurrentEditorInstallation); if (IsRiderInstallation(path)) { if (!FileSystemUtil.EditorPathExists(path)) // previously used rider was removed { var newEditor = editor.Installations.Last().Path; CodeEditor.SetExternalScriptEditor(newEditor); path = newEditor; } editor.CreateSolutionIfDoesntExist(); if (ShouldLoadEditorPlugin(path)) { editor.m_Initiliazer.Initialize(path); } InitProjectFilesWatcher(); } } catch (Exception e) { Debug.LogException(e); } } private static void InitProjectFilesWatcher() { var watcher = new FileSystemWatcher(); watcher.Path = Directory.GetCurrentDirectory(); watcher.NotifyFilter = NotifyFilters.LastWrite; //Watch for changes in LastWrite times watcher.Filter = "*.*"; // Add event handlers. watcher.Changed += OnChanged; watcher.Created += OnChanged; watcher.EnableRaisingEvents = true; // Begin watching. AppDomain.CurrentDomain.DomainUnload += (EventHandler) ((_, __) => { watcher.Dispose(); }); } private static void OnChanged(object sender, FileSystemEventArgs e) { var extension = Path.GetExtension(e.FullPath); if (extension == ".sln" || extension == ".csproj") RiderScriptEditorData.instance.HasChanges = true; } private static string GetEditorRealPath(string path) { if (string.IsNullOrEmpty(path)) { return path; } if (!FileSystemUtil.EditorPathExists(path)) return path; if (SystemInfo.operatingSystemFamily != OperatingSystemFamily.Windows) { var realPath = FileSystemUtil.GetFinalPathName(path); // case of snap installation if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.Linux) { if (new FileInfo(path).Name.ToLowerInvariant() == "rider" && new FileInfo(realPath).Name.ToLowerInvariant() == "snap") { var snapInstallPath = "/snap/rider/current/bin/rider.sh"; if (new FileInfo(snapInstallPath).Exists) return snapInstallPath; } } // in case of symlink return realPath; } return path; } const string unity_generate_all = "unity_generate_all_csproj"; public RiderScriptEditor(IDiscovery discovery, IGenerator projectGeneration) { m_Discoverability = discovery; m_ProjectGeneration = projectGeneration; } private static string[] defaultExtensions { get { var customExtensions = new[] {"json", "asmdef", "log"}; return EditorSettings.projectGenerationBuiltinExtensions.Concat(EditorSettings.projectGenerationUserExtensions) .Concat(customExtensions).Distinct().ToArray(); } } private static string[] HandledExtensions { get { return HandledExtensionsString.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).Select(s => s.TrimStart('.', '*')) .ToArray(); } } private static string HandledExtensionsString { get { return EditorPrefs.GetString("Rider_UserExtensions", string.Join(";", defaultExtensions));} set { EditorPrefs.SetString("Rider_UserExtensions", value); } } private static bool SupportsExtension(string path) { var extension = Path.GetExtension(path); if (string.IsNullOrEmpty(extension)) return false; return HandledExtensions.Contains(extension.TrimStart('.')); } public void OnGUI() { var prevGenerate = EditorPrefs.GetBool(unity_generate_all, false); var generateAll = EditorGUILayout.Toggle("Generate all .csproj files.", prevGenerate); if (generateAll != prevGenerate) { EditorPrefs.SetBool(unity_generate_all, generateAll); } m_ProjectGeneration.GenerateAll(generateAll); if (ShouldLoadEditorPlugin(CurrentEditor)) { HandledExtensionsString = EditorGUILayout.TextField(new GUIContent("Extensions handled: "), HandledExtensionsString); } } public void SyncIfNeeded(string[] addedFiles, string[] deletedFiles, string[] movedFiles, string[] movedFromFiles, string[] importedFiles) { m_ProjectGeneration.SyncIfNeeded(addedFiles.Union(deletedFiles).Union(movedFiles).Union(movedFromFiles), importedFiles); } public void SyncAll() { AssetDatabase.Refresh(); if (RiderScriptEditorData.instance.HasChanges) { m_ProjectGeneration.Sync(); RiderScriptEditorData.instance.HasChanges = false; } } public void Initialize(string editorInstallationPath) // is called each time ExternalEditor is changed { m_ProjectGeneration.Sync(); // regenerate csproj and sln for new editor } public bool OpenProject(string path, int line, int column) { if (path != "" && !SupportsExtension(path)) // Assets - Open C# Project passes empty path here { return false; } if (path == "" && SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX) { // there is a bug in DllImplementation - use package implementation here instead https://github.cds.internal.unity3d.com/unity/com.unity.ide.rider/issues/21 return OpenOSXApp(path, line, column); } if (!IsUnityScript(path)) { var fastOpenResult = EditorPluginInterop.OpenFileDllImplementation(path, line, column); if (fastOpenResult) return true; } if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX) { return OpenOSXApp(path, line, column); } var solution = GetSolutionFile(path); // TODO: If solution file doesn't exist resync. solution = solution == "" ? "" : $"\"{solution}\""; var process = new Process { StartInfo = new ProcessStartInfo { FileName = CodeEditor.CurrentEditorInstallation, Arguments = $"{solution} -l {line} \"{path}\"", UseShellExecute = true, } }; process.Start(); return true; } private bool OpenOSXApp(string path, int line, int column) { var solution = GetSolutionFile(path); // TODO: If solution file doesn't exist resync. solution = solution == "" ? "" : $"\"{solution}\""; var pathArguments = path == "" ? "" : $"-l {line} \"{path}\""; var process = new Process { StartInfo = new ProcessStartInfo { FileName = "open", Arguments = $"-n \"{CodeEditor.CurrentEditorInstallation}\" --args {solution} {pathArguments}", CreateNoWindow = true, UseShellExecute = true, } }; process.Start(); return true; } private string GetSolutionFile(string path) { if (IsUnityScript(path)) { return Path.Combine(GetBaseUnityDeveloperFolder(), "Projects/CSharp/Unity.CSharpProjects.gen.sln"); } var solutionFile = m_ProjectGeneration.SolutionFile(); if (File.Exists(solutionFile)) { return solutionFile; } return ""; } static bool IsUnityScript(string path) { if (UnityEditor.Unsupported.IsDeveloperBuild()) { var baseFolder = GetBaseUnityDeveloperFolder().Replace("\\", "/"); var lowerPath = path.ToLowerInvariant().Replace("\\", "/"); if (lowerPath.Contains((baseFolder + "/Runtime").ToLowerInvariant()) || lowerPath.Contains((baseFolder + "/Editor").ToLowerInvariant())) { return true; } } return false; } static string GetBaseUnityDeveloperFolder() { return Directory.GetParent(EditorApplication.applicationPath).Parent.Parent.FullName; } public bool TryGetInstallationForPath(string editorPath, out CodeEditor.Installation installation) { if (FileSystemUtil.EditorPathExists(editorPath) && IsRiderInstallation(editorPath)) { var info = new RiderPathLocator.RiderInfo(editorPath, false); installation = new CodeEditor.Installation { Name = info.Presentation, Path = info.Path }; return true; } installation = default; return false; } public static bool IsRiderInstallation(string path) { if (string.IsNullOrEmpty(path)) { return false; } var fileInfo = new FileInfo(path); var filename = fileInfo.Name.ToLowerInvariant(); return filename.StartsWith("rider", StringComparison.Ordinal); } public static string CurrentEditor // works fast, doesn't validate if executable really exists => EditorPrefs.GetString("kScriptsDefaultApp"); public static bool ShouldLoadEditorPlugin(string path) { var ver = RiderPathLocator.GetBuildNumber(path); if (!Version.TryParse(ver, out var version)) return false; return version >= new Version("191.7141.156"); } public CodeEditor.Installation[] Installations => m_Discoverability.PathCallback(); public void CreateSolutionIfDoesntExist() { if (!m_ProjectGeneration.HasSolutionBeenGenerated()) { m_ProjectGeneration.Sync(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/RiderScriptEditor.cs.meta ================================================ fileFormatVersion: 2 guid: c4095d72f77fbb64ea39b8b3ca246622 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/RiderScriptEditorData.cs ================================================ using UnityEditor; using UnityEngine; namespace Packages.Rider.Editor { public class RiderScriptEditorData:ScriptableSingleton { [SerializeField] internal bool HasChanges = true; // sln/csproj files were changed } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/RiderScriptEditorData.cs.meta ================================================ fileFormatVersion: 2 guid: f079e3afd077fb94fa2bda74d6409499 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util/FileSystemUtil.cs ================================================ using System; using System.ComponentModel; using System.IO; using System.Text; using JetBrains.Annotations; using UnityEngine; namespace Packages.Rider.Editor.Util { public static class FileSystemUtil { [NotNull] public static string GetFinalPathName([NotNull] string path) { if (path == null) throw new ArgumentNullException("path"); // up to MAX_PATH. MAX_PATH on Linux currently 4096, on Mac OS X 1024 // doc: http://man7.org/linux/man-pages/man3/realpath.3.html var sb = new StringBuilder(8192); var result = LibcNativeInterop.realpath(path, sb); if (result == IntPtr.Zero) { throw new Win32Exception($"{path} was not resolved."); } return new FileInfo(sb.ToString()).FullName; } public static string FileNameWithoutExtension(string path) { if (string.IsNullOrEmpty(path)) { return ""; } var indexOfDot = -1; var indexOfSlash = 0; for (var i = path.Length - 1; i >= 0; i--) { if (indexOfDot == -1 && path[i] == '.') { indexOfDot = i; } if (indexOfSlash == 0 && path[i] == '/' || path[i] == '\\') { indexOfSlash = i + 1; break; } } if (indexOfDot == -1) { indexOfDot = path.Length - 1; } return path.Substring(indexOfSlash, indexOfDot - indexOfSlash); } public static bool EditorPathExists(string editorPath) { return SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX && new DirectoryInfo(editorPath).Exists || SystemInfo.operatingSystemFamily != OperatingSystemFamily.MacOSX && new FileInfo(editorPath).Exists; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util/FileSystemUtil.cs.meta ================================================ fileFormatVersion: 2 guid: bdbd564a9fdad0b738e76d030cad1204 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util/LibcNativeInterop.cs ================================================ using System; using System.Runtime.InteropServices; using System.Text; namespace Packages.Rider.Editor.Util { internal static class LibcNativeInterop { [DllImport("libc", SetLastError = true)] public static extern IntPtr realpath(string path, StringBuilder resolved_path); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util/LibcNativeInterop.cs.meta ================================================ fileFormatVersion: 2 guid: 071c17858dc6c47ada7b2a1f1ded5402 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util/UnityUtils.cs ================================================ using System; using System.Linq; using UnityEngine; namespace Packages.Rider.Editor.Util { public static class UnityUtils { internal static readonly string UnityApplicationVersion = Application.unityVersion; public static Version UnityVersion { get { var ver = UnityApplicationVersion.Split(".".ToCharArray()).Take(2).Aggregate((a, b) => a + "." + b); return new Version(ver); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util/UnityUtils.cs.meta ================================================ fileFormatVersion: 2 guid: 3ec9edad2de6c4df3a146b543a0fbc4c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/Util.meta ================================================ fileFormatVersion: 2 guid: 5e726086cd652f82087d59d67d2c24cd folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/com.unity.ide.rider.asmdef ================================================ { "name": "Unity.Rider.Editor", "references": [], "optionalUnityReferences": [], "includePlatforms": [ "Editor" ], "excludePlatforms": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor/com.unity.ide.rider.asmdef.meta ================================================ fileFormatVersion: 2 guid: d528c8c98d269ca44a06cd9624a03945 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider/Editor.meta ================================================ fileFormatVersion: 2 guid: 1b393f6b29a9ee84c803af1ab4944b71 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/Rider.meta ================================================ fileFormatVersion: 2 guid: 9129183a42052cd43b9c284d6dbd541e folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/package.json ================================================ { "name": "com.unity.ide.rider", "displayName": "Rider Editor", "description": "Code editor integration for supporting Rider as code editor for unity. Adds support for generating csproj files for code completion, auto discovery of installations, etc.", "version": "1.1.0", "unity": "2019.2", "unityRelease": "0a12", "dependencies": { "com.unity.ext.nunit": "1.0.0" }, "relatedPackages": { "com.unity.ide.rider.tests": "1.1.0" }, "repository": { "type": "git", "url": "git@github.cds.internal.unity3d.com:unity/com.unity.ide.rider.git", "revision": "80ad81f593b04a6104771ae0d01cc71773d07b02" } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.rider@1.1.0/package.json.meta ================================================ fileFormatVersion: 2 guid: 66c95bb3c74257f41bae2622511dc02d TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/CHANGELOG.md ================================================ # Code Editor Package for Visual Studio Code ## [1.1.3] - 2019-10-22 Exe version of vscode will use Normal ProcessWindowStyle while cmd will use Hidden ## [1.1.2] - 2019-08-30 Fixing OSX open command arguments ## [1.1.1] - 2019-08-19 Support for Player Project. Generates specific csproj files containing files, reference, defines, etc. that will show how the assembly will be compiled for a target platform. ## [1.1.0] - 2019-08-07 Adds support for choosing extensions to be opened with VSCode. This can be done through the GUI in Preferences. Avoids opening all extensions after the change in core unity. ## [1.0.7] - 2019-05-15 Fix various OSX specific issues. Generate project on load if they are not generated. Fix path recognition. ## [1.0.6] - 2019-04-30 Ensure asset database is refreshed when generating csproj and solution files. ## [1.0.5] - 2019-04-27 Add support for generating all csproj files. ## [1.0.4] - 2019-04-18 Fix relative package paths. Fix opening editor on mac. Add %LOCALAPPDATA%/Programs to the path of install paths. ## [1.0.3] - 2019-01-01 ### This is the first release of *Unity Package vscode_editor*. Using the newly created api to integrate Visual Studio Code with Unity. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/CHANGELOG.md.meta ================================================ fileFormatVersion: 2 guid: 4ddcdc3816429494a8bea67e973875f7 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/CONTRIBUTING.md ================================================ # Contributing ## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement) By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions. ## Once you have a change ready following these ground rules. Simply make a pull request ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/CONTRIBUTING.md.meta ================================================ fileFormatVersion: 2 guid: fcb9be00baf924c4183fc0313e6185c5 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Documentation~/README.md ================================================ # Code Editor Package for Visual Studio Code This package is not intended to be modified by users. Nor does it provide any api intended to be included in user projects. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/AssemblyNameProvider.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEditor.Compilation; namespace VSCodeEditor { public interface IAssemblyNameProvider { string GetAssemblyNameFromScriptPath(string path); IEnumerable GetAssemblies(Func shouldFileBePartOfSolution); IEnumerable GetAllAssetPaths(); UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath); ResponseFileData ParseResponseFile(string responseFilePath, string projectDirectory, string[] systemReferenceDirectories); } internal class AssemblyNameProvider : IAssemblyNameProvider { public string GetAssemblyNameFromScriptPath(string path) { return CompilationPipeline.GetAssemblyNameFromScriptPath(path); } public IEnumerable GetAssemblies(Func shouldFileBePartOfSolution) { return CompilationPipeline.GetAssemblies() .Where(i => 0 < i.sourceFiles.Length && i.sourceFiles.Any(shouldFileBePartOfSolution)); } public IEnumerable GetAllAssetPaths() { return AssetDatabase.GetAllAssetPaths(); } public UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath) { return UnityEditor.PackageManager.PackageInfo.FindForAssetPath(assetPath); } public ResponseFileData ParseResponseFile(string responseFilePath, string projectDirectory, string[] systemReferenceDirectories) { return CompilationPipeline.ParseResponseFile( responseFilePath, projectDirectory, systemReferenceDirectories ); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/AssemblyNameProvider.cs.meta ================================================ fileFormatVersion: 2 guid: 1d93ffb668978f7488211a331977b73b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/FileIO.cs ================================================ using System.IO; using System.Text; namespace VSCodeEditor { public interface IFileIO { bool Exists(string fileName); string ReadAllText(string fileName); void WriteAllText(string fileName, string content); void CreateDirectory(string pathName); } class FileIOProvider : IFileIO { public bool Exists(string fileName) { return File.Exists(fileName); } public string ReadAllText(string fileName) { return File.ReadAllText(fileName); } public void WriteAllText(string fileName, string content) { File.WriteAllText(fileName, content, Encoding.UTF8); } public void CreateDirectory(string pathName) { Directory.CreateDirectory(pathName); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/FileIO.cs.meta ================================================ fileFormatVersion: 2 guid: eb221cf55b3544646b0c3b6bc790080f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/GUIDGenerator.cs ================================================ namespace VSCodeEditor { public interface IGUIDGenerator { string ProjectGuid(string projectName, string assemblyName); string SolutionGuid(string projectName, string extension); } class GUIDProvider : IGUIDGenerator { public string ProjectGuid(string projectName, string assemblyName) { return SolutionGuidGenerator.GuidForProject(projectName + assemblyName); } public string SolutionGuid(string projectName, string extension) { return SolutionGuidGenerator.GuidForSolution(projectName, extension); // GetExtensionOfSourceFiles(assembly.sourceFiles) } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/GUIDGenerator.cs.meta ================================================ fileFormatVersion: 2 guid: e58bd3cca6475e54b93632bb6837aeea MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/ProjectGeneration.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using UnityEditor; using UnityEditor.Compilation; using UnityEditor.PackageManager; using UnityEngine; using UnityEngine.Profiling; namespace VSCodeEditor { public interface IGenerator { bool SyncIfNeeded(IEnumerable affectedFiles, IEnumerable reimportedFiles); void Sync(); string SolutionFile(); string ProjectDirectory { get; } void GenerateAll(bool generateAll); bool SolutionExists(); } public class ProjectGeneration : IGenerator { enum ScriptingLanguage { None, CSharp } public static readonly string MSBuildNamespaceUri = "http://schemas.microsoft.com/developer/msbuild/2003"; const string k_WindowsNewline = "\r\n"; const string k_SettingsJson = @"{ ""files.exclude"": { ""**/.DS_Store"":true, ""**/.git"":true, ""**/.gitignore"":true, ""**/.gitmodules"":true, ""**/*.booproj"":true, ""**/*.pidb"":true, ""**/*.suo"":true, ""**/*.user"":true, ""**/*.userprefs"":true, ""**/*.unityproj"":true, ""**/*.dll"":true, ""**/*.exe"":true, ""**/*.pdf"":true, ""**/*.mid"":true, ""**/*.midi"":true, ""**/*.wav"":true, ""**/*.gif"":true, ""**/*.ico"":true, ""**/*.jpg"":true, ""**/*.jpeg"":true, ""**/*.png"":true, ""**/*.psd"":true, ""**/*.tga"":true, ""**/*.tif"":true, ""**/*.tiff"":true, ""**/*.3ds"":true, ""**/*.3DS"":true, ""**/*.fbx"":true, ""**/*.FBX"":true, ""**/*.lxo"":true, ""**/*.LXO"":true, ""**/*.ma"":true, ""**/*.MA"":true, ""**/*.obj"":true, ""**/*.OBJ"":true, ""**/*.asset"":true, ""**/*.cubemap"":true, ""**/*.flare"":true, ""**/*.mat"":true, ""**/*.meta"":true, ""**/*.prefab"":true, ""**/*.unity"":true, ""build/"":true, ""Build/"":true, ""Library/"":true, ""library/"":true, ""obj/"":true, ""Obj/"":true, ""ProjectSettings/"":true, ""temp/"":true, ""Temp/"":true } }"; /// /// Map source extensions to ScriptingLanguages /// static readonly Dictionary k_BuiltinSupportedExtensions = new Dictionary { { "cs", ScriptingLanguage.CSharp }, { "uxml", ScriptingLanguage.None }, { "uss", ScriptingLanguage.None }, { "shader", ScriptingLanguage.None }, { "compute", ScriptingLanguage.None }, { "cginc", ScriptingLanguage.None }, { "hlsl", ScriptingLanguage.None }, { "glslinc", ScriptingLanguage.None }, { "template", ScriptingLanguage.None }, { "raytrace", ScriptingLanguage.None } }; string m_SolutionProjectEntryTemplate = string.Join("\r\n", @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""", @"EndProject").Replace(" ", "\t"); string m_SolutionProjectConfigurationTemplate = string.Join("\r\n", @" {{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", @" {{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU", @" {{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU", @" {{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU").Replace(" ", "\t"); static readonly string[] k_ReimportSyncExtensions = { ".dll", ".asmdef" }; /// /// Map ScriptingLanguages to project extensions /// /*static readonly Dictionary k_ProjectExtensions = new Dictionary { { ScriptingLanguage.CSharp, ".csproj" }, { ScriptingLanguage.None, ".csproj" }, };*/ static readonly Regex k_ScriptReferenceExpression = new Regex( @"^Library.ScriptAssemblies.(?(?.*)\.dll$)", RegexOptions.Compiled | RegexOptions.IgnoreCase); string[] m_ProjectSupportedExtensions = new string[0]; public string ProjectDirectory { get; } bool m_ShouldGenerateAll; public void GenerateAll(bool generateAll) { m_ShouldGenerateAll = generateAll; } readonly string m_ProjectName; readonly IAssemblyNameProvider m_AssemblyNameProvider; readonly IFileIO m_FileIOProvider; readonly IGUIDGenerator m_GUIDProvider; const string k_ToolsVersion = "4.0"; const string k_ProductVersion = "10.0.20506"; const string k_BaseDirectory = "."; const string k_TargetFrameworkVersion = "v4.7.1"; const string k_TargetLanguageVersion = "latest"; public ProjectGeneration(string tempDirectory) : this(tempDirectory, new AssemblyNameProvider(), new FileIOProvider(), new GUIDProvider()) { } public ProjectGeneration(string tempDirectory, IAssemblyNameProvider assemblyNameProvider, IFileIO fileIO, IGUIDGenerator guidGenerator) { ProjectDirectory = tempDirectory.Replace('\\', '/'); m_ProjectName = Path.GetFileName(ProjectDirectory); m_AssemblyNameProvider = assemblyNameProvider; m_FileIOProvider = fileIO; m_GUIDProvider = guidGenerator; } /// /// Syncs the scripting solution if any affected files are relevant. /// /// /// Whether the solution was synced. /// /// /// A set of files whose status has changed /// /// /// A set of files that got reimported /// public bool SyncIfNeeded(IEnumerable affectedFiles, IEnumerable reimportedFiles) { Profiler.BeginSample("SolutionSynchronizerSync"); SetupProjectSupportedExtensions(); // Don't sync if we haven't synced before if (SolutionExists() && HasFilesBeenModified(affectedFiles, reimportedFiles)) { Sync(); Profiler.EndSample(); return true; } Profiler.EndSample(); return false; } bool HasFilesBeenModified(IEnumerable affectedFiles, IEnumerable reimportedFiles) { return affectedFiles.Any(ShouldFileBePartOfSolution) || reimportedFiles.Any(ShouldSyncOnReimportedAsset); } static bool ShouldSyncOnReimportedAsset(string asset) { return k_ReimportSyncExtensions.Contains(new FileInfo(asset).Extension); } public void Sync() { SetupProjectSupportedExtensions(); GenerateAndWriteSolutionAndProjects(); } public bool SolutionExists() { return m_FileIOProvider.Exists(SolutionFile()); } void SetupProjectSupportedExtensions() { m_ProjectSupportedExtensions = EditorSettings.projectGenerationUserExtensions; } bool ShouldFileBePartOfSolution(string file) { string extension = Path.GetExtension(file); // Exclude files coming from packages except if they are internalized. if (!m_ShouldGenerateAll && IsInternalizedPackagePath(file)) { return false; } // Dll's are not scripts but still need to be included.. if (extension == ".dll") return true; if (file.ToLower().EndsWith(".asmdef")) return true; return IsSupportedExtension(extension); } bool IsSupportedExtension(string extension) { extension = extension.TrimStart('.'); if (k_BuiltinSupportedExtensions.ContainsKey(extension)) return true; if (m_ProjectSupportedExtensions.Contains(extension)) return true; return false; } static ScriptingLanguage ScriptingLanguageFor(Assembly island) { return ScriptingLanguageFor(GetExtensionOfSourceFiles(island.sourceFiles)); } static string GetExtensionOfSourceFiles(string[] files) { return files.Length > 0 ? GetExtensionOfSourceFile(files[0]) : "NA"; } static string GetExtensionOfSourceFile(string file) { var ext = Path.GetExtension(file).ToLower(); ext = ext.Substring(1); //strip dot return ext; } static ScriptingLanguage ScriptingLanguageFor(string extension) { return k_BuiltinSupportedExtensions.TryGetValue(extension.TrimStart('.'), out var result) ? result : ScriptingLanguage.None; } public void GenerateAndWriteSolutionAndProjects() { // Only synchronize islands that have associated source files and ones that we actually want in the project. // This also filters out DLLs coming from .asmdef files in packages. var assemblies = m_AssemblyNameProvider.GetAssemblies(ShouldFileBePartOfSolution); var allAssetProjectParts = GenerateAllAssetProjectParts(); SyncSolution(assemblies); var allProjectIslands = RelevantIslandsForMode(assemblies).ToList(); foreach (Assembly assembly in allProjectIslands) { var responseFileData = ParseResponseFileData(assembly); SyncProject(assembly, allAssetProjectParts, responseFileData, allProjectIslands); } WriteVSCodeSettingsFiles(); } IEnumerable ParseResponseFileData(Assembly assembly) { var systemReferenceDirectories = CompilationPipeline.GetSystemAssemblyDirectories(assembly.compilerOptions.ApiCompatibilityLevel); Dictionary responseFilesData = assembly.compilerOptions.ResponseFiles.ToDictionary(x => x, x => m_AssemblyNameProvider.ParseResponseFile( x, ProjectDirectory, systemReferenceDirectories )); Dictionary responseFilesWithErrors = responseFilesData.Where(x => x.Value.Errors.Any()) .ToDictionary(x => x.Key, x => x.Value); if (responseFilesWithErrors.Any()) { foreach (var error in responseFilesWithErrors) foreach (var valueError in error.Value.Errors) { Debug.LogError($"{error.Key} Parse Error : {valueError}"); } } return responseFilesData.Select(x => x.Value); } Dictionary GenerateAllAssetProjectParts() { Dictionary stringBuilders = new Dictionary(); foreach (string asset in m_AssemblyNameProvider.GetAllAssetPaths()) { // Exclude files coming from packages except if they are internalized. // TODO: We need assets from the assembly API if (!m_ShouldGenerateAll && IsInternalizedPackagePath(asset)) { continue; } string extension = Path.GetExtension(asset); if (IsSupportedExtension(extension) && ScriptingLanguage.None == ScriptingLanguageFor(extension)) { // Find assembly the asset belongs to by adding script extension and using compilation pipeline. var assemblyName = m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset + ".cs"); if (string.IsNullOrEmpty(assemblyName)) { continue; } assemblyName = Utility.FileNameWithoutExtension(assemblyName); if (!stringBuilders.TryGetValue(assemblyName, out var projectBuilder)) { projectBuilder = new StringBuilder(); stringBuilders[assemblyName] = projectBuilder; } projectBuilder.Append(" ").Append(k_WindowsNewline); } } var result = new Dictionary(); foreach (var entry in stringBuilders) result[entry.Key] = entry.Value.ToString(); return result; } bool IsInternalizedPackagePath(string file) { if (string.IsNullOrWhiteSpace(file)) { return false; } var packageInfo = m_AssemblyNameProvider.FindForAssetPath(file); if (packageInfo == null) { return false; } var packageSource = packageInfo.source; return packageSource != PackageSource.Embedded && packageSource != PackageSource.Local; } void SyncProject( Assembly island, Dictionary allAssetsProjectParts, IEnumerable responseFilesData, List allProjectIslands) { SyncProjectFileIfNotChanged(ProjectFile(island), ProjectText(island, allAssetsProjectParts, responseFilesData, allProjectIslands)); } void SyncProjectFileIfNotChanged(string path, string newContents) { SyncFileIfNotChanged(path, newContents); } void SyncSolutionFileIfNotChanged(string path, string newContents) { SyncFileIfNotChanged(path, newContents); } void SyncFileIfNotChanged(string filename, string newContents) { if (m_FileIOProvider.Exists(filename)) { var currentContents = m_FileIOProvider.ReadAllText(filename); if (currentContents == newContents) { return; } } m_FileIOProvider.WriteAllText(filename, newContents); } string ProjectText( Assembly assembly, Dictionary allAssetsProjectParts, IEnumerable responseFilesData, List allProjectIslands) { var projectBuilder = new StringBuilder(ProjectHeader(assembly, responseFilesData)); var references = new List(); var projectReferences = new List(); foreach (string file in assembly.sourceFiles) { if (!ShouldFileBePartOfSolution(file)) continue; var extension = Path.GetExtension(file).ToLower(); var fullFile = EscapedRelativePathFor(file); if (".dll" != extension) { projectBuilder.Append(" ").Append(k_WindowsNewline); } else { references.Add(fullFile); } } // Append additional non-script files that should be included in project generation. if (allAssetsProjectParts.TryGetValue(assembly.name, out var additionalAssetsForProject)) projectBuilder.Append(additionalAssetsForProject); var islandRefs = references.Union(assembly.allReferences); foreach (string reference in islandRefs) { var match = k_ScriptReferenceExpression.Match(reference); if (match.Success) { // assume csharp language // Add a reference to a project except if it's a reference to a script assembly // that we are not generating a project for. This will be the case for assemblies // coming from .assembly.json files in non-internalized packages. var dllName = match.Groups["dllname"].Value; if (allProjectIslands.Any(i => Path.GetFileName(i.outputPath) == dllName)) { projectReferences.Add(match); continue; } } string fullReference = Path.IsPathRooted(reference) ? reference : Path.Combine(ProjectDirectory, reference); AppendReference(fullReference, projectBuilder); } var responseRefs = responseFilesData.SelectMany(x => x.FullPathReferences.Select(r => r)); foreach (var reference in responseRefs) { AppendReference(reference, projectBuilder); } if (0 < projectReferences.Count) { projectBuilder.AppendLine(" "); projectBuilder.AppendLine(" "); foreach (Match reference in projectReferences) { var referencedProject = reference.Groups["project"].Value; projectBuilder.Append(" ").Append(k_WindowsNewline); projectBuilder.Append(" {").Append(ProjectGuid(Path.Combine("Temp", reference.Groups["project"].Value + ".dll"))).Append("}").Append(k_WindowsNewline); projectBuilder.Append(" ").Append(referencedProject).Append("").Append(k_WindowsNewline); projectBuilder.AppendLine(" "); } } projectBuilder.Append(ProjectFooter()); return projectBuilder.ToString(); } static void AppendReference(string fullReference, StringBuilder projectBuilder) { //replace \ with / and \\ with / var escapedFullPath = SecurityElement.Escape(fullReference); escapedFullPath = escapedFullPath.Replace("\\", "/"); escapedFullPath = escapedFullPath.Replace("\\\\", "/"); projectBuilder.Append(" ").Append(k_WindowsNewline); projectBuilder.Append(" ").Append(escapedFullPath).Append("").Append(k_WindowsNewline); projectBuilder.Append(" ").Append(k_WindowsNewline); } public string ProjectFile(Assembly assembly) { var fileBuilder = new StringBuilder(assembly.name); // if (!assembly.flags.HasFlag(AssemblyFlags.EditorAssembly) && m_PlayerAssemblies.Contains(assembly)) // { // fileBuilder.Append("-player"); // } fileBuilder.Append(".csproj"); return Path.Combine(ProjectDirectory, fileBuilder.ToString()); } public string SolutionFile() { return Path.Combine(ProjectDirectory, $"{m_ProjectName}.sln"); } string ProjectHeader( Assembly assembly, IEnumerable responseFilesData ) { // TODO: .Concat(EditorUserBuildSettings.activeScriptCompilationDefines) var arguments = new object[] { k_ToolsVersion, k_ProductVersion, ProjectGuid(assembly.name), string.Join(";", new[] { "DEBUG", "TRACE" }.Concat(assembly.defines).Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray()), MSBuildNamespaceUri, assembly.name, EditorSettings.projectGenerationRootNamespace, k_TargetFrameworkVersion, k_TargetLanguageVersion, k_BaseDirectory, assembly.compilerOptions.AllowUnsafeCode | responseFilesData.Any(x => x.Unsafe) }; try { return string.Format(GetProjectHeaderTemplate(), arguments); } catch (Exception) { throw new NotSupportedException("Failed creating c# project because the c# project header did not have the correct amount of arguments, which is " + arguments.Length); } } static string GetSolutionText() { return string.Join("\r\n", @"", @"Microsoft Visual Studio Solution File, Format Version {0}", @"# Visual Studio {1}", @"{2}", @"Global", @" GlobalSection(SolutionConfigurationPlatforms) = preSolution", @" Debug|Any CPU = Debug|Any CPU", @" Release|Any CPU = Release|Any CPU", @" EndGlobalSection", @" GlobalSection(ProjectConfigurationPlatforms) = postSolution", @"{3}", @" EndGlobalSection", @" GlobalSection(SolutionProperties) = preSolution", @" HideSolutionNode = FALSE", @" EndGlobalSection", @"EndGlobal", @"").Replace(" ", "\t"); } static string GetProjectFooterTemplate() { return string.Join("\r\n", @" ", @" ", @" ", @"", @""); } static string GetProjectHeaderTemplate() { var header = new[] { @"", @"", @" ", @" {8}", @" ", @" ", @" Debug", @" AnyCPU", @" {1}", @" 2.0", @" {6}", @" {{{2}}}", @" Library", @" Properties", @" {5}", @" {7}", @" 512", @" {9}", @" ", @" ", @" true", @" full", @" false", @" Temp\bin\Debug\", @" {3}", @" prompt", @" 4", @" 0169", @" {10}", @" ", @" ", @" pdbonly", @" true", @" Temp\bin\Release\", @" prompt", @" 4", @" 0169", @" {10}", @" " }; var forceExplicitReferences = new[] { @" ", @" true", @" true", @" false", @" false", @" false", @" " }; var itemGroupStart = new[] { @" ", @"" }; var text = header.Concat(forceExplicitReferences).Concat(itemGroupStart).ToArray(); return string.Join("\r\n", text); } void SyncSolution(IEnumerable islands) { SyncSolutionFileIfNotChanged(SolutionFile(), SolutionText(islands)); } string SolutionText(IEnumerable islands) { var fileversion = "11.00"; var vsversion = "2010"; var relevantIslands = RelevantIslandsForMode(islands); string projectEntries = GetProjectEntries(relevantIslands); string projectConfigurations = string.Join(k_WindowsNewline, relevantIslands.Select(i => GetProjectActiveConfigurations(ProjectGuid(i.name))).ToArray()); return string.Format(GetSolutionText(), fileversion, vsversion, projectEntries, projectConfigurations); } static IEnumerable RelevantIslandsForMode(IEnumerable islands) { IEnumerable relevantIslands = islands.Where(i => ScriptingLanguage.CSharp == ScriptingLanguageFor(i)); return relevantIslands; } /// /// Get a Project("{guid}") = "MyProject", "MyProject.csproj", "{projectguid}" /// entry for each relevant language /// string GetProjectEntries(IEnumerable islands) { var projectEntries = islands.Select(i => string.Format( m_SolutionProjectEntryTemplate, SolutionGuid(i), i.name, Path.GetFileName(ProjectFile(i)), ProjectGuid(i.name) )); return string.Join(k_WindowsNewline, projectEntries.ToArray()); } /// /// Generate the active configuration string for a given project guid /// string GetProjectActiveConfigurations(string projectGuid) { return string.Format( m_SolutionProjectConfigurationTemplate, projectGuid); } string EscapedRelativePathFor(string file) { var projectDir = ProjectDirectory.Replace('/', '\\'); file = file.Replace('/', '\\'); var path = SkipPathPrefix(file, projectDir); var packageInfo = m_AssemblyNameProvider.FindForAssetPath(path.Replace('\\', '/')); if (packageInfo != null) { // We have to normalize the path, because the PackageManagerRemapper assumes // dir seperators will be os specific. var absolutePath = Path.GetFullPath(NormalizePath(path)).Replace('/', '\\'); path = SkipPathPrefix(absolutePath, projectDir); } return SecurityElement.Escape(path); } static string SkipPathPrefix(string path, string prefix) { if (path.StartsWith($@"{prefix}\")) return path.Substring(prefix.Length + 1); return path; } static string NormalizePath(string path) { if (Path.DirectorySeparatorChar == '\\') return path.Replace('/', Path.DirectorySeparatorChar); return path.Replace('\\', Path.DirectorySeparatorChar); } string ProjectGuid(string assembly) { return m_GUIDProvider.ProjectGuid(m_ProjectName, assembly); } string SolutionGuid(Assembly island) { return m_GUIDProvider.SolutionGuid(m_ProjectName, GetExtensionOfSourceFiles(island.sourceFiles)); } static string ProjectFooter() { return GetProjectFooterTemplate(); } static string GetProjectExtension() { return ".csproj"; } void WriteVSCodeSettingsFiles() { var vsCodeDirectory = Path.Combine(ProjectDirectory, ".vscode"); if (!m_FileIOProvider.Exists(vsCodeDirectory)) m_FileIOProvider.CreateDirectory(vsCodeDirectory); var vsCodeSettingsJson = Path.Combine(vsCodeDirectory, "settings.json"); if (!m_FileIOProvider.Exists(vsCodeSettingsJson)) m_FileIOProvider.WriteAllText(vsCodeSettingsJson, k_SettingsJson); } } public static class SolutionGuidGenerator { public static string GuidForProject(string projectName) { return ComputeGuidHashFor(projectName + "salt"); } public static string GuidForSolution(string projectName, string sourceFileExtension) { if (sourceFileExtension.ToLower() == "cs") // GUID for a C# class library: http://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; return ComputeGuidHashFor(projectName); } static string ComputeGuidHashFor(string input) { var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(input)); return HashAsGuid(HashToString(hash)); } static string HashAsGuid(string hash) { var guid = hash.Substring(0, 8) + "-" + hash.Substring(8, 4) + "-" + hash.Substring(12, 4) + "-" + hash.Substring(16, 4) + "-" + hash.Substring(20, 12); return guid.ToUpper(); } static string HashToString(byte[] bs) { var sb = new StringBuilder(); foreach (byte b in bs) sb.Append(b.ToString("x2")); return sb.ToString(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration/ProjectGeneration.cs.meta ================================================ fileFormatVersion: 2 guid: 97d6c87381e3e51488b49f5891490b70 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/ProjectGeneration.meta ================================================ fileFormatVersion: 2 guid: c779d3735d950f341ba35154e8b3234b folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/Unity.com.unity.vscode.Editor.asmdef ================================================ { "name": "Unity.VSCode.Editor", "references": [], "optionalUnityReferences": [], "includePlatforms": [ "Editor" ], "excludePlatforms": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/Unity.com.unity.vscode.Editor.asmdef.meta ================================================ fileFormatVersion: 2 guid: 8b845b123ab418448a8be2935fa804e0 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/Utility.cs ================================================ namespace VSCodeEditor { public static class Utility { public static string FileNameWithoutExtension(string path) { if (string.IsNullOrEmpty(path)) { return ""; } var indexOfDot = -1; var indexOfSlash = 0; for (var i = path.Length - 1; i >= 0; i--) { if (indexOfDot == -1 && path[i] == '.') { indexOfDot = i; } if (indexOfSlash == 0 && path[i] == '/' || path[i] == '\\') { indexOfSlash = i + 1; break; } } if (indexOfDot == -1) { indexOfDot = path.Length; } return path.Substring(indexOfSlash, indexOfDot - indexOfSlash); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/Utility.cs.meta ================================================ fileFormatVersion: 2 guid: 1ac677c5ece15b443b2aaf7fae5842f7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/VSCodeDiscovery.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Unity.CodeEditor; namespace VSCodeEditor { public interface IDiscovery { CodeEditor.Installation[] PathCallback(); } public class VSCodeDiscovery : IDiscovery { List m_Installations; public CodeEditor.Installation[] PathCallback() { if (m_Installations == null) { m_Installations = new List(); FindInstallationPaths(); } return m_Installations.ToArray(); } void FindInstallationPaths() { string[] possiblePaths = #if UNITY_EDITOR_OSX { "/Applications/Visual Studio Code.app", "/Applications/Visual Studio Code - Insiders.app" }; #elif UNITY_EDITOR_WIN { GetProgramFiles() + @"/Microsoft VS Code/bin/code.cmd", GetProgramFiles() + @"/Microsoft VS Code/Code.exe", GetProgramFiles() + @"/Microsoft VS Code Insiders/bin/code-insiders.cmd", GetProgramFiles() + @"/Microsoft VS Code Insiders/Code.exe", GetLocalAppData() + @"/Programs/Microsoft VS Code/bin/code.cmd", GetLocalAppData() + @"/Programs/Microsoft VS Code/Code.exe", GetLocalAppData() + @"/Programs/Microsoft VS Code Insiders/bin/code-insiders.cmd", GetLocalAppData() + @"/Programs/Microsoft VS Code Insiders/Code.exe", }; #else { "/usr/bin/code", "/bin/code", "/usr/local/bin/code", "/var/lib/flatpak/exports/bin/com.visualstudio.code", "/snap/current/bin/code" }; #endif var existingPaths = possiblePaths.Where(VSCodeExists).ToList(); if (!existingPaths.Any()) { return; } var lcp = GetLongestCommonPrefix(existingPaths); switch (existingPaths.Count) { case 1: { var path = existingPaths.First(); m_Installations = new List { new CodeEditor.Installation { Path = path, Name = path.Contains("Insiders") ? "Visual Studio Code Insiders" : "Visual Studio Code" } }; break; } case 2 when existingPaths.Any(path => !(path.Substring(lcp.Length).Contains("/") || path.Substring(lcp.Length).Contains("\\"))): { goto case 1; } default: { m_Installations = existingPaths.Select(path => new CodeEditor.Installation { Name = $"Visual Studio Code Insiders ({path.Substring(lcp.Length)})", Path = path }).ToList(); break; } } } #if UNITY_EDITOR_WIN static string GetProgramFiles() { return Environment.GetEnvironmentVariable("ProgramFiles")?.Replace("\\", "/"); } static string GetLocalAppData() { return Environment.GetEnvironmentVariable("LOCALAPPDATA")?.Replace("\\", "/"); } #endif static string GetLongestCommonPrefix(List paths) { var baseLength = paths.First().Length; for (var pathIndex = 1; pathIndex < paths.Count; pathIndex++) { baseLength = Math.Min(baseLength, paths[pathIndex].Length); for (var i = 0; i < baseLength; i++) { if (paths[pathIndex][i] == paths[0][i]) continue; baseLength = i; break; } } return paths[0].Substring(0, baseLength); } static bool VSCodeExists(string path) { #if UNITY_EDITOR_OSX return System.IO.Directory.Exists(path); #else return new FileInfo(path).Exists; #endif } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/VSCodeDiscovery.cs.meta ================================================ fileFormatVersion: 2 guid: 380f7372e785c7d408552e2c760d269d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/VSCodeScriptEditor.cs ================================================ using System; using System.IO; using System.Linq; using System.Diagnostics; using UnityEditor; using UnityEngine; using Unity.CodeEditor; namespace VSCodeEditor { [InitializeOnLoad] public class VSCodeScriptEditor : IExternalCodeEditor { const string vscode_argument = "vscode_arguments"; const string vscode_generate_all = "unity_generate_all_csproj"; const string vscode_extension = "vscode_userExtensions"; static readonly GUIContent k_ResetArguments = EditorGUIUtility.TrTextContent("Reset argument"); string m_Arguments; IDiscovery m_Discoverability; IGenerator m_ProjectGeneration; static readonly string[] k_SupportedFileNames = { "code.exe", "visualstudiocode.app", "visualstudiocode-insiders.app", "vscode.app", "code.app", "code.cmd", "code-insiders.cmd", "code", "com.visualstudio.code" }; static bool IsOSX => Application.platform == RuntimePlatform.OSXEditor; static string DefaultApp => EditorPrefs.GetString("kScriptsDefaultApp"); static string DefaultArgument { get; } = "\"$(ProjectPath)\" -g \"$(File)\":$(Line):$(Column)"; string Arguments { get => m_Arguments ?? (m_Arguments = EditorPrefs.GetString(vscode_argument, DefaultArgument)); set { m_Arguments = value; EditorPrefs.SetString(vscode_argument, value); } } static string[] defaultExtensions { get { var customExtensions = new[] { "json", "asmdef", "log" }; return EditorSettings.projectGenerationBuiltinExtensions .Concat(EditorSettings.projectGenerationUserExtensions) .Concat(customExtensions) .Distinct().ToArray(); } } static string[] HandledExtensions { get { return HandledExtensionsString .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.TrimStart('.', '*')) .ToArray(); } } static string HandledExtensionsString { get => EditorPrefs.GetString(vscode_extension, string.Join(";", defaultExtensions)); set => EditorPrefs.SetString(vscode_extension, value); } public bool TryGetInstallationForPath(string editorPath, out CodeEditor.Installation installation) { var lowerCasePath = editorPath.ToLower(); var filename = Path.GetFileName(lowerCasePath).Replace(" ", ""); var installations = Installations; if (!k_SupportedFileNames.Contains(filename)) { installation = default; return false; } if (!installations.Any()) { installation = new CodeEditor.Installation { Name = "Visual Studio Code", Path = editorPath }; } else { try { installation = installations.First(inst => inst.Path == editorPath); } catch (InvalidOperationException) { installation = new CodeEditor.Installation { Name = "Visual Studio Code", Path = editorPath }; } } return true; } public void OnGUI() { Arguments = EditorGUILayout.TextField("External Script Editor Args", Arguments); if (GUILayout.Button(k_ResetArguments, GUILayout.Width(120))) { Arguments = DefaultArgument; } var prevGenerate = EditorPrefs.GetBool(vscode_generate_all, false); var generateAll = EditorGUILayout.Toggle("Generate all .csproj files.", prevGenerate); if (generateAll != prevGenerate) { EditorPrefs.SetBool(vscode_generate_all, generateAll); } m_ProjectGeneration.GenerateAll(generateAll); HandledExtensionsString = EditorGUILayout.TextField(new GUIContent("Extensions handled: "), HandledExtensionsString); } public void CreateIfDoesntExist() { if (!m_ProjectGeneration.SolutionExists()) { m_ProjectGeneration.Sync(); } } public void SyncIfNeeded(string[] addedFiles, string[] deletedFiles, string[] movedFiles, string[] movedFromFiles, string[] importedFiles) { m_ProjectGeneration.SyncIfNeeded(addedFiles.Union(deletedFiles).Union(movedFiles).Union(movedFromFiles), importedFiles); } public void SyncAll() { AssetDatabase.Refresh(); m_ProjectGeneration.Sync(); } public bool OpenProject(string path, int line, int column) { if (path != "" && !SupportsExtension(path)) // Assets - Open C# Project passes empty path here { return false; } if (line == -1) line = 1; if (column == -1) column = 0; string arguments; if (Arguments != DefaultArgument) { arguments = m_ProjectGeneration.ProjectDirectory != path ? CodeEditor.ParseArgument(Arguments, path, line, column) : m_ProjectGeneration.ProjectDirectory; } else { arguments = $@"""{m_ProjectGeneration.ProjectDirectory}"""; if (m_ProjectGeneration.ProjectDirectory != path && path.Length != 0) { arguments += $@" -g ""{path}"":{line}:{column}"; } } if (IsOSX) { return OpenOSX(arguments); } var app = DefaultApp; var process = new Process { StartInfo = new ProcessStartInfo { FileName = app, Arguments = arguments, WindowStyle = app.EndsWith(".cmd", StringComparison.OrdinalIgnoreCase) ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal, CreateNoWindow = true, UseShellExecute = true, } }; process.Start(); return true; } static bool OpenOSX(string arguments) { var process = new Process { StartInfo = new ProcessStartInfo { FileName = "open", Arguments = $"-n \"{DefaultApp}\" --args {arguments}", UseShellExecute = true, } }; process.Start(); return true; } static bool SupportsExtension(string path) { var extension = Path.GetExtension(path); if (string.IsNullOrEmpty(extension)) return false; return HandledExtensions.Contains(extension.TrimStart('.')); } public CodeEditor.Installation[] Installations => m_Discoverability.PathCallback(); public VSCodeScriptEditor(IDiscovery discovery, IGenerator projectGeneration) { m_Discoverability = discovery; m_ProjectGeneration = projectGeneration; } static VSCodeScriptEditor() { var editor = new VSCodeScriptEditor(new VSCodeDiscovery(), new ProjectGeneration(Directory.GetParent(Application.dataPath).FullName)); CodeEditor.Register(editor); if (IsVSCodeInstallation(CodeEditor.CurrentEditorInstallation)) { editor.CreateIfDoesntExist(); } } static bool IsVSCodeInstallation(string path) { if (string.IsNullOrEmpty(path)) { return false; } var lowerCasePath = path.ToLower(); var filename = Path .GetFileName(lowerCasePath.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar)) .Replace(" ", ""); return k_SupportedFileNames.Contains(filename); } public void Initialize(string editorInstallationPath) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor/VSCodeScriptEditor.cs.meta ================================================ fileFormatVersion: 2 guid: ac3f13489022aa34d861a0320a6917b9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/Editor.meta ================================================ fileFormatVersion: 2 guid: 58628227479c34542ac8c5193ccced84 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/LICENSE.md ================================================ MIT License Copyright (c) 2019 Unity Technologies 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: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/LICENSE.md.meta ================================================ fileFormatVersion: 2 guid: c9aabac5924106d4790d7b3a924ca34d DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/package.json ================================================ { "name": "com.unity.ide.vscode", "displayName": "Visual Studio Code Editor", "description": "Code editor integration for supporting Visual Studio Code as code editor for unity. Adds support for generating csproj files for intellisense purposes, auto discovery of installations, etc.", "version": "1.1.3", "unity": "2019.2", "unityRelease": "0a12", "dependencies": {}, "relatedPackages": { "com.unity.ide.vscode.tests": "1.1.3" }, "repository": { "type": "git", "url": "git@github.cds.internal.unity3d.com:unity/com.unity.ide.vscode.git", "revision": "7509767be271ef8ccdfaf82ea0fb71162a971d43" } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.ide.vscode@1.1.3/package.json.meta ================================================ fileFormatVersion: 2 guid: ffc6271f08270b64ca0aae9c49235d81 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/CHANGELOG.md ================================================ # Changelog ## [1.0.13] - 2019-05-07 - Fixed a regression where results from the player would no longer update correctly in the UI (case 1151147). ## [1.0.12] - 2019-04-16 - Added specific unity release to the package information. ## [1.0.11] - 2019-04-10 - Fixed a regression from 1.0.10 where test-started events were triggered multiple times after a domain reload. ## [1.0.10] - 2019-04-08 - Fixed an issue where test-started events would not be fired correctly after a test performing a domain reload (case 1141530). - The UI should correctly run tests inside a nested class, when that class is selected. - All actions should now correctly display a prefix when reporting test result. E.g. "TearDown :". - Errors logged with Debug.LogError in TearDowns now append the error, rather than overwriting the existing result (case 1114306). - Incorrect implementations of IWrapTestMethod and IWrapSetUpTearDown now gives a meaningful error. - Fixed a regression where the Test Framework would run TearDown in a base class before the inheriting class (case 1142553). - Fixed a regression introduced in 1.0.9 where tests with the Explicit attribute could no longer be executed. ## [1.0.9] - 2019-03-27 - Fixed an issue where a corrupt instance of the test runner window would block for a new being opened. - Added the required modules to the list of package requirements. - Fixed an issue where errors would happen if the test filter ui was clicked before the ui is done loading. - Fix selecting items with duplicate names in test hierarchy of Test Runner window (case 987587). - Fixed RecompileScripts instruction which we use in tests (case 1128994). - Fixed an issue where using multiple filters on tests would sometimes give an incorrect result. ## [1.0.7] - 2019-03-12 ### This is the first release of *Unity Package com.unity.test-framework*. - Migrated the test-framework from the current extension in unity. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/CHANGELOG.md.meta ================================================ fileFormatVersion: 2 guid: d691174143fd3774ba63d7c493633b99 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/CONTRIBUTING.md ================================================ # Contributing ## If you are interested in contributing, here are some ground rules: * ... Define guidelines & rules for what contributors need to know to successfully make Pull requests against your repo ... ## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement) By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions. ## Once you have a change ready following these ground rules. Simply make a pull request ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/CONTRIBUTING.md.meta ================================================ fileFormatVersion: 2 guid: 57d2ac5c7d5786e499d4794973fe0d4e TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/Documentation~/PlaymodeTestFramework.md ================================================ # Writing and executing tests in Unity Test Runner The Unity Test Runner tests your code in __Edit__ mode and __Play__ mode, as well as on target platforms such as Standalone, Android, or iOS. The documentation on this page discusses writing and executing tests in the the Unity Test Runner, and assumes you understand both [scripting](https://docs.unity3d.com/Manual/CreatingAndUsingScripts.html) and the [Unity Test Runner](About.md). Unity delivers test results in an XML format. For more information, see the [NUnit documentation on XML format test results](https://github.com/nunit/docs/wiki/Test-Result-XML-Format). ## UnityTestAttribute [UnityTestAttribute](https://docs.unity3d.com/ScriptReference/TestTools.UnityTestAttribute.html) requires you to return `IEnumerator`. In __Play__ mode, execute the test as a [coroutine](https://docs.unity3d.com/ScriptReference/Coroutine.html). In __Edit__ mode, you can yield `null` from the test, which skips the current frame. __Note:__ The WebGL and WSA platforms do not support `UnityTestAttribute`. ### Regular NUnit test (works in Edit mode and Play mode) ``` [Test] public void GameObject_CreatedWithGiven_WillHaveTheName() { var go = new GameObject("MyGameObject"); Assert.AreEqual("MyGameObject", go.name); } ``` ### Example in Play mode ``` [UnityTest] public IEnumerator GameObject_WithRigidBody_WillBeAffectedByPhysics() { var go = new GameObject(); go.AddComponent(); var originalPosition = go.transform.position.y; yield return new WaitForFixedUpdate(); Assert.AreNotEqual(originalPosition, go.transform.position.y); } ``` ### Example in Edit mode: ``` [UnityTest] public IEnumerator EditorUtility_WhenExecuted_ReturnsSuccess() { var utility = RunEditorUtilityInTheBackgroud(); while (utility.isRunning) { yield return null; } Assert.IsTrue(utility.isSuccess); } ``` ## UnityPlatformAttribute Use [UnityPlatformAttribute](https://docs.unity3d.com/ScriptReference/TestTools.UnityPlatformAttribute.html) to filter tests based on the the executing platform. It behaves like the [NUnit ](http://nunit.org/docs/2.5/platform.html)[PlatformAttribute](http://nunit.org/docs/2.5/platform.html). ``` [Test] [UnityPlatform (RuntimePlatform.WindowsPlayer)] public void TestMethod1() { Assert.AreEqual(Application.platform, RuntimePlatform.WindowsPlayer); } [Test] [UnityPlatform(exclude = new[] {RuntimePlatform.WindowsEditor })] public void TestMethod2() { Assert.AreNotEqual(Application.platform, RuntimePlatform.WindowsEditor); } ``` To only execute Editor tests on a given platform, you can also use `UnityPlatform` . ### PrebuildSetupAttriubte Use [PrebuildSetupAttribute](https://docs.unity3d.com/ScriptReference/TestTools.PrebuildSetupAttribute.html) if you need to perform any extra set-up before the test starts. To do this, specify the class type that implements the [IPrebuildSetup](https://docs.unity3d.com/ScriptReference/TestTools.IPrebuildSetup.html) interface. If you need to run the set-up code for the whole class (for example, if you want to execute some code before the test starts, such as Asset preparation or set-up required for a specific test), implement the `IPrebuildSetup` interface in the class for tests. ``` public class TestsWithPrebuildStep : IPrebuildSetup { public void Setup() { // Run this code before the tests are executed } [Test] //PrebuildSetupAttribute can be skipped because it's implemented in the same class [PrebuildSetup(typeof(TestsWithPrebuildStep))] public void Test() { (...) } } ``` Execute the `IPrebuildSetup` code before entering Play mode or building a player. Setup can use UnityEditor namespace and its function, but to avoid compilation errors, you must place it either in the *Editor* folder, or guard it with the `#if UNITY_EDITOR` directive. ## LogAssert A test fails if Unity logs a message other than a regular log or warning message. Use the [LogAssert](https://docs.unity3d.com/ScriptReference/TestTools.LogAssert.html) class to make a message expected in the log, so that the test does not fail when Unity logs that message. A test also reports as failed if an expected message does not appear, or if Unity does not log any regular log or warning messages. ### Example ``` [Test] public void LogAssertExample() { //Expect a regular log message LogAssert.Expect(LogType.Log, "Log message"); //A log message is expected so without the following line //the test would fail Debug.Log("Log message"); //An error log is printed Debug.LogError("Error message"); //Without expecting an error log, the test would fail LogAssert.Expect(LogType.Error, "Error message"); } ``` ## MonoBehaviourTest [MonoBehaviourTest](https://docs.unity3d.com/ScriptReference/TestTools.MonoBehaviourTest_1.html) is a [coroutine](https://docs.unity3d.com/ScriptReference/Coroutine.html), and a helper for writing [MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) tests. Yield `MonoBehaviourTest` from the [UnityTest](https://docs.unity3d.com/ScriptReference/TestTools.UnityTestAttribute.html) attribute to instantiate the specified MonoBehaviour and wait for it to finish executing. Implement the [IMonoBehaviourTest](https://docs.unity3d.com/ScriptReference/TestTools.IMonoBehaviourTest.html) interface to indicate when the test is done. ### Example ``` [UnityTest] public IEnumerator MonoBehaviourTest_Works() { yield return new MonoBehaviourTest(); } public class MyMonoBehaviourTest : MonoBehaviour, IMonoBehaviourTest { private int frameCount; public bool IsTestFinished { get { return frameCount > 10; } } void Update() { frameCount++; } } ``` ## Running tests on platforms In __Play__ mode, you can run tests on specific platforms. The target platform is always the current Platform selected in [Build Settings](https://docs.unity3d.com/Manual/BuildSettings.html) (menu: __File__ > __Build Settings__). Click __Run all in the player__ to build and run your tests on the currently active target platform. Note that your current platform displays in brackets on the button. For example, in the screenshot below, the button reads __Run all in player (StandaloneWindows)__, because the current platform is Windows. ![](UnityTestRunner-3.png) The test results display in the build once the test is complete. ![](UnityTestRunner-4.png) To get the test results from the platform to the Editor running the test, both need to be on same network. The application running on the platform reports back the test results, displays the tests executed, and shuts down. Note that some platforms do not support shutting down the application with [Application.Quit](https://docs.unity3d.com/ScriptReference/Application.Quit.html). These continue running after reporting test results. If Unity cannot instantiate the connection, you can visually see the tests succeed in the running application. Note that running tests on platforms with arguments, in this state, does not provide XML test results. ## Running from the command line To do this, run Unity with the following [command line arguments](https://docs.unity3d.com/Manual/CommandLineArguments.html): * `runTest` - Executes tests in the Project. * `testPlatform` - The platform you want to run tests on. * Available platforms: * `playmode` and `editmode`. Note that If unspecified, tests run in `editmode` by default. * Platform/Type convention is from the [BuildTarget](https://docs.unity3d.com/ScriptReference/BuildTarget.html) enum. The tested and official supported platforms: * [StandaloneWindows](https://docs.unity3d.com/ScriptReference/BuildTarget.StandaloneWindows.html) * [StandaloneWindows64](https://docs.unity3d.com/ScriptReference/BuildTarget.StandaloneWindows64.html) * [StandaloneOSXIntel](https://docs.unity3d.com/ScriptReference/BuildTarget.StandaloneOSXIntel.html) * [StandaloneOSXIntel64](https://docs.unity3d.com/ScriptReference/BuildTarget.StandaloneOSXIntel64.html) * [iOS](https://docs.unity3d.com/ScriptReference/BuildTarget.iOS.html) * [tvOS](https://docs.unity3d.com/ScriptReference/BuildTarget.tvOS.html) * [Android](https://docs.unity3d.com/ScriptReference/BuildTarget.Android.html) * [PS4](https://docs.unity3d.com/ScriptReference/BuildTarget.PS4.html) * [XboxOne](https://docs.unity3d.com/ScriptReference/BuildTarget.XboxOne.html) * `testResults` - The path indicating where Unity should save the result file. By default, Unity saves it in the Project’s root folder. ### Example The following example shows a command line argument on Windows. The specific line may differ depending on your operating system. ``` >Unity.exe -runTests -projectPath PATH_TO_YOUR_PROJECT -testResults C:\temp\results.xml -testPlatform editmode ``` __Tip:__ On Windows, in order to read the result code of the executed command, run the following: `start /WAIT Unity.exe ARGUMENT_LIST`. ## Comparison utilities The [UnityEngine.TestTools.Utils](https://docs.unity3d.com/ScriptReference/TestTools.Utils.Utils.html) namespace contains utility classes to compare [Vector2](https://docs.unity3d.com/ScriptReference/Vector2.html), [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html), [Vector4](https://docs.unity3d.com/ScriptReference/Vector4.html), [Quaternion](https://docs.unity3d.com/ScriptReference/Quaternion.html), [Color](https://docs.unity3d.com/ScriptReference/Color.html) and `float` types using NUnit constraints. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/Documentation~/com.unity.test-framework.md ================================================ # Unity Test Runner The Unity Test Runner is a tool that tests your code in both __Edit__ mode and __Play__ mode, and also on target platforms such as [Standalone](https://docs.unity3d.com/Manual/Standalone.html), Android, or iOS. To access the Unity Test Runner, go to __Window__ > __Test Runner__. ![](UnityTestRunner-0.png) The Unity Test Runner uses a Unity integration of the NUnit library, which is an open-source unit testing library for .Net languages. For more information about NUnit, see the [official NUnit website](http://www.nunit.org/) and the [NUnit documentation on GitHub](https://github.com/nunit/docs/wiki/NUnit-Documentation). [UnityTestAttribute](https://docs.unity3d.com/ScriptReference/TestTools.UnityTestAttribute.html) is the main addition to the standard NUnit library for the Unity Test Runner. This is a type of unit test that allows you to skip a frame from within a test (which allows background tasks to finish). To use `UnityTestAttribute`: * In __Play__ mode: Execute `UnityTestAttribute` as a [coroutine](https://docs.unity3d.com/ScriptReference/Coroutine.html). * In __Edit__ mode: Execute `UnityTestAttribute` in the [EditorApplication.update](https://docs.unity3d.com/ScriptReference/EditorApplication-update.html) callback loop. ## Known issues and limitations There are some known issues and limitations of the Unity Test Runner: * The WebGL and WSA platforms do not support `UnityTestAttribute`. * `UnityTest` does not support [Parameterized tests](https://github.com/nunit/docs/wiki/Parameterized-Tests) (except for `ValueSource`). ## How to use Unity Test Runner This page assumes you already have an understanding of unit testing and NUnit. If you are new to NUnit or would like more information, see to the [NUnit documentation on GitHub](https://github.com/nunit/docs/wiki/NUnit-Documentation). To open the Unity Test Runner, open Unity and go to __Window__ > __Test Runner__. If there are no tests in your Project, click the __Create Test Script in current folder__ button to create a basic test script. This button is greyed out if adding a test script would result in a compilation error. The conditions for adding a test script are in the [Editor](https://docs.unity3d.com/Manual/SpecialFolders.html) folder, or any folders using Assembly Definition files that reference test assemblies (NUnit, Unity Test Runner, and user script assemblies). ![](UnityTestRunner-1.png) You can also create test scripts by navigating to __Assets__ > __Create__ > __C# Test Script__. This option is disabled if adding a test script would result in a compilation error. __Note:__ Unity does not include test assemblies (NUnit, Unity TestRunner, and user script assemblies) when using the normal build pipeline, but does include them when using "Run on <Platform>" in the Test Runner Window. ### Testing in Edit mode In __Edit__ mode, Unity runs tests from the Test Runner window. Edit mode test scripts are defined by the file location you place them in. Valid locations: * Project [Editor](https://docs.unity3d.com/Manual/SpecialFolders.html) folder * Assembly Definition file that references test assemblies that are Editor-only * Precompiled assemblies that are in the Project’s [Editor](https://docs.unity3d.com/Manual/SpecialFolders.html) folder Click the __EditMode__ button, then click __Create Test Script in current folder__ to create a basic test script. Open and edit this in your preferred script editing software as required. Note: When running in __Edit__ mode, execute [UnityTestAttribute](https://docs.unity3d.com/ScriptReference/TestTools.UnityTestAttribute.html) in the [EditorApplication.update](https://docs.unity3d.com/ScriptReference/EditorApplication-update.html) callback loop. ### Testing in Play mode You need to place Play mode test scripts in a folder that an Assembly Definition file includes. The Assembly Definition file needs to reference test assemblies (Nunit and Unity TestRunner). Pre-defined Unity assemblies (such as *Assembly-CSharp.dll*) do not reference the defined assembly. This Assembly Definition file also needs to reference the assembly you want to test. This means that it’s only possible to test code defined by other Assembly Definition files. Unity does not include test assemblies in normal player builds; only when running through the Test Runner. If you need to test code in pre-defined assemblies, you can reference test assemblies from all the assemblies. However, you must manually remove these tests afterwards, so that Unity does not add them to the final player build. To do this: 1. Save your project. 2. Go to __Window__ > __Test Runner.__ 3. Click the small drop-down menu in the top-right of the window. 4. Click __Enable playmode tests for all assemblies__. 5. In the dialog box appears, click __OK__ to manually restart the Editor. ![](UnityTestRunner-2.png) __Note:__ Enabling __PlayMode__ tests for all assemblies includes additional assemblies in your Project’s build, which can increase your Project’s size as well as build time. To create __PlayMode__ test scripts, select __PlayMode__ in the Test Runner window and click __Create Test Script in current folder__. This button is greyed out if adding the script would result in a compilation error. __Note__: Execute [UnityTestAttribute](https://docs.unity3d.com/ScriptReference/TestTools.UnityTestAttribute.html) as a [coroutine](https://docs.unity3d.com/ScriptReference/Coroutine.html) when running in __Play__ mode. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/LICENSE.md ================================================ Test Framework copyright © 2019 Unity Technologies ApS Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/LICENSE.md.meta ================================================ fileFormatVersion: 2 guid: 3ec7596410385054a9e0bc90377fbe63 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/CallbacksDelegator.cs ================================================ using System; using System.Linq; using System.Text; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEditor.TestTools.TestRunner.Api { internal class CallbacksDelegator { private static CallbacksDelegator s_instance; public static CallbacksDelegator instance { get { if (s_instance == null) { s_instance = new CallbacksDelegator(CallbacksHolder.instance.GetAll, new TestAdaptorFactory()); } return s_instance; } } private readonly Func m_CallbacksProvider; private readonly ITestAdaptorFactory m_AdaptorFactory; public CallbacksDelegator(Func callbacksProvider, ITestAdaptorFactory adaptorFactory) { m_CallbacksProvider = callbacksProvider; m_AdaptorFactory = adaptorFactory; } public void RunStarted(ITest testsToRun) { var testRunnerTestsToRun = m_AdaptorFactory.Create(testsToRun); TryInvokeAllCallbacks(callbacks => callbacks.RunStarted(testRunnerTestsToRun)); } public void RunStartedRemotely(byte[] testsToRunData) { var testData = Deserialize(testsToRunData); var testsToRun = m_AdaptorFactory.BuildTree(testData); TryInvokeAllCallbacks(callbacks => callbacks.RunStarted(testsToRun)); } public void RunFinished(ITestResult testResults) { var testResult = m_AdaptorFactory.Create(testResults); TryInvokeAllCallbacks(callbacks => callbacks.RunFinished(testResult)); } public void RunFinishedRemotely(byte[] testResultsData) { var remoteTestResult = Deserialize(testResultsData); var testResult = m_AdaptorFactory.Create(remoteTestResult.results.First(), remoteTestResult); TryInvokeAllCallbacks(callbacks => callbacks.RunFinished(testResult)); } public void RunFailed(string failureMessage) { var nunitTestResult = new TestSuiteResult(new TestSuite("test")); nunitTestResult.SetResult(ResultState.Error, failureMessage); var testResult = m_AdaptorFactory.Create(nunitTestResult); TryInvokeAllCallbacks(callbacks => callbacks.RunFinished(testResult)); } public void TestStarted(ITest test) { var testRunnerTest = m_AdaptorFactory.Create(test); TryInvokeAllCallbacks(callbacks => callbacks.TestStarted(testRunnerTest)); } public void TestStartedRemotely(byte[] testStartedData) { var testData = Deserialize(testStartedData); var testsToRun = m_AdaptorFactory.BuildTree(testData); TryInvokeAllCallbacks(callbacks => callbacks.TestStarted(testsToRun)); } public void TestFinished(ITestResult result) { var testResult = m_AdaptorFactory.Create(result); TryInvokeAllCallbacks(callbacks => callbacks.TestFinished(testResult)); } public void TestFinishedRemotely(byte[] testResultsData) { var remoteTestResult = Deserialize(testResultsData); var testResult = m_AdaptorFactory.Create(remoteTestResult.results.First(), remoteTestResult); TryInvokeAllCallbacks(callbacks => callbacks.TestFinished(testResult)); } private void TryInvokeAllCallbacks(Action callbackAction) { foreach (var testRunnerApiCallback in m_CallbacksProvider()) { try { callbackAction(testRunnerApiCallback); } catch (Exception ex) { Debug.LogException(ex); } } } private static T Deserialize(byte[] data) { return JsonUtility.FromJson(Encoding.UTF8.GetString(data)); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/CallbacksDelegator.cs.meta ================================================ fileFormatVersion: 2 guid: 0de03ebd74e2b474fa23d05ab42d0cd8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/CallbacksDelegatorListener.cs ================================================ using UnityEngine; using UnityEngine.TestTools.TestRunner; namespace UnityEditor.TestTools.TestRunner.Api { internal class CallbacksDelegatorListener : ScriptableObject, ITestRunnerListener { public void RunStarted(NUnit.Framework.Interfaces.ITest testsToRun) { CallbacksDelegator.instance.RunStarted(testsToRun); } public void RunFinished(NUnit.Framework.Interfaces.ITestResult testResults) { CallbacksDelegator.instance.RunFinished(testResults); } public void TestStarted(NUnit.Framework.Interfaces.ITest test) { CallbacksDelegator.instance.TestStarted(test); } public void TestFinished(NUnit.Framework.Interfaces.ITestResult result) { CallbacksDelegator.instance.TestFinished(result); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/CallbacksDelegatorListener.cs.meta ================================================ fileFormatVersion: 2 guid: f3e1b3cbf3fac6a459b1a602167ad311 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/CallbacksHolder.cs ================================================ using System.Collections.Generic; using System.Linq; namespace UnityEditor.TestTools.TestRunner.Api { internal class CallbacksHolder : ScriptableSingleton { private List m_Callbacks = new List(); public void Add(ICallbacks callback, int priority) { m_Callbacks.Add(new CallbackWithPriority(callback, priority)); } public void Remove(ICallbacks callback) { m_Callbacks.RemoveAll(callbackWithPriority => callbackWithPriority.Callback == callback); } public ICallbacks[] GetAll() { return m_Callbacks.OrderByDescending(callback => callback.Priority).Select(callback => callback.Callback).ToArray(); } public void Clear() { m_Callbacks.Clear(); } private struct CallbackWithPriority { public ICallbacks Callback; public int Priority; public CallbackWithPriority(ICallbacks callback, int priority) { Callback = callback; Priority = priority; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/CallbacksHolder.cs.meta ================================================ fileFormatVersion: 2 guid: 4884ccc3528cb2e40a0e6f0a19a2b35b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ExecutionSettings.cs ================================================ namespace UnityEditor.TestTools.TestRunner.Api { internal class ExecutionSettings { public BuildTarget? targetPlatform; public ITestRunSettings overloadTestRunSettings; public Filter filter; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ExecutionSettings.cs.meta ================================================ fileFormatVersion: 2 guid: eea34a28297f9bc4c9f4c573bc8d5d1c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/Filter.cs ================================================ using System; using UnityEngine; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.Api { [Serializable] internal class Filter { [SerializeField] public TestMode testMode; [SerializeField] public string[] testNames; [SerializeField] public string[] groupNames; [SerializeField] public string[] categoryNames; [SerializeField] public string[] assemblyNames; public static Filter empty = new Filter(); internal TestRunnerFilter ToTestRunnerFilter() { return new TestRunnerFilter() { testNames = testNames, categoryNames = categoryNames, groupNames = groupNames, assemblyNames = assemblyNames }; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/Filter.cs.meta ================================================ fileFormatVersion: 2 guid: 05f92e4a2414cb144a92157752dfa324 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ICallbacks.cs ================================================ namespace UnityEditor.TestTools.TestRunner.Api { internal interface ICallbacks { void RunStarted(ITestAdaptor testsToRun); void RunFinished(ITestResultAdaptor result); void TestStarted(ITestAdaptor test); void TestFinished(ITestResultAdaptor result); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ICallbacks.cs.meta ================================================ fileFormatVersion: 2 guid: 93eea84e53d0226479c9a584f19427b5 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestAdaptor.cs ================================================ using System.Collections.Generic; using NUnit.Framework.Interfaces; namespace UnityEditor.TestTools.TestRunner.Api { internal interface ITestAdaptor { string Id { get; } string Name { get; } string FullName { get; } int TestCaseCount { get; } bool HasChildren { get; } bool IsSuite { get; } IEnumerable Children { get; } int TestCaseTimeout { get; } ITypeInfo TypeInfo { get; } IMethodInfo Method { get; } string[] Categories { get; } bool IsTestAssembly { get; } RunState RunState { get; } string Description { get; } string SkipReason { get; } string ParentId { get; } string UniqueName { get; } string ParentUniqueName { get; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestAdaptor.cs.meta ================================================ fileFormatVersion: 2 guid: 85dd7af03f02aea4aae13a3945e3b313 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestAdaptorFactory.cs ================================================ using System.Collections.Generic; using NUnit.Framework.Interfaces; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEditor.TestTools.TestRunner.Api { internal interface ITestAdaptorFactory { ITestAdaptor Create(ITest test); ITestAdaptor Create(RemoteTestData testData); ITestResultAdaptor Create(ITestResult testResult); ITestResultAdaptor Create(RemoteTestResultData testResult, RemoteTestResultDataWithTestData allData); ITestAdaptor BuildTree(RemoteTestResultDataWithTestData data); IEnumerator BuildTreeAsync(RemoteTestResultDataWithTestData data); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestAdaptorFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 803abab0f7e17044db56f8760186dbd1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestResultAdaptor.cs ================================================ using System; using System.Collections.Generic; using NUnit.Framework.Interfaces; namespace UnityEditor.TestTools.TestRunner.Api { internal interface ITestResultAdaptor { ITestAdaptor Test { get; } string Name { get; } /// Gets the full name of the test result string FullName { get; } string ResultState { get; } TestStatus TestStatus { get; } /// Gets the elapsed time for running the test in seconds double Duration { get; } /// Gets or sets the time the test started running. DateTime StartTime { get; } /// Gets or sets the time the test finished running. DateTime EndTime { get; } /// /// Gets the message associated with a test /// failure or with not running the test /// string Message { get; } /// /// Gets any stacktrace associated with an /// error or failure. Not available in /// the Compact Framework 1.0. /// string StackTrace { get; } /// /// Gets the number of asserts executed /// when running the test and all its children. /// int AssertCount { get; } /// /// Gets the number of test cases that failed /// when running the test and all its children. /// int FailCount { get; } /// /// Gets the number of test cases that passed /// when running the test and all its children. /// int PassCount { get; } /// /// Gets the number of test cases that were skipped /// when running the test and all its children. /// int SkipCount { get; } /// /// Gets the number of test cases that were inconclusive /// when running the test and all its children. /// int InconclusiveCount { get; } /// /// Indicates whether this result has any child results. /// Accessing HasChildren should not force creation of the /// Children collection in classes implementing this interface. /// bool HasChildren { get; } /// Gets the the collection of child results. IEnumerable Children { get; } /// Gets any text output written to this result. string Output { get; } TNode ToXml(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestResultAdaptor.cs.meta ================================================ fileFormatVersion: 2 guid: 4f90cfe4bf5cfb44f84a5b11387f2a42 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestRunSettings.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner.Api { internal interface ITestRunSettings : IDisposable { void Apply(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestRunSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 2ae2ce6274819484fa8747a28cebdf3a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestRunnerApi.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner.Api { interface ITestRunnerApi { void Execute(ExecutionSettings executionSettings); void RegisterCallbacks(T testCallbacks, int priority = 0) where T : ICallbacks; void UnregisterCallbacks(T testCallbacks) where T : ICallbacks; void RetrieveTestList(ExecutionSettings executionSettings, Action callback); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/ITestRunnerApi.cs.meta ================================================ fileFormatVersion: 2 guid: a7842a837a4b13e41ae16193db753418 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/RunState.cs ================================================ namespace UnityEditor.TestTools.TestRunner.Api { internal enum RunState { NotRunnable, Runnable, Explicit, Skipped, Ignored, } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/RunState.cs.meta ================================================ fileFormatVersion: 2 guid: 8bb59cb2f66d156418ca1bd1e2703233 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestAdaptor.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine.TestRunner.NUnitExtensions; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestRunner.TestLaunchers; using UnityEngine.TestTools.Utils; namespace UnityEditor.TestTools.TestRunner.Api { internal class TestAdaptor : ITestAdaptor { internal TestAdaptor(ITest test) : this(test, new ITest[0]) { } internal TestAdaptor(ITest test, ITest[] additionalChildren) { Id = test.Id; Name = test.Name; var childIndex = -1; if (test.Properties["childIndex"].Count > 0) { childIndex = (int)test.Properties["childIndex"][0]; } FullName = childIndex != -1 ? GetIndexedTestCaseName(test.FullName, childIndex) : test.FullName; TestCaseCount = test.TestCaseCount; HasChildren = test.HasChildren; IsSuite = test.IsSuite; Children = new[] {test.Tests, additionalChildren}.SelectMany(t => t).Select(t => new TestAdaptor(t)).ToArray(); if (UnityTestExecutionContext.CurrentContext != null) { TestCaseTimeout = UnityTestExecutionContext.CurrentContext.TestCaseTimeout; } else { TestCaseTimeout = CoroutineRunner.k_DefaultTimeout; } TypeInfo = test.TypeInfo; Method = test.Method; FullPath = GetFullPath(test); Categories = test.GetAllCategoriesFromTest().Distinct().ToArray(); IsTestAssembly = test is TestAssembly; RunState = (RunState)Enum.Parse(typeof(RunState), test.RunState.ToString()); Description = (string)test.Properties.Get(PropertyNames.Description); SkipReason = test.GetSkipReason(); ParentId = test.GetParentId(); UniqueName = test.GetUniqueName(); ParentUniqueName = test.GetParentUniqueName(); } internal TestAdaptor(RemoteTestData test) { Id = test.id; Name = test.name; FullName = test.ChildIndex != -1 ? GetIndexedTestCaseName(test.fullName, test.ChildIndex) : test.fullName; TestCaseCount = test.testCaseCount; HasChildren = test.hasChildren; IsSuite = test.isSuite; m_ChildrenIds = test.childrenIds; TestCaseTimeout = test.testCaseTimeout; Categories = test.Categories; IsTestAssembly = test.IsTestAssembly; RunState = (RunState)Enum.Parse(typeof(RunState), test.RunState.ToString()); Description = test.Description; SkipReason = test.SkipReason; ParentId = test.ParentId; UniqueName = test.UniqueName; ParentUniqueName = test.ParentUniqueName; } internal void ApplyChildren(IEnumerable allTests) { Children = m_ChildrenIds.Select(id => allTests.First(t => t.Id == id)).ToArray(); } public string Id { get; private set; } public string Name { get; private set; } public string FullName { get; private set; } public int TestCaseCount { get; private set; } public bool HasChildren { get; private set; } public bool IsSuite { get; private set; } public IEnumerable Children { get; private set; } public int TestCaseTimeout { get; private set; } public ITypeInfo TypeInfo { get; private set; } public IMethodInfo Method { get; private set; } public string FullPath { get; private set; } private string[] m_ChildrenIds; public string[] Categories { get; private set; } public bool IsTestAssembly { get; private set; } public RunState RunState { get; } public string Description { get; } public string SkipReason { get; } public string ParentId { get; } public string UniqueName { get; } public string ParentUniqueName { get; } private static string GetFullPath(ITest test) { if (test.Parent != null && test.Parent.Parent != null) return GetFullPath(test.Parent) + "/" + test.Name; return test.Name; } private static string GetIndexedTestCaseName(string fullName, int index) { var generatedTestSuffix = " GeneratedTestCase" + index; if (fullName.EndsWith(")")) { // Test names from generated TestCaseSource look like Test(TestCaseSourceType) // This inserts a unique test case index in the name, so that it becomes Test(TestCaseSourceType GeneratedTestCase0) return fullName.Substring(0, fullName.Length - 1) + generatedTestSuffix + fullName[fullName.Length - 1]; } // In some cases there can be tests with duplicate names generated in other ways and they won't have () in their name // We just append a suffix at the end of the name in that case return fullName + generatedTestSuffix; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestAdaptor.cs.meta ================================================ fileFormatVersion: 2 guid: 6e0e62db88935c74288c97c907243bd0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestAdaptorFactory.cs ================================================ using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEditor.TestTools.TestRunner.Api { internal class TestAdaptorFactory : ITestAdaptorFactory { public ITestAdaptor Create(ITest test) { return new TestAdaptor(test); } public ITestAdaptor Create(RemoteTestData testData) { return new TestAdaptor(testData); } public ITestResultAdaptor Create(ITestResult testResult) { return new TestResultAdaptor(testResult); } public ITestResultAdaptor Create(RemoteTestResultData testResult, RemoteTestResultDataWithTestData allData) { return new TestResultAdaptor(testResult, allData); } public ITestAdaptor BuildTree(RemoteTestResultDataWithTestData data) { var tests = data.tests.Select(remoteTestData => new TestAdaptor(remoteTestData)).ToList(); foreach (var test in tests) { test.ApplyChildren(tests); } return tests.First(); } public IEnumerator BuildTreeAsync(RemoteTestResultDataWithTestData data) { var tests = data.tests.Select(remoteTestData => new TestAdaptor(remoteTestData)).ToList(); for (var index = 0; index < tests.Count; index++) { var test = tests[index]; test.ApplyChildren(tests); if (index % 100 == 0) { yield return null; } } yield return tests.First(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestAdaptorFactory.cs.meta ================================================ fileFormatVersion: 2 guid: d0663d520c26b7c48a4135599e66acf8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestLauncherFactory.cs ================================================ using System; using UnityEngine.TestTools; using UnityEngine.TestTools.TestRunner; namespace UnityEditor.TestTools.TestRunner.Api { internal class TestLauncherFactory { internal TestLauncherBase GetLauncher(ExecutionSettings executionSettings) { if (executionSettings.filter.testMode == TestMode.EditMode) { return GetEditModeLauncher(executionSettings.filter); } else { var settings = PlaymodeTestsControllerSettings.CreateRunnerSettings(executionSettings.filter.ToTestRunnerFilter()); return GetPlayModeLauncher(settings, executionSettings); } } static TestLauncherBase GetEditModeLauncher(Filter filter) { return GetEditModeLauncherForProvidedAssemblies(filter); } static TestLauncherBase GetPlayModeLauncher(PlaymodeTestsControllerSettings settings, ExecutionSettings executionSettings) { if (executionSettings.targetPlatform != null) { return GetPlayerLauncher(settings, executionSettings.targetPlatform.Value, executionSettings.overloadTestRunSettings); } if (PlayerSettings.runPlayModeTestAsEditModeTest) { return GetEditModeLauncherForProvidedAssemblies(executionSettings.filter, TestPlatform.PlayMode); } return GetPlayModeLauncher(settings); } static TestLauncherBase GetEditModeLauncherForProvidedAssemblies(Filter filter, TestPlatform testPlatform = TestPlatform.EditMode) { return new EditModeLauncher(filter.ToTestRunnerFilter(), testPlatform); } static TestLauncherBase GetPlayModeLauncher(PlaymodeTestsControllerSettings settings) { return new PlaymodeLauncher(settings); } static TestLauncherBase GetPlayerLauncher(PlaymodeTestsControllerSettings settings, BuildTarget targetPlatform, ITestRunSettings overloadTestRunSettings) { return new PlayerLauncher(settings, targetPlatform, overloadTestRunSettings); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestLauncherFactory.cs.meta ================================================ fileFormatVersion: 2 guid: f33e570b8b9af1048b80a27e7848cb09 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestMode.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner.Api { [Flags] internal enum TestMode { EditMode = 1 << 0, PlayMode = 1 << 1 } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestMode.cs.meta ================================================ fileFormatVersion: 2 guid: cad095eccea17b741bc4cd264e7441cd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestResultAdaptor.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEditor.TestTools.TestRunner.Api { internal class TestResultAdaptor : ITestResultAdaptor { private TNode m_Node; internal TestResultAdaptor(ITestResult result) { Test = new TestAdaptor(result.Test); Name = result.Name; FullName = result.FullName; ResultState = result.ResultState.ToString(); TestStatus = ParseTestStatus(result.ResultState.Status); Duration = result.Duration; StartTime = result.StartTime; EndTime = result.EndTime; Message = result.Message; StackTrace = result.StackTrace; AssertCount = result.AssertCount; FailCount = result.FailCount; PassCount = result.PassCount; SkipCount = result.SkipCount; InconclusiveCount = result.InconclusiveCount; HasChildren = result.HasChildren; Output = result.Output; Children = result.Children.Select(child => new TestResultAdaptor(child)).ToArray(); m_Node = result.ToXml(true); } internal TestResultAdaptor(RemoteTestResultData result, RemoteTestResultDataWithTestData allData) { Test = new TestAdaptor(allData.tests.First(t => t.id == result.testId)); Name = result.name; FullName = result.fullName; ResultState = result.resultState; TestStatus = ParseTestStatus(result.testStatus); Duration = result.duration; StartTime = result.startTime; EndTime = result.endTime; Message = result.message; StackTrace = result.stackTrace; AssertCount = result.assertCount; FailCount = result.failCount; PassCount = result.passCount; SkipCount = result.skipCount; InconclusiveCount = result.inconclusiveCount; HasChildren = result.hasChildren; Output = result.output; Children = result.childrenIds.Select(childId => new TestResultAdaptor(allData.results.First(r => r.testId == childId), allData)).ToArray(); m_Node = TNode.FromXml(result.xml); } public ITestAdaptor Test { get; private set; } public string Name { get; private set; } public string FullName { get; private set; } public string ResultState { get; private set; } public TestStatus TestStatus { get; private set; } public double Duration { get; private set; } public DateTime StartTime { get; private set; } public DateTime EndTime { get; private set; } public string Message { get; private set; } public string StackTrace { get; private set; } public int AssertCount { get; private set; } public int FailCount { get; private set; } public int PassCount { get; private set; } public int SkipCount { get; private set; } public int InconclusiveCount { get; private set; } public bool HasChildren { get; private set; } public IEnumerable Children { get; private set; } public string Output { get; private set; } public TNode ToXml() { return m_Node; } private static TestStatus ParseTestStatus(NUnit.Framework.Interfaces.TestStatus testStatus) { return (TestStatus)Enum.Parse(typeof(TestStatus), testStatus.ToString()); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestResultAdaptor.cs.meta ================================================ fileFormatVersion: 2 guid: d061ada5d3169454daf54243390b5fdb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestRunData.cs ================================================ using System; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.Api { [Serializable] internal class TestRunData : ScriptableSingleton { [SerializeField] public ExecutionSettings executionSettings; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestRunData.cs.meta ================================================ fileFormatVersion: 2 guid: 973b024861c5ae84f869aad614234b04 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestRunnerApi.cs ================================================ using System; using System.Linq; using System.Threading; using UnityEngine; using UnityEngine.TestRunner.TestLaunchers; using UnityEngine.TestTools; using UnityEngine.TestTools.NUnitExtensions; namespace UnityEditor.TestTools.TestRunner.Api { internal class TestRunnerApi : ScriptableObject, ITestRunnerApi { public void Execute(ExecutionSettings executionSettings) { if (executionSettings == null) { throw new ArgumentException("Filter for execution is undefined."); } var launcherFactory = new TestLauncherFactory(); var data = TestRunData.instance; data.executionSettings = executionSettings; var testLauncher = launcherFactory.GetLauncher(executionSettings); testLauncher.Run(); } public void RegisterCallbacks(T testCallbacks, int priority = 0) where T : ICallbacks { if (testCallbacks == null) { throw new ArgumentException("TestCallbacks for execution is undefined."); } CallbacksHolder.instance.Add(testCallbacks, priority); } public void UnregisterCallbacks(T testCallbacks) where T : ICallbacks { if (testCallbacks == null) { throw new ArgumentException("TestCallbacks for execution is undefined."); } CallbacksHolder.instance.Remove(testCallbacks); } public void RetrieveTestList(ExecutionSettings executionSettings, Action callback) { if (executionSettings == null) { throw new ArgumentException("Filter for execution is undefined."); } if (callback == null) { throw new ArgumentException("Callback is undefined."); } var platform = ParseTestMode(executionSettings.filter.testMode); var testAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy()); var testAdaptorFactory = new TestAdaptorFactory(); var testListCache = new TestListCache(testAdaptorFactory, new RemoteTestResultDataFactory(), TestListCacheData.instance); var testListProvider = new TestListProvider(testAssemblyProvider, new UnityTestAssemblyBuilder()); var cachedTestListProvider = new CachingTestListProvider(testListProvider, testListCache, testAdaptorFactory); var job = new TestListJob(cachedTestListProvider, platform, callback); job.Start(); } private static TestPlatform ParseTestMode(TestMode testmode) { if (testmode == TestMode.EditMode) { return TestPlatform.EditMode; } return TestPlatform.PlayMode; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestRunnerApi.cs.meta ================================================ fileFormatVersion: 2 guid: 68993ba529ae04440916cb7c23bf3279 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestStatus.cs ================================================ namespace UnityEditor.TestTools.TestRunner.Api { internal enum TestStatus { Skipped, Passed, Failed, Inconclusive } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api/TestStatus.cs.meta ================================================ fileFormatVersion: 2 guid: 9ec94545c5b00344c9bd8e691f15d799 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/Api.meta ================================================ fileFormatVersion: 2 guid: fa423365b1ce06a4dbdc6fb4a8597bfa folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("UnityEditor.TestRunner")] [assembly: InternalsVisibleTo("Assembly-CSharp-Editor-testable")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("Unity.PerformanceTesting.Editor")] [assembly: InternalsVisibleTo("Unity.IntegrationTests")] [assembly: InternalsVisibleTo("UnityEditor.TestRunner.Tests")] [assembly: InternalsVisibleTo("Unity.TestTools.CodeCoverage.Editor")] [assembly: InternalsVisibleTo("Unity.PackageManagerUI.Develop.Editor")] [assembly: InternalsVisibleTo("Unity.PackageManagerUI.Develop.EditorTests")] [assembly: AssemblyVersion("1.0.0")] ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/AssemblyInfo.cs.meta ================================================ fileFormatVersion: 2 guid: 9db19a04003fca7439552acd4de9baa1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser/CommandLineOption.cs ================================================ using System; using System.Linq; namespace UnityEditor.TestRunner.CommandLineParser { internal class CommandLineOption : ICommandLineOption { Action m_ArgAction; public CommandLineOption(string argName, Action action) { ArgName = argName; m_ArgAction = s => action(); } public CommandLineOption(string argName, Action action) { ArgName = argName; m_ArgAction = action; } public CommandLineOption(string argName, Action action) { ArgName = argName; m_ArgAction = s => action(SplitStringToArray(s)); } public string ArgName { get; private set; } public void ApplyValue(string value) { m_ArgAction(value); } static string[] SplitStringToArray(string value) { if (string.IsNullOrEmpty(value)) { return null; } return value.Split(';').ToArray(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser/CommandLineOption.cs.meta ================================================ fileFormatVersion: 2 guid: a3529368f4cd0424a89aa51080a16b06 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser/CommandLineOptionSet.cs ================================================ using System; namespace UnityEditor.TestRunner.CommandLineParser { internal class CommandLineOptionSet { ICommandLineOption[] m_Options; public CommandLineOptionSet(params ICommandLineOption[] options) { m_Options = options; } public void Parse(string[] args) { var i = 0; while (i < args.Length) { var arg = args[i]; if (!arg.StartsWith("-")) { i++; continue; } string value = null; if (i + 1 < args.Length && !args[i + 1].StartsWith("-")) { value = args[i + 1]; i++; } ApplyValueToMatchingOptions(arg, value); i++; } } private void ApplyValueToMatchingOptions(string argName, string value) { foreach (var option in m_Options) { if ("-" + option.ArgName == argName) { option.ApplyValue(value); } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser/CommandLineOptionSet.cs.meta ================================================ fileFormatVersion: 2 guid: 139c5eac101a4dc4fb3098e30c29f15e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser/ICommandLineOption.cs ================================================ namespace UnityEditor.TestRunner.CommandLineParser { interface ICommandLineOption { string ArgName { get; } void ApplyValue(string value); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser/ICommandLineOption.cs.meta ================================================ fileFormatVersion: 2 guid: f445ca0c614a846449fcd8ae648c24e2 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineParser.meta ================================================ fileFormatVersion: 2 guid: 7602252bdb82b8d45ae3483c3a00d3e1 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/Executer.cs ================================================ using System; using System.Linq; using UnityEditor.TestRunner.TestLaunchers; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class Executer { private ITestRunnerApi m_TestRunnerApi; private ISettingsBuilder m_SettingsBuilder; private Action m_LogErrorFormat; private Action m_LogException; private Action m_ExitEditorApplication; private Func m_ScriptCompilationFailedCheck; public Executer(ITestRunnerApi testRunnerApi, ISettingsBuilder settingsBuilder, Action logErrorFormat, Action logException, Action exitEditorApplication, Func scriptCompilationFailedCheck) { m_TestRunnerApi = testRunnerApi; m_SettingsBuilder = settingsBuilder; m_LogErrorFormat = logErrorFormat; m_LogException = logException; m_ExitEditorApplication = exitEditorApplication; m_ScriptCompilationFailedCheck = scriptCompilationFailedCheck; } internal void InitializeAndExecuteRun(string[] commandLineArgs) { Api.ExecutionSettings executionSettings; try { executionSettings = m_SettingsBuilder.BuildApiExecutionSettings(commandLineArgs); if (executionSettings.targetPlatform.HasValue) RemotePlayerLogController.instance.SetBuildTarget(executionSettings.targetPlatform.Value); } catch (SetupException exception) { HandleSetupException(exception); return; } try { Debug.Log("Executing tests with settings: " + ExecutionSettingsToString(executionSettings)); m_TestRunnerApi.Execute(executionSettings); } catch (Exception exception) { m_LogException(exception); m_ExitEditorApplication((int)ReturnCodes.RunError); } } internal ExecutionSettings BuildExecutionSettings(string[] commandLineArgs) { return m_SettingsBuilder.BuildExecutionSettings(commandLineArgs); } internal enum ReturnCodes { Ok = 0, Failed = 2, RunError = 3, PlatformNotFoundReturnCode = 4 } internal void SetUpCallbacks(ExecutionSettings executionSettings) { RemotePlayerLogController.instance.SetLogsDirectory(executionSettings.DeviceLogsDirectory); var resultSavingCallback = ScriptableObject.CreateInstance(); resultSavingCallback.m_ResultFilePath = executionSettings.TestResultsFile; var logSavingCallback = ScriptableObject.CreateInstance(); m_TestRunnerApi.RegisterCallbacks(resultSavingCallback); m_TestRunnerApi.RegisterCallbacks(logSavingCallback); m_TestRunnerApi.RegisterCallbacks(ScriptableObject.CreateInstance(), -10); var timeoutCallbacks = ScriptableObject.CreateInstance(); timeoutCallbacks.Init((action, time) => new DelayedCallback(action, time), m_LogErrorFormat, m_ExitEditorApplication); m_TestRunnerApi.RegisterCallbacks(timeoutCallbacks); } internal void ExitOnCompileErrors() { if (m_ScriptCompilationFailedCheck()) { var handling = s_ExceptionHandlingMapping.First(h => h.m_ExceptionType == SetupException.ExceptionType.ScriptCompilationFailed); m_LogErrorFormat(handling.m_Message, new object[0]); m_ExitEditorApplication(handling.m_ReturnCode); } } void HandleSetupException(SetupException exception) { ExceptionHandling handling = s_ExceptionHandlingMapping.FirstOrDefault(h => h.m_ExceptionType == exception.Type) ?? new ExceptionHandling(exception.Type, "Unknown command line test run error. " + exception.Type, ReturnCodes.RunError); m_LogErrorFormat(handling.m_Message, exception.Details); m_ExitEditorApplication(handling.m_ReturnCode); } private class ExceptionHandling { internal SetupException.ExceptionType m_ExceptionType; internal string m_Message; internal int m_ReturnCode; public ExceptionHandling(SetupException.ExceptionType exceptionType, string message, ReturnCodes returnCode) { m_ExceptionType = exceptionType; m_Message = message; m_ReturnCode = (int)returnCode; } } static ExceptionHandling[] s_ExceptionHandlingMapping = new[] { new ExceptionHandling(SetupException.ExceptionType.ScriptCompilationFailed, "Scripts had compilation errors.", ReturnCodes.RunError), new ExceptionHandling(SetupException.ExceptionType.PlatformNotFound, "Test platform not found ({0}).", ReturnCodes.PlatformNotFoundReturnCode), new ExceptionHandling(SetupException.ExceptionType.TestSettingsFileNotFound, "Test settings file not found at {0}.", ReturnCodes.RunError) }; private static string ExecutionSettingsToString(Api.ExecutionSettings executionSettings) { if (executionSettings == null) { return "none"; } if (executionSettings.filter == null) { return "no filter"; } return "test mode = " + executionSettings.filter.testMode; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/Executer.cs.meta ================================================ fileFormatVersion: 2 guid: 083c6a3a5426382449369ddc12b691d8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ExecutionSettings.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { [Serializable] internal class ExecutionSettings { public string TestResultsFile; public string DeviceLogsDirectory; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ExecutionSettings.cs.meta ================================================ fileFormatVersion: 2 guid: c3a75354f6ceac94ca15ca9d96593290 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ExitCallbacks.cs ================================================ using System; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { [Serializable] internal class ExitCallbacks : ScriptableObject, ICallbacks { private bool m_AnyTestsExecuted; private bool m_RunFailed; internal static bool preventExit; public void RunFinished(ITestResultAdaptor testResults) { if (preventExit) { return; } if (!m_AnyTestsExecuted) { Debug.LogFormat(LogType.Warning, LogOption.NoStacktrace, null, "No tests were executed"); } EditorApplication.Exit(m_RunFailed ? (int)Executer.ReturnCodes.Failed : (int)Executer.ReturnCodes.Ok); } public void TestStarted(ITestAdaptor test) { if (!test.IsSuite) { m_AnyTestsExecuted = true; } } public void TestFinished(ITestResultAdaptor result) { if (!result.Test.IsSuite && (result.TestStatus == TestStatus.Failed)) { m_RunFailed = true; } } public void RunStarted(ITestAdaptor testsToRun) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ExitCallbacks.cs.meta ================================================ fileFormatVersion: 2 guid: 1adaa8dcc4fda3d4cb4d3c8e0cb65d12 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ISettingsBuilder.cs ================================================ using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { interface ISettingsBuilder { Api.ExecutionSettings BuildApiExecutionSettings(string[] commandLineArgs); ExecutionSettings BuildExecutionSettings(string[] commandLineArgs); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ISettingsBuilder.cs.meta ================================================ fileFormatVersion: 2 guid: 8a13cbeb2099aca47bb456f49845f86c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/LogSavingCallbacks.cs ================================================ using System; using UnityEditor.TestRunner.TestLaunchers; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { [Serializable] internal class LogSavingCallbacks : ScriptableObject, ICallbacks { public void RunStarted(ITestAdaptor testsToRun) { RemotePlayerLogController.instance.StartLogWriters(); } public virtual void RunFinished(ITestResultAdaptor testResults) { RemotePlayerLogController.instance.StopLogWriters(); } public void TestStarted(ITestAdaptor test) { } public void TestFinished(ITestResultAdaptor result) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/LogSavingCallbacks.cs.meta ================================================ fileFormatVersion: 2 guid: 8d20eedbe40f0ce41a4c4f633f225de8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/LogWriter.cs ================================================ using System; using System.Collections.Generic; using System.IO; using UnityEditor.DeploymentTargets; using UnityEditor.Utils; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class LogWriter : IDisposable { private string m_LogsDirectory; private string m_DeviceID; private Dictionary m_LogStreams; private DeploymentTargetLogger m_Logger; internal LogWriter(string logsDirectory, string deviceID, DeploymentTargetLogger logger) { m_LogStreams = new Dictionary(); m_Logger = logger; m_LogsDirectory = logsDirectory; m_DeviceID = deviceID; logger.logMessage += WriteLogToFile; } private void WriteLogToFile(string id, string logLine) { StreamWriter logStream; var streamExists = m_LogStreams.TryGetValue(id, out logStream); if (!streamExists) { var filePath = GetLogFilePath(m_LogsDirectory, m_DeviceID, id); logStream = CreateLogFile(filePath); m_LogStreams.Add(id, logStream); } try { if (logLine != null) logStream.WriteLine(logLine); } catch (Exception ex) { Debug.LogError($"Writing {id} log failed."); Debug.LogException(ex); } } public void Stop() { m_Logger.Stop(); foreach (var logStream in m_LogStreams) { logStream.Value.Close(); } } public void Dispose() { Stop(); } private StreamWriter CreateLogFile(string path) { Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, "Creating {0} device log: {1}", m_DeviceID, path); StreamWriter streamWriter = null; try { if (!Directory.Exists(path)) Directory.CreateDirectory(Path.GetDirectoryName(path)); streamWriter = File.CreateText(path); } catch (Exception ex) { Debug.LogError($"Creating device log {path} file failed."); Debug.LogException(ex); } return streamWriter; } private string GetLogFilePath(string lgosDirectory, string deviceID, string logID) { var fileName = "Device-" + deviceID + "-" + logID + ".txt"; fileName = string.Join("_", fileName.Split(Path.GetInvalidFileNameChars())); return Paths.Combine(lgosDirectory, fileName); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/LogWriter.cs.meta ================================================ fileFormatVersion: 2 guid: 05778dd1de4433d418793b6f3d3c18cf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ResultsSavingCallbacks.cs ================================================ using System; using System.IO; using UnityEditor.TestTools.TestRunner.Api; using UnityEditor.Utils; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { [Serializable] internal class ResultsSavingCallbacks : ScriptableObject, ICallbacks { [SerializeField] public string m_ResultFilePath; public ResultsSavingCallbacks() { this.m_ResultFilePath = GetDefaultResultFilePath(); } public void RunStarted(ITestAdaptor testsToRun) { } public virtual void RunFinished(ITestResultAdaptor testResults) { if (string.IsNullOrEmpty(m_ResultFilePath)) { m_ResultFilePath = GetDefaultResultFilePath(); } var resultWriter = new ResultsWriter(); resultWriter.WriteResultToFile(testResults, m_ResultFilePath); } public void TestStarted(ITestAdaptor test) { } public void TestFinished(ITestResultAdaptor result) { } private static string GetDefaultResultFilePath() { var fileName = "TestResults-" + DateTime.Now.Ticks + ".xml"; var projectPath = Directory.GetCurrentDirectory(); return Paths.Combine(projectPath, fileName); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ResultsSavingCallbacks.cs.meta ================================================ fileFormatVersion: 2 guid: ef563c5a6ecf64d4193dc144cb7d472a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ResultsWriter.cs ================================================ using System; using System.IO; using System.Xml; using NUnit.Framework.Interfaces; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class ResultsWriter { private const string k_nUnitVersion = "3.5.0.0"; private const string k_TestRunNode = "test-run"; private const string k_Id = "id"; private const string k_Testcasecount = "testcasecount"; private const string k_Result = "result"; private const string k_Total = "total"; private const string k_Passed = "passed"; private const string k_Failed = "failed"; private const string k_Inconclusive = "inconclusive"; private const string k_Skipped = "skipped"; private const string k_Asserts = "asserts"; private const string k_EngineVersion = "engine-version"; private const string k_ClrVersion = "clr-version"; private const string k_StartTime = "start-time"; private const string k_EndTime = "end-time"; private const string k_Duration = "duration"; private const string k_TimeFormat = "u"; public void WriteResultToFile(ITestResultAdaptor result, string filePath) { Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, "Saving results to: {0}", filePath); try { if (!Directory.Exists(filePath)) { CreateDirectory(filePath); } using (var fileStream = File.CreateText(filePath)) { WriteResultToStream(result, fileStream); } } catch (Exception ex) { Debug.LogError("Saving result file failed."); Debug.LogException(ex); } } void CreateDirectory(string filePath) { Directory.CreateDirectory(Path.GetDirectoryName(filePath)); } public void WriteResultToStream(ITestResultAdaptor result, StreamWriter streamWriter, XmlWriterSettings settings = null) { settings = settings ?? new XmlWriterSettings(); settings.Indent = true; settings.NewLineOnAttributes = false; using (var xmlWriter = XmlWriter.Create(streamWriter, settings)) { WriteResultsToXml(result, xmlWriter); } } void WriteResultsToXml(ITestResultAdaptor result, XmlWriter xmlWriter) { // XML format as specified at https://github.com/nunit/docs/wiki/Test-Result-XML-Format var testRunNode = new TNode(k_TestRunNode); testRunNode.AddAttribute(k_Id, "2"); testRunNode.AddAttribute(k_Testcasecount, (result.PassCount + result.FailCount + result.SkipCount + result.InconclusiveCount).ToString()); testRunNode.AddAttribute(k_Result, result.ResultState.ToString()); testRunNode.AddAttribute(k_Total, (result.PassCount + result.FailCount + result.SkipCount + result.InconclusiveCount).ToString()); testRunNode.AddAttribute(k_Passed, result.PassCount.ToString()); testRunNode.AddAttribute(k_Failed, result.FailCount.ToString()); testRunNode.AddAttribute(k_Inconclusive, result.InconclusiveCount.ToString()); testRunNode.AddAttribute(k_Skipped, result.SkipCount.ToString()); testRunNode.AddAttribute(k_Asserts, result.AssertCount.ToString()); testRunNode.AddAttribute(k_EngineVersion, k_nUnitVersion); testRunNode.AddAttribute(k_ClrVersion, Environment.Version.ToString()); testRunNode.AddAttribute(k_StartTime, result.StartTime.ToString(k_TimeFormat)); testRunNode.AddAttribute(k_EndTime, result.EndTime.ToString(k_TimeFormat)); testRunNode.AddAttribute(k_Duration, result.Duration.ToString()); var resultNode = result.ToXml(); testRunNode.ChildNodes.Add(resultNode); testRunNode.WriteTo(xmlWriter); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/ResultsWriter.cs.meta ================================================ fileFormatVersion: 2 guid: 29d603e0a726a9043b3503112271844a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/RunData.cs ================================================ namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class RunData : ScriptableSingleton { public bool isRunning; public ExecutionSettings executionSettings; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/RunData.cs.meta ================================================ fileFormatVersion: 2 guid: 3f8c1075884df0249b80e23a0598f9c1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/RunSettings.cs ================================================ using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class RunSettings : ITestRunSettings { private ITestSettings m_TestSettings; public RunSettings(ITestSettings testSettings) { this.m_TestSettings = testSettings; } public void Apply() { if (m_TestSettings != null) { m_TestSettings.SetupProjectParameters(); } } public void Dispose() { if (m_TestSettings != null) { m_TestSettings.Dispose(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/RunSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 59d3f5586b341a74c84c8f72144a4568 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/SettingsBuilder.cs ================================================ using System; using System.IO; using UnityEditor.TestRunner.CommandLineParser; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class SettingsBuilder : ISettingsBuilder { private ITestSettingsDeserializer m_TestSettingsDeserializer; private Action m_LogAction; private Action m_LogWarningAction; private Func m_FileExistsCheck; private Func m_ScriptCompilationFailedCheck; public SettingsBuilder(ITestSettingsDeserializer testSettingsDeserializer, Action logAction, Action logWarningAction, Func fileExistsCheck, Func scriptCompilationFailedCheck) { m_LogAction = logAction; m_LogWarningAction = logWarningAction; m_FileExistsCheck = fileExistsCheck; m_ScriptCompilationFailedCheck = scriptCompilationFailedCheck; m_TestSettingsDeserializer = testSettingsDeserializer; } public Api.ExecutionSettings BuildApiExecutionSettings(string[] commandLineArgs) { var quit = false; string testPlatform = TestMode.EditMode.ToString(); string[] testFilters = null; string[] testCategories = null; string testSettingsFilePath = null; int testRepetitions = 1; var optionSet = new CommandLineOptionSet( new CommandLineOption("quit", () => { quit = true; }), new CommandLineOption("testPlatform", platform => { testPlatform = platform; }), new CommandLineOption("editorTestsFilter", filters => { testFilters = filters; }), new CommandLineOption("testFilter", filters => { testFilters = filters; }), new CommandLineOption("editorTestsCategories", catagories => { testCategories = catagories; }), new CommandLineOption("testCategory", catagories => { testCategories = catagories; }), new CommandLineOption("testSettingsFile", settingsFilePath => { testSettingsFilePath = settingsFilePath; }), new CommandLineOption("testRepetitions", reps => { testRepetitions = int.Parse(reps); }) ); optionSet.Parse(commandLineArgs); DisplayQuitWarningIfQuitIsGiven(quit); CheckForScriptCompilationErrors(); LogParametersForRun(testPlatform, testFilters, testCategories, testSettingsFilePath); var testSettings = GetTestSettings(testSettingsFilePath); var filter = new Filter() { groupNames = testFilters, categoryNames = testCategories }; var buildTarget = SetFilterAndGetBuildTarget(testPlatform, filter); RerunCallbackData.instance.runFilter = new TestRunnerFilter() { categoryNames = filter.categoryNames, groupNames = filter.groupNames, testRepetitions = testRepetitions }; RerunCallbackData.instance.testMode = filter.testMode; return new Api.ExecutionSettings() { filter = filter, overloadTestRunSettings = new RunSettings(testSettings), targetPlatform = buildTarget }; } public ExecutionSettings BuildExecutionSettings(string[] commandLineArgs) { string resultFilePath = null; string deviceLogsDirectory = null; var optionSet = new CommandLineOptionSet( new CommandLineOption("editorTestsResultFile", filePath => { resultFilePath = filePath; }), new CommandLineOption("testResults", filePath => { resultFilePath = filePath; }), new CommandLineOption("deviceLogs", dirPath => { deviceLogsDirectory = dirPath; }) ); optionSet.Parse(commandLineArgs); return new ExecutionSettings() { TestResultsFile = resultFilePath, DeviceLogsDirectory = deviceLogsDirectory }; } void DisplayQuitWarningIfQuitIsGiven(bool quitIsGiven) { if (quitIsGiven) { m_LogWarningAction("Running tests from command line arguments will not work when \"quit\" is specified."); } } void CheckForScriptCompilationErrors() { if (m_ScriptCompilationFailedCheck()) { throw new SetupException(SetupException.ExceptionType.ScriptCompilationFailed); } } void LogParametersForRun(string testPlatform, string[] testFilters, string[] testCategories, string testSettingsFilePath) { m_LogAction("Running tests for " + testPlatform); if (testFilters != null && testFilters.Length > 0) { m_LogAction("With test filter: " + string.Join(", ", testFilters)); } if (testCategories != null && testCategories.Length > 0) { m_LogAction("With test categories: " + string.Join(", ", testCategories)); } if (!string.IsNullOrEmpty(testSettingsFilePath)) { m_LogAction("With test settings file: " + testSettingsFilePath); } } ITestSettings GetTestSettings(string testSettingsFilePath) { ITestSettings testSettings = null; if (!string.IsNullOrEmpty(testSettingsFilePath)) { if (!m_FileExistsCheck(testSettingsFilePath)) { throw new SetupException(SetupException.ExceptionType.TestSettingsFileNotFound, testSettingsFilePath); } testSettings = m_TestSettingsDeserializer.GetSettingsFromJsonFile(testSettingsFilePath); } return testSettings; } static BuildTarget? SetFilterAndGetBuildTarget(string testPlatform, Filter filter) { BuildTarget? buildTarget = null; if (testPlatform.ToLower() == "editmode") { filter.testMode = TestMode.EditMode; } else if (testPlatform.ToLower() == "playmode") { filter.testMode = TestMode.PlayMode; } else { try { buildTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), testPlatform, true); filter.testMode = TestMode.PlayMode; } catch (ArgumentException) { throw new SetupException(SetupException.ExceptionType.PlatformNotFound, testPlatform); } } return buildTarget; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/SettingsBuilder.cs.meta ================================================ fileFormatVersion: 2 guid: b7468a027a77337478e133b40b42b4f9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/SetupException.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class SetupException : Exception { public ExceptionType Type { get; } public object[] Details { get; } public SetupException(ExceptionType type, params object[] details) { Type = type; Details = details; } public enum ExceptionType { ScriptCompilationFailed, PlatformNotFound, TestSettingsFileNotFound, } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/SetupException.cs.meta ================================================ fileFormatVersion: 2 guid: 63572993f2104574099a48392460b211 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/TestStarter.cs ================================================ using System; using System.IO; using UnityEditor.TestRunner.CommandLineParser; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { [InitializeOnLoad] static class TestStarter { static TestStarter() { if (!ShouldRunTests()) { return; } if (EditorApplication.isCompiling) { return; } executer.ExitOnCompileErrors(); if (RunData.instance.isRunning) { executer.SetUpCallbacks(RunData.instance.executionSettings); return; } EditorApplication.update += UpdateWatch; } static void UpdateWatch() { EditorApplication.update -= UpdateWatch; if (RunData.instance.isRunning) { return; } RunData.instance.isRunning = true; var commandLineArgs = Environment.GetCommandLineArgs(); RunData.instance.executionSettings = executer.BuildExecutionSettings(commandLineArgs); executer.SetUpCallbacks(RunData.instance.executionSettings); executer.InitializeAndExecuteRun(commandLineArgs); } static bool ShouldRunTests() { var shouldRunTests = false; var optionSet = new CommandLineOptionSet( new CommandLineOption("runTests", () => { shouldRunTests = true; }), new CommandLineOption("runEditorTests", () => { shouldRunTests = true; }) ); optionSet.Parse(Environment.GetCommandLineArgs()); return shouldRunTests; } static Executer s_Executer; static Executer executer { get { if (s_Executer == null) { Func compilationCheck = () => EditorUtility.scriptCompilationFailed; Action actionLogger = (string msg) => { Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, msg); }; var apiSettingsBuilder = new SettingsBuilder(new TestSettingsDeserializer(() => new TestSettings()), actionLogger, Debug.LogWarning, File.Exists, compilationCheck); s_Executer = new Executer(ScriptableObject.CreateInstance(), apiSettingsBuilder, Debug.LogErrorFormat, Debug.LogException, EditorApplication.Exit, compilationCheck); } return s_Executer; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/TestStarter.cs.meta ================================================ fileFormatVersion: 2 guid: 4d616d1a494edd144b262cf6cd5e5fda MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/TimeoutCallbacks.cs ================================================ using System; using UnityEditor.TestRunner.TestLaunchers; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.CommandLineTest { internal class TimeoutCallbacks : ScriptableObject, ICallbacks { internal const int k_DefaultTimeout = 600; private Func m_DelayedCallbackFactory; private Action m_LogErrorFormat; private Action m_ExitApplication; private double m_CurrentTimeout; private IDelayedCallback m_TimeoutCallback; public void Init(Func delayedCallbackFactory, Action logErrorFormat, Action exitApplication) { m_DelayedCallbackFactory = delayedCallbackFactory; m_LogErrorFormat = logErrorFormat; m_ExitApplication = exitApplication; } public void RunFinished(ITestResultAdaptor result) { if (m_TimeoutCallback != null) { m_TimeoutCallback.Clear(); } } public void RunStarted(ITestAdaptor testsToRun) { ResetToTimeout(k_DefaultTimeout); } public void TestFinished(ITestResultAdaptor result) { ResetToTimeout(k_DefaultTimeout); } public void TestStarted(ITestAdaptor test) { ResetToTimeout(k_DefaultTimeout + test.TestCaseTimeout / 1000); } private void ResetToTimeout(double timeoutValue) { if (m_TimeoutCallback != null && Math.Abs(m_CurrentTimeout - timeoutValue) < 0.1f) { m_TimeoutCallback.Reset(); } else { if (m_TimeoutCallback != null) { m_TimeoutCallback.Clear(); } m_TimeoutCallback = m_DelayedCallbackFactory(TimeoutReached, timeoutValue); m_CurrentTimeout = timeoutValue; } } private void TimeoutReached() { RemotePlayerLogController.instance.StopLogWriters(); m_LogErrorFormat("Test execution timed out.", new object[0]); m_ExitApplication((int)Executer.ReturnCodes.RunError); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest/TimeoutCallbacks.cs.meta ================================================ fileFormatVersion: 2 guid: 4dc5887d05b52fd4fb5f52909d09ffe9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/CommandLineTest.meta ================================================ fileFormatVersion: 2 guid: b477d1f29b65a674e9d5cdab4eb72b01 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/AssetsDatabaseHelper.cs ================================================ namespace UnityEditor.TestTools.TestRunner.GUI { internal class AssetsDatabaseHelper : IAssetsDatabaseHelper { public void OpenAssetInItsDefaultExternalEditor(string assetPath, int line) { var asset = AssetDatabase.LoadMainAssetAtPath(assetPath); AssetDatabase.OpenAsset(asset, line); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/AssetsDatabaseHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 740b3785866edda4b8d1e1a05570a5f8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/GuiHelper.cs ================================================ using System; using System.IO; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using UnityEditor.Utils; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.GUI { internal class GuiHelper : IGuiHelper { public GuiHelper(IMonoCecilHelper monoCecilHelper, IAssetsDatabaseHelper assetsDatabaseHelper) { MonoCecilHelper = monoCecilHelper; AssetsDatabaseHelper = assetsDatabaseHelper; } protected IMonoCecilHelper MonoCecilHelper { get; private set; } public IAssetsDatabaseHelper AssetsDatabaseHelper { get; private set; } public void OpenScriptInExternalEditor(Type type, MethodInfo method) { var fileOpenInfo = GetFileOpenInfo(type, method); if (string.IsNullOrEmpty(fileOpenInfo.FilePath)) { Debug.LogWarning("Failed to open test method source code in external editor. Inconsistent filename and yield return operator in target method."); return; } if (fileOpenInfo.LineNumber == 1) { Debug.LogWarning("Failed to get a line number for unity test method. So please find it in opened file in external editor."); } AssetsDatabaseHelper.OpenAssetInItsDefaultExternalEditor(fileOpenInfo.FilePath, fileOpenInfo.LineNumber); } public IFileOpenInfo GetFileOpenInfo(Type type, MethodInfo method) { const string fileExtension = ".cs"; var fileOpenInfo = MonoCecilHelper.TryGetCecilFileOpenInfo(type, method); if (string.IsNullOrEmpty(fileOpenInfo.FilePath)) { var dirPath = Paths.UnifyDirectorySeparator(Application.dataPath); var allCsFiles = Directory.GetFiles(dirPath, string.Format("*{0}", fileExtension), SearchOption.AllDirectories) .Select(Paths.UnifyDirectorySeparator); var fileName = allCsFiles.FirstOrDefault(x => x.Split(Path.DirectorySeparatorChar).Last().Equals(string.Concat(type.Name, fileExtension))); fileOpenInfo.FilePath = fileName ?? string.Empty; } fileOpenInfo.FilePath = FilePathToAssetsRelativeAndUnified(fileOpenInfo.FilePath); return fileOpenInfo; } public string FilePathToAssetsRelativeAndUnified(string filePath) { if (string.IsNullOrEmpty(filePath)) return string.Empty; filePath = Paths.UnifyDirectorySeparator(filePath); var length = Paths.UnifyDirectorySeparator(Application.dataPath).Length - "Assets".Length; return filePath.Substring(length); } public bool OpenScriptInExternalEditor(string stacktrace) { if (string.IsNullOrEmpty(stacktrace)) return false; var regex = new Regex("in (?.*):{1}(?[0-9]+)"); var matchingLines = stacktrace.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Where(x => regex.IsMatch(x)).ToList(); if (!matchingLines.Any()) return false; var fileOpenInfo = matchingLines .Select(x => regex.Match(x)) .Select(x => new FileOpenInfo { FilePath = x.Groups["path"].Value, LineNumber = int.Parse(x.Groups["line"].Value) }) .First(openInfo => !string.IsNullOrEmpty(openInfo.FilePath) && File.Exists(openInfo.FilePath)); var filePath = FilePathToAssetsRelativeAndUnified(fileOpenInfo.FilePath); AssetsDatabaseHelper.OpenAssetInItsDefaultExternalEditor(filePath, fileOpenInfo.LineNumber); return true; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/GuiHelper.cs.meta ================================================ fileFormatVersion: 2 guid: d0138170d24533e47b8e6c250c6d7fbc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/IAssetsDatabaseHelper.cs ================================================ namespace UnityEditor.TestTools.TestRunner.GUI { internal interface IAssetsDatabaseHelper { void OpenAssetInItsDefaultExternalEditor(string assetPath, int line); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/IAssetsDatabaseHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 208e46d59ff6e304db0318377d20f5a1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/IGuiHelper.cs ================================================ using System; using System.Reflection; namespace UnityEditor.TestTools.TestRunner.GUI { internal interface IGuiHelper { bool OpenScriptInExternalEditor(string stacktrace); void OpenScriptInExternalEditor(Type type, MethodInfo method); IFileOpenInfo GetFileOpenInfo(Type type, MethodInfo method); string FilePathToAssetsRelativeAndUnified(string filePath); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/IGuiHelper.cs.meta ================================================ fileFormatVersion: 2 guid: fd57cf917f61bbb42b8f030436426ddd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/RenderingOptions.cs ================================================ namespace UnityEditor.TestTools.TestRunner.GUI { internal class RenderingOptions { public string nameFilter; public bool showSucceeded; public bool showFailed; public bool showIgnored; public bool showNotRunned; public string[] categories; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/RenderingOptions.cs.meta ================================================ fileFormatVersion: 2 guid: 87357ff0dec4ef348a295235835c6ee4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/ResultSummarizer.cs ================================================ // **************************************************************** // Based on nUnit 2.6.2 (http://www.nunit.org/) // **************************************************************** using System; using System.Collections.Generic; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { /// /// Summary description for ResultSummarizer. /// internal class ResultSummarizer { private int m_ErrorCount = -1; private int m_FailureCount; private int m_IgnoreCount = -1; private int m_InconclusiveCount = -1; private int m_NotRunnable = -1; private int m_ResultCount; private int m_SkipCount; private int m_SuccessCount; private int m_TestsRun; private TimeSpan m_Duration = TimeSpan.FromSeconds(0); public ResultSummarizer(IEnumerable results) { foreach (var result in results) Summarize(result); } public bool success { get { return m_FailureCount == 0; } } /// /// Returns the number of test cases for which results /// have been summarized. Any tests excluded by use of /// Category or Explicit attributes are not counted. /// public int ResultCount { get { return m_ResultCount; } } /// /// Returns the number of test cases actually run, which /// is the same as ResultCount, less any Skipped, Ignored /// or NonRunnable tests. /// public int TestsRun { get { return m_TestsRun; } } /// /// Returns the number of tests that passed /// public int Passed { get { return m_SuccessCount; } } /// /// Returns the number of test cases that had an error. /// public int errors { get { return m_ErrorCount; } } /// /// Returns the number of test cases that failed. /// public int failures { get { return m_FailureCount; } } /// /// Returns the number of test cases that failed. /// public int inconclusive { get { return m_InconclusiveCount; } } /// /// Returns the number of test cases that were not runnable /// due to errors in the signature of the class or method. /// Such tests are also counted as Errors. /// public int notRunnable { get { return m_NotRunnable; } } /// /// Returns the number of test cases that were skipped. /// public int Skipped { get { return m_SkipCount; } } public int ignored { get { return m_IgnoreCount; } } public double duration { get { return m_Duration.TotalSeconds; } } public int testsNotRun { get { return m_SkipCount + m_IgnoreCount + m_NotRunnable; } } public void Summarize(TestRunnerResult result) { m_Duration += TimeSpan.FromSeconds(result.duration); m_ResultCount++; if (result.resultStatus != TestRunnerResult.ResultStatus.NotRun) { //TODO implement missing features // if(result.IsIgnored) // { // m_IgnoreCount++; // return; // } m_SkipCount++; return; } switch (result.resultStatus) { case TestRunnerResult.ResultStatus.Passed: m_SuccessCount++; m_TestsRun++; break; case TestRunnerResult.ResultStatus.Failed: m_FailureCount++; m_TestsRun++; break; //TODO implement missing features // case TestResultState.Error: // case TestResultState.Cancelled: // m_ErrorCount++; // m_TestsRun++; // break; // case TestResultState.Inconclusive: // m_InconclusiveCount++; // m_TestsRun++; // break; // case TestResultState.NotRunnable: // m_NotRunnable++; // // errorCount++; // break; // case TestResultState.Ignored: // m_IgnoreCount++; // break; default: m_SkipCount++; break; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/ResultSummarizer.cs.meta ================================================ fileFormatVersion: 2 guid: 95a2914724952ef40bb590d0607fc878 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/TestFilterSettings.cs ================================================ using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { internal class TestFilterSettings { public bool showSucceeded; public bool showFailed; public bool showIgnored; public bool showNotRun; public string filterByName; public int filterByCategory; private GUIContent m_SucceededBtn; private GUIContent m_FailedBtn; private GUIContent m_IgnoredBtn; private GUIContent m_NotRunBtn; public string[] availableCategories; private readonly string m_PrefsKey; public TestFilterSettings(string prefsKey) { availableCategories = null; m_PrefsKey = prefsKey; Load(); UpdateCounters(Enumerable.Empty()); } public void Load() { showSucceeded = EditorPrefs.GetBool(m_PrefsKey + ".ShowSucceeded", true); showFailed = EditorPrefs.GetBool(m_PrefsKey + ".ShowFailed", true); showIgnored = EditorPrefs.GetBool(m_PrefsKey + ".ShowIgnored", true); showNotRun = EditorPrefs.GetBool(m_PrefsKey + ".ShowNotRun", true); filterByName = EditorPrefs.GetString(m_PrefsKey + ".FilterByName", string.Empty); filterByCategory = EditorPrefs.GetInt(m_PrefsKey + ".FilterByCategory", 0); } public void Save() { EditorPrefs.SetBool(m_PrefsKey + ".ShowSucceeded", showSucceeded); EditorPrefs.SetBool(m_PrefsKey + ".ShowFailed", showFailed); EditorPrefs.SetBool(m_PrefsKey + ".ShowIgnored", showIgnored); EditorPrefs.SetBool(m_PrefsKey + ".ShowNotRun", showNotRun); EditorPrefs.SetString(m_PrefsKey + ".FilterByName", filterByName); EditorPrefs.SetInt(m_PrefsKey + ".FilterByCategory", filterByCategory); } public void UpdateCounters(IEnumerable results) { var summary = new ResultSummarizer(results); m_SucceededBtn = new GUIContent(summary.Passed.ToString(), Icons.s_SuccessImg, "Show tests that succeeded"); m_FailedBtn = new GUIContent((summary.errors + summary.failures + summary.inconclusive).ToString(), Icons.s_FailImg, "Show tests that failed"); m_IgnoredBtn = new GUIContent((summary.ignored + summary.notRunnable).ToString(), Icons.s_IgnoreImg, "Show tests that are ignored"); m_NotRunBtn = new GUIContent((summary.testsNotRun - summary.ignored - summary.notRunnable).ToString(), Icons.s_UnknownImg, "Show tests that didn't run"); } public string[] GetSelectedCategories() { if (availableCategories == null) return new string[0]; return availableCategories.Where((c, i) => (filterByCategory & (1 << i)) != 0).ToArray(); } public void OnGUI() { EditorGUI.BeginChangeCheck(); filterByName = GUILayout.TextField(filterByName, "ToolbarSeachTextField", GUILayout.MinWidth(100), GUILayout.MaxWidth(250), GUILayout.ExpandWidth(true)); if (GUILayout.Button(GUIContent.none, string.IsNullOrEmpty(filterByName) ? "ToolbarSeachCancelButtonEmpty" : "ToolbarSeachCancelButton")) filterByName = string.Empty; if (availableCategories != null && availableCategories.Length > 0) filterByCategory = EditorGUILayout.MaskField(filterByCategory, availableCategories, EditorStyles.toolbarDropDown, GUILayout.MaxWidth(90)); showSucceeded = GUILayout.Toggle(showSucceeded, m_SucceededBtn, EditorStyles.toolbarButton); showFailed = GUILayout.Toggle(showFailed, m_FailedBtn, EditorStyles.toolbarButton); showIgnored = GUILayout.Toggle(showIgnored, m_IgnoredBtn, EditorStyles.toolbarButton); showNotRun = GUILayout.Toggle(showNotRun, m_NotRunBtn, EditorStyles.toolbarButton); if (EditorGUI.EndChangeCheck()) Save(); } public RenderingOptions BuildRenderingOptions() { var options = new RenderingOptions(); options.showSucceeded = showSucceeded; options.showFailed = showFailed; options.showIgnored = showIgnored; options.showNotRunned = showNotRun; options.nameFilter = filterByName; options.categories = GetSelectedCategories(); return options; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/TestFilterSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 046c3854296c5ec48bac50da6ca248ec MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/TestTreeViewBuilder.cs ================================================ using System.Collections.Generic; using System.Linq; using UnityEditor.IMGUI.Controls; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestRunner.NUnitExtensions; using UnityEngine.TestTools.TestRunner.GUI; using UnityEngine.TestRunner.NUnitExtensions.Filters; namespace UnityEditor.TestTools.TestRunner.GUI { internal class TestTreeViewBuilder { public List results = new List(); private readonly List m_OldTestResultList; private readonly TestRunnerUIFilter m_UIFilter; private readonly ITestAdaptor m_TestListRoot; private readonly List m_AvailableCategories = new List(); public string[] AvailableCategories { get { return m_AvailableCategories.Distinct().OrderBy(a => a).ToArray(); } } public TestTreeViewBuilder(ITestAdaptor tests, List oldTestResultResults, TestRunnerUIFilter uiFilter) { m_AvailableCategories.Add(CategoryFilterExtended.k_DefaultCategory); m_OldTestResultList = oldTestResultResults; m_TestListRoot = tests; m_UIFilter = uiFilter; } public TreeViewItem BuildTreeView(TestFilterSettings settings, bool sceneBased, string sceneName) { var rootItem = new TreeViewItem(int.MaxValue, 0, null, "Invisible Root Item"); ParseTestTree(0, rootItem, m_TestListRoot); return rootItem; } private bool IsFilteredOutByUIFilter(ITestAdaptor test, TestRunnerResult result) { if (m_UIFilter.PassedHidden && result.resultStatus == TestRunnerResult.ResultStatus.Passed) return true; if (m_UIFilter.FailedHidden && (result.resultStatus == TestRunnerResult.ResultStatus.Failed || result.resultStatus == TestRunnerResult.ResultStatus.Inconclusive)) return true; if (m_UIFilter.NotRunHidden && (result.resultStatus == TestRunnerResult.ResultStatus.NotRun || result.resultStatus == TestRunnerResult.ResultStatus.Skipped)) return true; if (m_UIFilter.CategoryFilter.Length > 0) return !test.Categories.Any(category => m_UIFilter.CategoryFilter.Contains(category)); return false; } private void ParseTestTree(int depth, TreeViewItem rootItem, ITestAdaptor testElement) { m_AvailableCategories.AddRange(testElement.Categories); var testElementId = testElement.UniqueName; if (!testElement.HasChildren) { var result = m_OldTestResultList.FirstOrDefault(a => a.uniqueId == testElementId); if (result != null && (result.ignoredOrSkipped || result.notRunnable || testElement.RunState == RunState.NotRunnable || testElement.RunState == RunState.Ignored || testElement.RunState == RunState.Skipped ) ) { //if the test was or becomes ignored or not runnable, we recreate the result in case it has changed result = null; } if (result == null) { result = new TestRunnerResult(testElement); } results.Add(result); var test = new TestTreeViewItem(testElement, depth, rootItem); if (!IsFilteredOutByUIFilter(testElement, result)) rootItem.AddChild(test); test.SetResult(result); return; } var groupResult = m_OldTestResultList.FirstOrDefault(a => a.uniqueId == testElementId); if (groupResult == null) { groupResult = new TestRunnerResult(testElement); } results.Add(groupResult); var group = new TestTreeViewItem(testElement, depth, rootItem); group.SetResult(groupResult); depth++; foreach (var child in testElement.Children) { ParseTestTree(depth, group, child); } if (testElement.IsTestAssembly && !testElement.HasChildren) return; if (group.hasChildren) rootItem.AddChild(group); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder/TestTreeViewBuilder.cs.meta ================================================ fileFormatVersion: 2 guid: e17c88b021c2a4c409b3f15b0d80ac62 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListBuilder.meta ================================================ fileFormatVersion: 2 guid: 07ea0326ed848fb4489187cb58f96113 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListGuiHelper.cs ================================================ using System; using System.IO; using System.Linq; using UnityEditor.ProjectWindowCallback; using UnityEditor.Scripting.ScriptCompilation; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.GUI { internal class TestListGUIHelper { private const string kResourcesTemplatePath = "Resources/ScriptTemplates"; private const string kAssemblyDefinitionTestTemplate = "92-Assembly Definition-NewTestAssembly.asmdef.txt"; private const string kAssemblyDefinitionEditModeTestTemplate = "92-Assembly Definition-NewEditModeTestAssembly.asmdef.txt"; private const string kTestScriptTemplate = "83-C# Script-NewTestScript.cs.txt"; private const string kNewTestScriptName = "NewTestScript.cs"; private const string kNunit = "nunit.framework.dll"; [MenuItem("Assets/Create/Testing/Tests Assembly Folder", false, 83)] public static void MenuItemAddFolderAndAsmDefForTesting() { AddFolderAndAsmDefForTesting(); } [MenuItem("Assets/Create/Testing/Tests Assembly Folder", true, 83)] public static bool MenuItemAddFolderAndAsmDefForTestingWithValidation() { return !SelectedFolderContainsTestAssembly(); } public static void AddFolderAndAsmDefForTesting(bool isEditorOnly = false) { ProjectWindowUtil.CreateFolderWithTemplates("Tests", isEditorOnly ? kAssemblyDefinitionEditModeTestTemplate : kAssemblyDefinitionTestTemplate); } public static bool SelectedFolderContainsTestAssembly() { var theNearestCustomScriptAssembly = GetTheNearestCustomScriptAssembly(); if (theNearestCustomScriptAssembly != null) { return theNearestCustomScriptAssembly.PrecompiledReferences != null && theNearestCustomScriptAssembly.PrecompiledReferences.Any(x => Path.GetFileName(x) == kNunit); } return false; } [MenuItem("Assets/Create/Testing/C# Test Script", false, 83)] public static void AddTest() { var basePath = Path.Combine(EditorApplication.applicationContentsPath, kResourcesTemplatePath); var destPath = Path.Combine(GetActiveFolderPath(), kNewTestScriptName); var templatePath = Path.Combine(basePath, kTestScriptTemplate); var icon = EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D; ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance(), destPath, icon, templatePath); AssetDatabase.Refresh(); } [MenuItem("Assets/Create/Testing/C# Test Script", true, 83)] public static bool CanAddScriptAndItWillCompile() { return CanAddEditModeTestScriptAndItWillCompile() || CanAddPlayModeTestScriptAndItWillCompile(); } public static bool CanAddEditModeTestScriptAndItWillCompile() { var theNearestCustomScriptAssembly = GetTheNearestCustomScriptAssembly(); if (theNearestCustomScriptAssembly != null) { return (theNearestCustomScriptAssembly.AssemblyFlags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly; } var activeFolderPath = GetActiveFolderPath(); return activeFolderPath.ToLower().Contains("/editor"); } public static bool CanAddPlayModeTestScriptAndItWillCompile() { if (PlayerSettings.playModeTestRunnerEnabled) { return true; } var theNearestCustomScriptAssembly = GetTheNearestCustomScriptAssembly(); if (theNearestCustomScriptAssembly == null) { return false; } var hasTestAssemblyFlag = theNearestCustomScriptAssembly.PrecompiledReferences != null && theNearestCustomScriptAssembly.PrecompiledReferences.Any(x => Path.GetFileName(x) == kNunit);; var editorOnlyAssembly = (theNearestCustomScriptAssembly.AssemblyFlags & AssemblyFlags.EditorOnly) != 0; return hasTestAssemblyFlag && !editorOnlyAssembly; } public static string GetActiveFolderPath() { var path = "Assets"; foreach (var obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) { path = AssetDatabase.GetAssetPath(obj); if (!string.IsNullOrEmpty(path) && File.Exists(path)) { path = Path.GetDirectoryName(path); break; } } return path; } private static CustomScriptAssembly GetTheNearestCustomScriptAssembly() { CustomScriptAssembly findCustomScriptAssemblyFromScriptPath; try { findCustomScriptAssemblyFromScriptPath = EditorCompilationInterface.Instance.FindCustomScriptAssemblyFromScriptPath( Path.Combine(GetActiveFolderPath(), "Foo.cs")); } catch (Exception) { return null; } return findCustomScriptAssemblyFromScriptPath; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListGuiHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 97a05971510726f438153cd4987526fb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/Icons.cs ================================================ using UnityEngine; namespace UnityEditor.TestTools.TestRunner.GUI { internal static class Icons { public static readonly Texture2D s_FailImg; public static readonly Texture2D s_IgnoreImg; public static readonly Texture2D s_SuccessImg; public static readonly Texture2D s_UnknownImg; public static readonly Texture2D s_InconclusiveImg; public static readonly Texture2D s_StopwatchImg; static Icons() { s_FailImg = EditorGUIUtility.IconContent("TestFailed").image as Texture2D; s_IgnoreImg = EditorGUIUtility.IconContent("TestIgnored").image as Texture2D; s_SuccessImg = EditorGUIUtility.IconContent("TestPassed").image as Texture2D; s_UnknownImg = EditorGUIUtility.IconContent("TestNormal").image as Texture2D; s_InconclusiveImg = EditorGUIUtility.IconContent("TestInconclusive").image as Texture2D; s_StopwatchImg = EditorGUIUtility.IconContent("TestStopwatch").image as Texture2D; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/Icons.cs.meta ================================================ fileFormatVersion: 2 guid: 27769e9b00b038d47aefe306a4d20bec MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/TestListTreeViewDataSource.cs ================================================ using System.Collections.Generic; using UnityEditor.IMGUI.Controls; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.SceneManagement; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { internal class TestListTreeViewDataSource : TreeViewDataSource { private bool m_ExpandTreeOnCreation; private readonly TestListGUI m_TestListGUI; private ITestAdaptor m_RootTest; public TestListTreeViewDataSource(TreeViewController testListTree, TestListGUI testListGUI, ITestAdaptor rootTest) : base(testListTree) { showRootItem = false; rootIsCollapsable = false; m_TestListGUI = testListGUI; m_RootTest = rootTest; } public override void FetchData() { var sceneName = SceneManager.GetActiveScene().name; if (sceneName.StartsWith("InitTestScene")) sceneName = PlaymodeTestsController.GetController().settings.originalScene; var testListBuilder = new TestTreeViewBuilder(m_RootTest, m_TestListGUI.newResultList, m_TestListGUI.m_TestRunnerUIFilter); m_RootItem = testListBuilder.BuildTreeView(null, false, sceneName); SetExpanded(m_RootItem, true); if (m_RootItem.hasChildren && m_RootItem.children.Count == 1) SetExpanded(m_RootItem.children[0], true); if (m_ExpandTreeOnCreation) SetExpandedWithChildren(m_RootItem, true); m_TestListGUI.newResultList = new List(testListBuilder.results); m_TestListGUI.m_TestRunnerUIFilter.availableCategories = testListBuilder.AvailableCategories; m_NeedRefreshRows = true; } public override bool IsRenamingItemAllowed(TreeViewItem item) { return false; } public void ExpandTreeOnCreation() { m_ExpandTreeOnCreation = true; } public override bool IsExpandable(TreeViewItem item) { if (item is TestTreeViewItem) return ((TestTreeViewItem)item).IsGroupNode; return base.IsExpandable(item); } protected override List Search(TreeViewItem rootItem, string search) { var result = new List(); if (rootItem.hasChildren) { foreach (var child in rootItem.children) { SearchTestTree(child, search, result); } } return result; } protected void SearchTestTree(TreeViewItem item, string search, IList searchResult) { var testItem = item as TestTreeViewItem; if (!testItem.IsGroupNode) { if (testItem.FullName.ToLower().Contains(search)) { searchResult.Add(item); } } else if (item.children != null) { foreach (var child in item.children) SearchTestTree(child, search, searchResult); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/TestListTreeViewDataSource.cs.meta ================================================ fileFormatVersion: 2 guid: ce87c287371edde43a4b5fcfdee7b9ef MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/TestListTreeViewGUI.cs ================================================ using UnityEditor.IMGUI.Controls; namespace UnityEditor.TestTools.TestRunner.GUI { internal class TestListTreeViewGUI : TreeViewGUI { public TestListTreeViewGUI(TreeViewController testListTree) : base(testListTree) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/TestListTreeViewGUI.cs.meta ================================================ fileFormatVersion: 2 guid: 52c907c81459f324497af504b84fd557 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/TestTreeViewItem.cs ================================================ using System; using System.Reflection; using System.Text; using UnityEditor.IMGUI.Controls; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { internal sealed class TestTreeViewItem : TreeViewItem { public TestRunnerResult result; internal ITestAdaptor m_Test; public Type type; public MethodInfo method; private const int k_ResultTestMaxLength = 15000; public bool IsGroupNode { get { return m_Test.IsSuite; } } public string FullName { get { return m_Test.FullName; } } public TestTreeViewItem(ITestAdaptor test, int depth, TreeViewItem parent) : base(GetId(test), depth, parent, test.Name) { m_Test = test; if (test.TypeInfo != null) { type = test.TypeInfo.Type; } if (test.Method != null) { method = test.Method.MethodInfo; } displayName = test.Name.Replace("\n", ""); icon = Icons.s_UnknownImg; } private static int GetId(ITestAdaptor test) { return test.UniqueName.GetHashCode(); } public void SetResult(TestRunnerResult testResult) { result = testResult; result.SetResultChangedCallback(ResultUpdated); ResultUpdated(result); } public string GetResultText() { var durationString = String.Format("{0:0.000}", result.duration); var sb = new StringBuilder(string.Format("{0} ({1}s)", displayName.Trim(), durationString)); if (!string.IsNullOrEmpty(result.description)) { sb.AppendFormat("\n{0}", result.description); } if (!string.IsNullOrEmpty(result.messages)) { sb.Append("\n---\n"); sb.Append(result.messages.Trim()); } if (!string.IsNullOrEmpty(result.stacktrace)) { sb.Append("\n---\n"); sb.Append(result.stacktrace.Trim()); } if (!string.IsNullOrEmpty(result.output)) { sb.Append("\n---\n"); sb.Append(result.output.Trim()); } if (sb.Length > k_ResultTestMaxLength) { sb.Length = k_ResultTestMaxLength; sb.AppendFormat("...\n\n---MESSAGE TRUNCATED AT {0} CHARACTERS---", k_ResultTestMaxLength); } return sb.ToString().Trim(); } private void ResultUpdated(TestRunnerResult testResult) { switch (testResult.resultStatus) { case TestRunnerResult.ResultStatus.Passed: icon = Icons.s_SuccessImg; break; case TestRunnerResult.ResultStatus.Failed: icon = Icons.s_FailImg; break; case TestRunnerResult.ResultStatus.Inconclusive: icon = Icons.s_InconclusiveImg; break; case TestRunnerResult.ResultStatus.Skipped: icon = Icons.s_IgnoreImg; break; default: if (testResult.ignoredOrSkipped) { icon = Icons.s_IgnoreImg; } else if (testResult.notRunnable) { icon = Icons.s_FailImg; } else { icon = Icons.s_UnknownImg; } break; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView/TestTreeViewItem.cs.meta ================================================ fileFormatVersion: 2 guid: ce567ddbf30368344bc7b80e20cac36e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestListTreeView.meta ================================================ fileFormatVersion: 2 guid: 68cb547af0187634aad591a09c01cd5b folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestRunnerResult.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { [Serializable] internal class TestRunnerResult : TestRunnerFilter.IClearableResult { public string id; public string uniqueId; public string name; public string fullName; public ResultStatus resultStatus = ResultStatus.NotRun; public float duration; public string messages; public string output; public string stacktrace; public bool notRunnable; public bool ignoredOrSkipped; public string description; public bool isSuite; public List categories; public string parentId; public string parentUniqueId; //This field is suppose to mark results from before domain reload //Such result is outdated because the code might haev changed //This field will get reset every time a domain reload happens [NonSerialized] public bool notOutdated; protected Action m_OnResultUpdate; internal TestRunnerResult(ITestAdaptor test) { id = test.Id; uniqueId = test.UniqueName; fullName = test.FullName; name = test.Name; description = test.Description; isSuite = test.IsSuite; ignoredOrSkipped = test.RunState == RunState.Ignored || test.RunState == RunState.Skipped; notRunnable = test.RunState == RunState.NotRunnable; if (ignoredOrSkipped) { messages = test.SkipReason; } if (notRunnable) { resultStatus = ResultStatus.Failed; messages = test.SkipReason; } categories = test.Categories.ToList(); parentId = test.ParentId; parentUniqueId = test.ParentUniqueName; } internal TestRunnerResult(ITestResultAdaptor testResult) : this(testResult.Test) { notOutdated = true; messages = testResult.Message; output = testResult.Output; stacktrace = testResult.StackTrace; duration = (float)testResult.Duration; if (testResult.Test.IsSuite && testResult.ResultState == "Ignored") { resultStatus = ResultStatus.Passed; } else { resultStatus = ParseNUnitResultStatus(testResult.TestStatus); } } public void Update(TestRunnerResult result) { if (ReferenceEquals(result, null)) return; resultStatus = result.resultStatus; duration = result.duration; messages = result.messages; output = result.output; stacktrace = result.stacktrace; ignoredOrSkipped = result.ignoredOrSkipped; notRunnable = result.notRunnable; description = result.description; notOutdated = result.notOutdated; if (m_OnResultUpdate != null) m_OnResultUpdate(this); } public void SetResultChangedCallback(Action resultUpdated) { m_OnResultUpdate = resultUpdated; } [Serializable] internal enum ResultStatus { NotRun, Passed, Failed, Inconclusive, Skipped } private static ResultStatus ParseNUnitResultStatus(TestStatus status) { switch (status) { case TestStatus.Passed: return ResultStatus.Passed; case TestStatus.Failed: return ResultStatus.Failed; case TestStatus.Inconclusive: return ResultStatus.Inconclusive; case TestStatus.Skipped: return ResultStatus.Skipped; default: return ResultStatus.NotRun; } } public override string ToString() { return string.Format("{0} ({1})", name, fullName); } public string Id { get { return uniqueId; } } public string FullName { get { return fullName; } } public string ParentId { get { return parentUniqueId; } } public bool IsSuite { get { return isSuite; } } public List Categories { get { return categories; } } public void Clear() { resultStatus = ResultStatus.NotRun; if (m_OnResultUpdate != null) m_OnResultUpdate(this); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestRunnerResult.cs.meta ================================================ fileFormatVersion: 2 guid: a04a45bbed9e1714f9902fc9443669b9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestRunnerUIFilter.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { [Serializable] internal class TestRunnerUIFilter { private int m_PassedCount; private int m_FailedCount; private int m_NotRunCount; private int m_InconclusiveCount; private int m_SkippedCount; public int PassedCount { get { return m_PassedCount; } } public int FailedCount { get { return m_FailedCount + m_InconclusiveCount; } } public int NotRunCount { get { return m_NotRunCount + m_SkippedCount; } } [SerializeField] public bool PassedHidden; [SerializeField] public bool FailedHidden; [SerializeField] public bool NotRunHidden; [SerializeField] private string m_SearchString; [SerializeField] private int selectedCategoryMask; public string[] availableCategories = new string[0]; private GUIContent m_SucceededBtn; private GUIContent m_FailedBtn; private GUIContent m_NotRunBtn; public Action RebuildTestList; public Action SearchStringChanged; public bool IsFiltering { get { return !string.IsNullOrEmpty(m_SearchString) || PassedHidden || FailedHidden || NotRunHidden || selectedCategoryMask != 0; } } public string[] CategoryFilter { get { var list = new List(); for (int i = 0; i < availableCategories.Length; i++) { if ((selectedCategoryMask & (1 << i)) != 0) { list.Add(availableCategories[i]); } } return list.ToArray(); } } public void UpdateCounters(List resultList) { m_PassedCount = m_FailedCount = m_NotRunCount = m_InconclusiveCount = m_SkippedCount = 0; foreach (var result in resultList) { if (result.isSuite) continue; switch (result.resultStatus) { case TestRunnerResult.ResultStatus.Passed: m_PassedCount++; break; case TestRunnerResult.ResultStatus.Failed: m_FailedCount++; break; case TestRunnerResult.ResultStatus.Inconclusive: m_InconclusiveCount++; break; case TestRunnerResult.ResultStatus.Skipped: m_SkippedCount++; break; case TestRunnerResult.ResultStatus.NotRun: default: m_NotRunCount++; break; } } var succeededTooltip = string.Format("Show tests that succeeded\n{0} succeeded", m_PassedCount); m_SucceededBtn = new GUIContent(PassedCount.ToString(), Icons.s_SuccessImg, succeededTooltip); var failedTooltip = string.Format("Show tests that failed\n{0} failed\n{1} inconclusive", m_FailedCount, m_InconclusiveCount); m_FailedBtn = new GUIContent(FailedCount.ToString(), Icons.s_FailImg, failedTooltip); var notRunTooltip = string.Format("Show tests that didn't run\n{0} didn't run\n{1} skipped or ignored", m_NotRunCount, m_SkippedCount); m_NotRunBtn = new GUIContent(NotRunCount.ToString(), Icons.s_UnknownImg, notRunTooltip); } public void Draw() { EditorGUI.BeginChangeCheck(); m_SearchString = EditorGUILayout.ToolbarSearchField(m_SearchString); if (EditorGUI.EndChangeCheck() && SearchStringChanged != null) { SearchStringChanged(m_SearchString); } if (availableCategories != null && availableCategories.Any()) { EditorGUI.BeginChangeCheck(); selectedCategoryMask = EditorGUILayout.MaskField(selectedCategoryMask, availableCategories, EditorStyles.toolbarDropDown, GUILayout.MaxWidth(150)); if (EditorGUI.EndChangeCheck() && RebuildTestList != null) { RebuildTestList(); } } else { EditorGUILayout.Popup(0, new[] { "" }, EditorStyles.toolbarDropDown, GUILayout.MaxWidth(150)); } EditorGUI.BeginChangeCheck(); if (m_SucceededBtn != null) { PassedHidden = !GUILayout.Toggle(!PassedHidden, m_SucceededBtn, EditorStyles.toolbarButton, GUILayout.MaxWidth(GetMaxWidth(PassedCount))); } if (m_FailedBtn != null) { FailedHidden = !GUILayout.Toggle(!FailedHidden, m_FailedBtn, EditorStyles.toolbarButton, GUILayout.MaxWidth(GetMaxWidth(FailedCount))); } if (m_NotRunBtn != null) { NotRunHidden = !GUILayout.Toggle(!NotRunHidden, m_NotRunBtn, EditorStyles.toolbarButton, GUILayout.MaxWidth(GetMaxWidth(NotRunCount))); } if (EditorGUI.EndChangeCheck() && RebuildTestList != null) { RebuildTestList(); } } private static int GetMaxWidth(int count) { if (count < 10) return 33; return count < 100 ? 40 : 47; } public void Clear() { PassedHidden = false; FailedHidden = false; NotRunHidden = false; selectedCategoryMask = 0; m_SearchString = ""; if (SearchStringChanged != null) { SearchStringChanged(m_SearchString); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/TestRunnerUIFilter.cs.meta ================================================ fileFormatVersion: 2 guid: 15f870c6975ad6449b5b52514b90dc2b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views/EditModeTestListGUI.cs ================================================ using System; using System.Linq; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.TestTools; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { [Serializable] internal class EditModeTestListGUI : TestListGUI { public override TestMode TestMode { get { return TestMode.EditMode; } } public override void RenderNoTestsInfo() { if (!TestListGUIHelper.SelectedFolderContainsTestAssembly()) { var noTestText = "No tests to show"; if (!PlayerSettings.playModeTestRunnerEnabled) { const string testsArePulledFromCustomAssemblies = "EditMode tests can be in Editor only Assemblies, either in the editor special folder or Editor only Assembly Definitions with added Unity References \"Test Assemblies\"."; noTestText += Environment.NewLine + testsArePulledFromCustomAssemblies; } EditorGUILayout.HelpBox(noTestText, MessageType.Info); if (GUILayout.Button("Create EditMode Test Assembly Folder")) { TestListGUIHelper.AddFolderAndAsmDefForTesting(isEditorOnly: true); } } if (!TestListGUIHelper.CanAddEditModeTestScriptAndItWillCompile()) { UnityEngine.GUI.enabled = false; EditorGUILayout.HelpBox("EditMode test scripts can only be created in editor test assemblies.", MessageType.Warning); } if (GUILayout.Button("Create Test Script in current folder")) { TestListGUIHelper.AddTest(); } UnityEngine.GUI.enabled = true; } public override void PrintHeadPanel() { base.PrintHeadPanel(); DrawFilters(); } protected override void RunTests(TestRunnerFilter filter) { if (EditorUtility.scriptCompilationFailed) { Debug.LogError("Fix compilation issues before running tests"); return; } filter.ClearResults(newResultList.OfType().ToList()); RerunCallbackData.instance.runFilter = filter; RerunCallbackData.instance.testMode = TestMode.EditMode; var testRunnerApi = ScriptableObject.CreateInstance(); testRunnerApi.Execute(new ExecutionSettings() { filter = new Filter() { categoryNames = filter.categoryNames, groupNames = filter.groupNames, testMode = TestMode, testNames = filter.testNames } }); } public override TestPlatform TestPlatform { get { return TestPlatform.EditMode; } } protected override bool IsBusy() { return EditModeLauncher.IsRunning || EditorApplication.isCompiling || EditorApplication.isPlaying; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views/EditModeTestListGUI.cs.meta ================================================ fileFormatVersion: 2 guid: 0336a32a79bfaed43a3fd2d88b91e974 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views/PlayModeTestListGUI.cs ================================================ using System; using System.Linq; using UnityEditor.SceneManagement; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.TestTools; using UnityEngine.SceneManagement; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner.GUI { [Serializable] internal class PlayModeTestListGUI : TestListGUI { public override TestMode TestMode { get { return TestMode.PlayMode; } } public override void PrintHeadPanel() { EditorGUILayout.BeginHorizontal(GUILayout.ExpandHeight(false)); base.PrintHeadPanel(); if (GUILayout.Button("Run all in player (" + EditorUserBuildSettings.activeBuildTarget + ")", EditorStyles.toolbarButton)) { RunTestsInPlayer(null); } EditorGUILayout.EndHorizontal(); DrawFilters(); EditorGUILayout.BeginHorizontal(GUILayout.ExpandHeight(false)); EditorGUILayout.EndHorizontal(); } public override void RenderNoTestsInfo() { if (!TestListGUIHelper.SelectedFolderContainsTestAssembly()) { var noTestText = "No tests to show"; if (!PlayerSettings.playModeTestRunnerEnabled) { const string testsArePulledFromCustomAssemblues = "Test Assemblies are defined by Assembly Definitions where you add Unity References \"Test Assemblies\""; const string infoTextAboutTestsInAllAssemblies = "To have tests in all assemblies enable it in the Test Runner window context menu"; noTestText += Environment.NewLine + testsArePulledFromCustomAssemblues + Environment.NewLine + infoTextAboutTestsInAllAssemblies; } EditorGUILayout.HelpBox(noTestText, MessageType.Info); if (GUILayout.Button("Create PlayMode Test Assembly Folder")) { TestListGUIHelper.AddFolderAndAsmDefForTesting(); } } if (!TestListGUIHelper.CanAddPlayModeTestScriptAndItWillCompile()) { UnityEngine.GUI.enabled = false; EditorGUILayout.HelpBox("PlayMode test scripts can only be created in non editor test assemblies.", MessageType.Warning); } if (GUILayout.Button("Create Test Script in current folder")) { TestListGUIHelper.AddTest(); } UnityEngine.GUI.enabled = true; } protected override void RunTests(TestRunnerFilter filter) { // Give user chance to save the changes to their currently open scene because we close it and load our own var cancelled = !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo(); if (cancelled) return; filter.ClearResults(newResultList.OfType().ToList()); RerunCallbackData.instance.runFilter = filter; RerunCallbackData.instance.testMode = TestMode.PlayMode; var testRunnerApi = ScriptableObject.CreateInstance(); testRunnerApi.Execute(new ExecutionSettings() { filter = new Filter() { categoryNames = filter.categoryNames, groupNames = filter.groupNames, testMode = TestMode, testNames = filter.testNames } }); } protected void RunTestsInPlayer(TestRunnerFilter filter) { var settings = PlaymodeTestsControllerSettings.CreateRunnerSettings(filter); var testExecutor = new PlayerLauncher(settings, null, null); testExecutor.Run(); GUIUtility.ExitGUI(); } public override TestPlatform TestPlatform { get { return TestPlatform.PlayMode; } } protected override bool IsBusy() { return PlaymodeLauncher.IsRunning || EditorApplication.isCompiling || EditorApplication.isPlaying; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views/PlayModeTestListGUI.cs.meta ================================================ fileFormatVersion: 2 guid: c3efd39f2cfb43a4c830d4fd5689900f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views/TestListGUIBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using UnityEditor.IMGUI.Controls; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.TestTools.TestRunner.GUI; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner.GUI { internal abstract class TestListGUI { private static readonly GUIContent s_GUIRunSelectedTests = EditorGUIUtility.TrTextContent("Run Selected", "Run selected test(s)"); private static readonly GUIContent s_GUIRunAllTests = EditorGUIUtility.TrTextContent("Run All", "Run all tests"); private static readonly GUIContent s_GUIRerunFailedTests = EditorGUIUtility.TrTextContent("Rerun Failed", "Rerun all failed tests"); private static readonly GUIContent s_GUIRun = EditorGUIUtility.TrTextContent("Run"); private static readonly GUIContent s_GUIRunUntilFailed = EditorGUIUtility.TrTextContent("Run Until Failed"); private static readonly GUIContent s_GUIRun100Times = EditorGUIUtility.TrTextContent("Run 100 times"); private static readonly GUIContent s_GUIOpenTest = EditorGUIUtility.TrTextContent("Open source code"); private static readonly GUIContent s_GUIOpenErrorLine = EditorGUIUtility.TrTextContent("Open error line"); [SerializeField] protected TestRunnerWindow m_Window; [SerializeField] public List newResultList = new List(); [SerializeField] private string m_ResultText; [SerializeField] private string m_ResultStacktrace; private TreeViewController m_TestListTree; [SerializeField] internal TreeViewState m_TestListState; [SerializeField] internal TestRunnerUIFilter m_TestRunnerUIFilter = new TestRunnerUIFilter(); private Vector2 m_TestInfoScroll, m_TestListScroll; private string m_PreviousProjectPath; private List m_QueuedResults = new List(); protected TestListGUI() { MonoCecilHelper = new MonoCecilHelper(); AssetsDatabaseHelper = new AssetsDatabaseHelper(); GuiHelper = new GuiHelper(MonoCecilHelper, AssetsDatabaseHelper); } protected IMonoCecilHelper MonoCecilHelper { get; private set; } protected IAssetsDatabaseHelper AssetsDatabaseHelper { get; private set; } protected IGuiHelper GuiHelper { get; private set; } public abstract TestMode TestMode { get; } public virtual void PrintHeadPanel() { EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); using (new EditorGUI.DisabledScope(IsBusy())) { if (GUILayout.Button(s_GUIRunAllTests, EditorStyles.toolbarButton)) { var filter = new TestRunnerFilter {categoryNames = m_TestRunnerUIFilter.CategoryFilter}; RunTests(filter); GUIUtility.ExitGUI(); } } using (new EditorGUI.DisabledScope(m_TestListTree == null || !m_TestListTree.HasSelection() || IsBusy())) { if (GUILayout.Button(s_GUIRunSelectedTests, EditorStyles.toolbarButton)) { RunTests(GetSelectedTestsAsFilter(m_TestListTree.GetSelection())); GUIUtility.ExitGUI(); } } using (new EditorGUI.DisabledScope(m_TestRunnerUIFilter.FailedCount == 0 || IsBusy())) { if (GUILayout.Button(s_GUIRerunFailedTests, EditorStyles.toolbarButton)) { var failedTestnames = new List(); foreach (var result in newResultList) { if (result.isSuite) continue; if (result.resultStatus == TestRunnerResult.ResultStatus.Failed || result.resultStatus == TestRunnerResult.ResultStatus.Inconclusive) failedTestnames.Add(result.fullName); } RunTests(new TestRunnerFilter() {testNames = failedTestnames.ToArray(), categoryNames = m_TestRunnerUIFilter.CategoryFilter}); GUIUtility.ExitGUI(); } } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } protected void DrawFilters() { EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); m_TestRunnerUIFilter.Draw(); EditorGUILayout.EndHorizontal(); } public bool HasTreeData() { return m_TestListTree != null; } public virtual void RenderTestList() { if (m_TestListTree == null) { GUILayout.Label("Loading..."); return; } m_TestListScroll = EditorGUILayout.BeginScrollView(m_TestListScroll, GUILayout.ExpandWidth(true), GUILayout.MaxWidth(2000)); if (m_TestListTree.data.root == null || m_TestListTree.data.rowCount == 0 || (!m_TestListTree.isSearching && !m_TestListTree.data.GetItem(0).hasChildren)) { if (m_TestRunnerUIFilter.IsFiltering) { if (GUILayout.Button("Clear filters")) { m_TestRunnerUIFilter.Clear(); m_TestListTree.ReloadData(); m_Window.Repaint(); } } RenderNoTestsInfo(); } else { var treeRect = EditorGUILayout.GetControlRect(GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true)); var treeViewKeyboardControlId = GUIUtility.GetControlID(FocusType.Keyboard); m_TestListTree.OnGUI(treeRect, treeViewKeyboardControlId); } EditorGUILayout.EndScrollView(); } public virtual void RenderNoTestsInfo() { EditorGUILayout.HelpBox("No tests to show", MessageType.Info); } public void RenderDetails() { m_TestInfoScroll = EditorGUILayout.BeginScrollView(m_TestInfoScroll); var resultTextSize = TestRunnerWindow.Styles.info.CalcSize(new GUIContent(m_ResultText)); EditorGUILayout.SelectableLabel(m_ResultText, TestRunnerWindow.Styles.info, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true), GUILayout.MinWidth(resultTextSize.x), GUILayout.MinHeight(resultTextSize.y)); EditorGUILayout.EndScrollView(); } public void Reload() { if (m_TestListTree != null) { m_TestListTree.ReloadData(); UpdateQueuedResults(); } } public void Repaint() { if (m_TestListTree == null || m_TestListTree.data.root == null) { return; } m_TestListTree.Repaint(); if (m_TestListTree.data.rowCount == 0) m_TestListTree.SetSelection(new int[0], false); TestSelectionCallback(m_TestListState.selectedIDs.ToArray()); } public void Init(TestRunnerWindow window, ITestAdaptor rootTest) { if (m_Window == null) { m_Window = window; } if (m_TestListTree == null) { if (m_TestListState == null) { m_TestListState = new TreeViewState(); } if (m_TestListTree == null) m_TestListTree = new TreeViewController(m_Window, m_TestListState); m_TestListTree.deselectOnUnhandledMouseDown = false; m_TestListTree.selectionChangedCallback += TestSelectionCallback; m_TestListTree.itemDoubleClickedCallback += TestDoubleClickCallback; m_TestListTree.contextClickItemCallback += TestContextClickCallback; var testListTreeViewDataSource = new TestListTreeViewDataSource(m_TestListTree, this, rootTest); if (!newResultList.Any()) testListTreeViewDataSource.ExpandTreeOnCreation(); m_TestListTree.Init(new Rect(), testListTreeViewDataSource, new TestListTreeViewGUI(m_TestListTree), null); } EditorApplication.update += RepaintIfProjectPathChanged; m_TestRunnerUIFilter.UpdateCounters(newResultList); m_TestRunnerUIFilter.RebuildTestList = () => m_TestListTree.ReloadData(); m_TestRunnerUIFilter.SearchStringChanged = s => m_TestListTree.searchString = s; } public void UpdateResult(TestRunnerResult result) { if (!HasTreeData()) { m_QueuedResults.Add(result); return; } if (newResultList.All(x => x.uniqueId != result.uniqueId)) { return; } var testRunnerResult = newResultList.FirstOrDefault(x => x.uniqueId == result.uniqueId); if (testRunnerResult != null) { testRunnerResult.Update(result); } Repaint(); m_Window.Repaint(); } private void UpdateQueuedResults() { foreach (var testRunnerResult in m_QueuedResults) { var existingResult = newResultList.FirstOrDefault(x => x.uniqueId == testRunnerResult.uniqueId); if (existingResult != null) { existingResult.Update(testRunnerResult); } } m_QueuedResults.Clear(); TestSelectionCallback(m_TestListState.selectedIDs.ToArray()); Repaint(); m_Window.Repaint(); } internal void TestSelectionCallback(int[] selected) { if (m_TestListTree != null && selected.Length == 1) { if (m_TestListTree != null) { var node = m_TestListTree.FindItem(selected[0]); if (node is TestTreeViewItem) { var test = node as TestTreeViewItem; m_ResultText = test.GetResultText(); m_ResultStacktrace = test.result.stacktrace; } } } else if (selected.Length == 0) { m_ResultText = ""; } } protected virtual void TestDoubleClickCallback(int id) { if (IsBusy()) return; RunTests(GetSelectedTestsAsFilter(new List { id })); GUIUtility.ExitGUI(); } protected virtual void RunTests(TestRunnerFilter filter) { throw new NotImplementedException(); } protected virtual void TestContextClickCallback(int id) { if (id == 0) return; var m = new GenericMenu(); var testFilter = GetSelectedTestsAsFilter(m_TestListState.selectedIDs); var multilineSelection = m_TestListState.selectedIDs.Count > 1; if (!multilineSelection) { var testNode = GetSelectedTest(); var isNotSuite = !testNode.IsGroupNode; if (isNotSuite) { if (!string.IsNullOrEmpty(m_ResultStacktrace)) { m.AddItem(s_GUIOpenErrorLine, false, data => { if (!GuiHelper.OpenScriptInExternalEditor(m_ResultStacktrace)) { GuiHelper.OpenScriptInExternalEditor(testNode.type, testNode.method); } }, ""); } m.AddItem(s_GUIOpenTest, false, data => GuiHelper.OpenScriptInExternalEditor(testNode.type, testNode.method), ""); m.AddSeparator(""); } } if (!IsBusy()) { m.AddItem(multilineSelection ? s_GUIRunSelectedTests : s_GUIRun, false, data => RunTests(testFilter), ""); if (EditorPrefs.GetBool("DeveloperMode", false)) { m.AddItem(multilineSelection ? s_GUIRunSelectedTests : s_GUIRunUntilFailed, false, data => { testFilter.testRepetitions = int.MaxValue; RunTests(testFilter); }, ""); m.AddItem(multilineSelection ? s_GUIRunSelectedTests : s_GUIRun100Times, false, data => { testFilter.testRepetitions = 100; RunTests(testFilter); }, ""); } } else m.AddDisabledItem(multilineSelection ? s_GUIRunSelectedTests : s_GUIRun, false); m.ShowAsContext(); } private TestRunnerFilter GetSelectedTestsAsFilter(IEnumerable selectedIDs) { var namesToRun = new List(); var exactNamesToRun = new List(); var assembliesToRun = new List(); foreach (var lineId in selectedIDs) { var line = m_TestListTree.FindItem(lineId); if (line is TestTreeViewItem) { var testLine = line as TestTreeViewItem; if (testLine.IsGroupNode && !testLine.FullName.Contains("+")) { if (testLine.parent != null && testLine.parent.displayName == "Invisible Root Item") { //Root node selected. Use an empty TestRunnerFilter to run every test namesToRun.Clear(); exactNamesToRun.Clear(); assembliesToRun.Clear(); break; } if (testLine.FullName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) assembliesToRun.Add(TestRunnerFilter.AssemblyNameFromPath(testLine.FullName)); else namesToRun.Add(string.Format("^{0}$", testLine.FullName)); } else exactNamesToRun.Add(testLine.FullName); } } var filter = new TestRunnerFilter { assemblyNames = assembliesToRun.ToArray(), groupNames = namesToRun.ToArray(), testNames = exactNamesToRun.ToArray(), categoryNames = m_TestRunnerUIFilter.CategoryFilter }; return filter; } private TestTreeViewItem GetSelectedTest() { foreach (var lineId in m_TestListState.selectedIDs) { var line = m_TestListTree.FindItem(lineId); if (line is TestTreeViewItem) { return line as TestTreeViewItem; } } return null; } public abstract TestPlatform TestPlatform { get; } public void RebuildUIFilter() { m_TestRunnerUIFilter.UpdateCounters(newResultList); if (m_TestRunnerUIFilter.IsFiltering) { m_TestListTree.ReloadData(); } } public void RepaintIfProjectPathChanged() { var path = TestListGUIHelper.GetActiveFolderPath(); if (path != m_PreviousProjectPath) { m_PreviousProjectPath = path; TestRunnerWindow.s_Instance.Repaint(); } EditorApplication.update -= RepaintIfProjectPathChanged; } protected abstract bool IsBusy(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views/TestListGUIBase.cs.meta ================================================ fileFormatVersion: 2 guid: b8abb41ceb6f62c45a00197ae59224c1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI/Views.meta ================================================ fileFormatVersion: 2 guid: c5535d742ea2e4941850b421f9c70a1f folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/GUI.meta ================================================ fileFormatVersion: 2 guid: 7e609b27ad2caa14c83dd9951b6c13c6 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/NUnitExtension/Attributes/AssetPipelineIgnore.cs ================================================ using System; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEditor.TestTools { /// /// Ignore attributes dedicated to Asset Import Pipeline backend version handling. /// internal static class AssetPipelineIgnore { internal enum AssetPipelineBackend { V1, V2 } /// /// Ignore the test when running with the legacy Asset Import Pipeline V1 backend. /// internal class IgnoreInV1 : AssetPipelineIgnoreAttribute { public IgnoreInV1(string ignoreReason) : base(AssetPipelineBackend.V1, ignoreReason) {} } /// /// Ignore the test when running with the latest Asset Import Pipeline V2 backend. /// internal class IgnoreInV2 : AssetPipelineIgnoreAttribute { public IgnoreInV2(string ignoreReason) : base(AssetPipelineBackend.V2, ignoreReason) {} } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] internal class AssetPipelineIgnoreAttribute : NUnitAttribute, IApplyToTest { readonly string m_IgnoreReason; readonly AssetPipelineBackend m_IgnoredBackend; static readonly AssetPipelineBackend k_ActiveBackend = AssetDatabase.IsV2Enabled() ? AssetPipelineBackend.V2 : AssetPipelineBackend.V1; static string ActiveBackendName = Enum.GetName(typeof(AssetPipelineBackend), k_ActiveBackend); public AssetPipelineIgnoreAttribute(AssetPipelineBackend backend, string ignoreReason) { m_IgnoredBackend = backend; m_IgnoreReason = ignoreReason; } public void ApplyToTest(Test test) { if (k_ActiveBackend == m_IgnoredBackend) { test.RunState = RunState.Ignored; var skipReason = string.Format("Not supported by asset pipeline {0} backend {1}", ActiveBackendName, m_IgnoreReason); test.Properties.Add(PropertyNames.SkipReason, skipReason); } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/NUnitExtension/Attributes/AssetPipelineIgnore.cs.meta ================================================ fileFormatVersion: 2 guid: b88caca58e05ee74486d86fb404c48e2 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/NUnitExtension/Attributes.meta ================================================ fileFormatVersion: 2 guid: 96c503bf059df984c86eecf572370347 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/NUnitExtension/TestRunnerStateSerializer.cs ================================================ using System; using System.Reflection; using System.Text; using System.Collections.Generic; using UnityEngine; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools.NUnitExtensions; using UnityEngine.TestTools.Logging; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class TestRunnerStateSerializer : IStateSerializer { private const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy; [SerializeField] private HideFlags m_OriginalHideFlags; [SerializeField] private bool m_ShouldRestore; [SerializeField] private string m_TestObjectTypeName; [SerializeField] private ScriptableObject m_TestObject; [SerializeField] private string m_TestObjectTxt; [SerializeField] private long StartTicks; [SerializeField] private double StartTimeOA; [SerializeField] private string output; [SerializeField] private LogMatch[] m_ExpectedLogs; public bool ShouldRestore() { return m_ShouldRestore; } public void SaveContext() { var currentContext = UnityTestExecutionContext.CurrentContext; if (currentContext.TestObject != null) { m_TestObjectTypeName = currentContext.TestObject.GetType().AssemblyQualifiedName; m_TestObject = null; m_TestObjectTxt = null; if (currentContext.TestObject is ScriptableObject) { m_TestObject = currentContext.TestObject as ScriptableObject; m_OriginalHideFlags = m_TestObject.hideFlags; m_TestObject.hideFlags |= HideFlags.DontSave; } else { m_TestObjectTxt = JsonUtility.ToJson(currentContext.TestObject); } } output = currentContext.CurrentResult.Output; StartTicks = currentContext.StartTicks; StartTimeOA = currentContext.StartTime.ToOADate(); if (LogScope.HasCurrentLogScope()) { m_ExpectedLogs = LogScope.Current.ExpectedLogs.ToArray(); } m_ShouldRestore = true; } public void RestoreContext() { var currentContext = UnityTestExecutionContext.CurrentContext; var outputProp = currentContext.CurrentResult.GetType().BaseType.GetField("_output", Flags); (outputProp.GetValue(currentContext.CurrentResult) as StringBuilder).Append(output); currentContext.StartTicks = StartTicks; currentContext.StartTime = DateTime.FromOADate(StartTimeOA); if (LogScope.HasCurrentLogScope()) { LogScope.Current.ExpectedLogs = new Queue(m_ExpectedLogs); } m_ShouldRestore = false; } public bool CanRestoreFromScriptableObject(Type requestedType) { if (m_TestObject == null) { return false; } return m_TestObjectTypeName == requestedType.AssemblyQualifiedName; } public ScriptableObject RestoreScriptableObjectInstance() { if (m_TestObject == null) { Debug.LogError("No object to restore"); return null; } EditorApplication.playModeStateChanged += OnPlayModeStateChanged; var temp = m_TestObject; m_TestObject = null; m_TestObjectTypeName = null; return temp; } public bool CanRestoreFromJson(Type requestedType) { if (string.IsNullOrEmpty(m_TestObjectTxt)) { return false; } return m_TestObjectTypeName == requestedType.AssemblyQualifiedName; } public void RestoreClassFromJson(ref object instance) { if (string.IsNullOrEmpty(m_TestObjectTxt)) { Debug.LogWarning("No JSON representation to restore"); return; } JsonUtility.FromJsonOverwrite(m_TestObjectTxt, instance); m_TestObjectTxt = null; m_TestObjectTypeName = null; } private void OnPlayModeStateChanged(PlayModeStateChange state) { if (m_TestObject == null) { EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; return; } //We set the DontSave flag here because the ScriptableObject would be nulled right before entering EditMode if (state == PlayModeStateChange.ExitingPlayMode) { m_TestObject.hideFlags |= HideFlags.DontSave; } else if (state == PlayModeStateChange.EnteredEditMode) { m_TestObject.hideFlags = m_OriginalHideFlags; EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/NUnitExtension/TestRunnerStateSerializer.cs.meta ================================================ fileFormatVersion: 2 guid: 124533853216377448d786fd7c725701 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/NUnitExtension.meta ================================================ fileFormatVersion: 2 guid: 3f9202a39620f51418046c7754f215f0 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/RequireApiProfileAttribute.cs ================================================ using System; using System.Linq; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEditor.TestTools { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] internal class RequireApiProfileAttribute : NUnitAttribute, IApplyToTest { public ApiCompatibilityLevel[] apiProfiles { get; private set; } public RequireApiProfileAttribute(params ApiCompatibilityLevel[] apiProfiles) { this.apiProfiles = apiProfiles; } void IApplyToTest.ApplyToTest(Test test) { test.Properties.Add(PropertyNames.Category, string.Format("ApiProfile({0})", string.Join(", ", apiProfiles.Select(p => p.ToString()).OrderBy(p => p).ToArray()))); ApiCompatibilityLevel testProfile = PlayerSettings.GetApiCompatibilityLevel(EditorUserBuildSettings.activeBuildTargetGroup); if (!apiProfiles.Contains(testProfile)) { string skipReason = "Skipping test as it requires a compatible api profile set: " + string.Join(", ", apiProfiles.Select(p => p.ToString()).ToArray()); test.RunState = RunState.Skipped; test.Properties.Add(PropertyNames.SkipReason, skipReason); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/RequireApiProfileAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: a667f6654ad7a9548b8c8e68b51c8895 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/RequirePlatformSupportAttribute.cs ================================================ using System; using System.Linq; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEditor.TestTools { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] public class RequirePlatformSupportAttribute : NUnitAttribute, IApplyToTest { public RequirePlatformSupportAttribute(params BuildTarget[] platforms) { this.platforms = platforms; } public BuildTarget[] platforms { get; private set; } void IApplyToTest.ApplyToTest(Test test) { test.Properties.Add(PropertyNames.Category, string.Format("RequirePlatformSupport({0})", string.Join(", ", platforms.Select(p => p.ToString()).OrderBy(p => p).ToArray()))); if (!platforms.All(p => BuildPipeline.IsBuildTargetSupported(BuildTargetGroup.Unknown, p))) { var missingPlatforms = platforms.Where(p => !BuildPipeline.IsBuildTargetSupported(BuildTargetGroup.Unknown, p)).Select(p => p.ToString()).ToArray(); string skipReason = "Test cannot be run as it requires support for the following platforms to be installed: " + string.Join(", ", missingPlatforms); test.RunState = RunState.Skipped; test.Properties.Add(PropertyNames.SkipReason, skipReason); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/RequirePlatformSupportAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: d2146428d3f1ad54eb7326c9a44b3284 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestBuildAssemblyFilter.cs ================================================ using System.Linq; using UnityEditor.Build; namespace UnityEditor.TestRunner { internal class TestBuildAssemblyFilter : IFilterBuildAssemblies { private const string nunitAssemblyName = "nunit.framework"; private const string unityTestRunnerAssemblyName = "UnityEngine.TestRunner"; public int callbackOrder { get; } public string[] OnFilterAssemblies(BuildOptions buildOptions, string[] assemblies) { if ((buildOptions & BuildOptions.IncludeTestAssemblies) == BuildOptions.IncludeTestAssemblies || PlayerSettings.playModeTestRunnerEnabled) { return assemblies; } return assemblies.Where(x => !x.Contains(nunitAssemblyName) && !x.Contains(unityTestRunnerAssemblyName)).ToArray(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestBuildAssemblyFilter.cs.meta ================================================ fileFormatVersion: 2 guid: 3411e19edd44cfd46b548b058c3bc36c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/AttributeFinderBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal abstract class AttributeFinderBase { public abstract IEnumerable Search(ITest tests, ITestFilter filter, RuntimePlatform testTargetPlatform); } internal abstract class AttributeFinderBase : AttributeFinderBase where T2 : Attribute { private readonly Func m_TypeSelector; protected AttributeFinderBase(Func typeSelector) { m_TypeSelector = typeSelector; } public override IEnumerable Search(ITest tests, ITestFilter filter, RuntimePlatform testTargetPlatform) { var selectedTests = new List(); GetMatchingTests(tests, filter, ref selectedTests, testTargetPlatform); var result = new List(); result.AddRange(GetTypesFromPrebuildAttributes(selectedTests)); result.AddRange(GetTypesFromInterface(selectedTests, testTargetPlatform)); return result.Distinct(); } private static void GetMatchingTests(ITest tests, ITestFilter filter, ref List resultList, RuntimePlatform testTargetPlatform) { foreach (var test in tests.Tests) { if (IsTestEnabledOnPlatform(test, testTargetPlatform)) { if (test.IsSuite) { GetMatchingTests(test, filter, ref resultList, testTargetPlatform); } else { if (filter.Pass(test)) resultList.Add(test); } } } } private static bool IsTestEnabledOnPlatform(ITest test, RuntimePlatform testTargetPlatform) { if (test.Method == null) { return true; } var attributesFromMethods = test.Method.GetCustomAttributes(true).Select(attribute => attribute); var attributesFromTypes = test.Method.TypeInfo.GetCustomAttributes(true).Select(attribute => attribute); if (!attributesFromMethods.All(a => a.IsPlatformSupported(testTargetPlatform))) { return false; } if (!attributesFromTypes.All(a => a.IsPlatformSupported(testTargetPlatform))) { return false; } return true; } private IEnumerable GetTypesFromPrebuildAttributes(IEnumerable tests) { var attributesFromMethods = tests.SelectMany(t => t.Method.GetCustomAttributes(true).Select(attribute => attribute)); var attributesFromTypes = tests.SelectMany(t => t.Method.TypeInfo.GetCustomAttributes(true).Select(attribute => attribute)); var result = new List(); result.AddRange(attributesFromMethods); result.AddRange(attributesFromTypes); return result.Select(m_TypeSelector).Where(type => type != null); } private static IEnumerable GetTypesFromInterface(IEnumerable selectedTests, RuntimePlatform testTargetPlatform) { var typesWithInterfaces = selectedTests.Where(t => typeof(T1).IsAssignableFrom(t.Method.TypeInfo.Type) && IsTestEnabledOnPlatform(t, testTargetPlatform)); return typesWithInterfaces.Select(t => t.Method.TypeInfo.Type); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/AttributeFinderBase.cs.meta ================================================ fileFormatVersion: 2 guid: 5d4de3d4682a8d641907cc75e4fb950e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/EditModeLauncher.cs ================================================ using System.Collections.Generic; using NUnit.Framework.Interfaces; using UnityEditor.SceneManagement; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner { internal class EditModeLauncher : TestLauncherBase { public static bool IsRunning; private readonly EditModeRunner m_EditModeRunner; public EditModeLauncher(TestRunnerFilter filter, TestPlatform platform) { m_EditModeRunner = ScriptableObject.CreateInstance(); m_EditModeRunner.UnityTestAssemblyRunnerFactory = new UnityTestAssemblyRunnerFactory(); m_EditModeRunner.Init(filter, platform); } public override void Run() { // Give user chance to save the changes to their currently open scene because we close it and load our own var cancelled = !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo(); if (cancelled) return; IsRunning = true; var exceptionThrown = ExecutePreBuildSetupMethods(m_EditModeRunner.GetLoadedTests(), m_EditModeRunner.GetFilter()); if (exceptionThrown) { CallbacksDelegator.instance.RunFailed("Run Failed: One or more errors in a prebuild setup. See the editor log for details."); return; } var undoGroup = Undo.GetCurrentGroup(); SceneSetup[] previousSceneSetup; if (!OpenNewScene(out previousSceneSetup)) return; var callback = AddEventHandler(); callback.previousSceneSetup = previousSceneSetup; callback.undoGroup = undoGroup; callback.runner = m_EditModeRunner; AddEventHandler(); m_EditModeRunner.Run(); AddEventHandler(); } private static bool OpenNewScene(out SceneSetup[] previousSceneSetup) { previousSceneSetup = null; var sceneCount = SceneManager.sceneCount; var scene = SceneManager.GetSceneAt(0); var isSceneNotPersisted = string.IsNullOrEmpty(scene.path); if (sceneCount == 1 && isSceneNotPersisted) { EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); return true; } RemoveUntitledScenes(); // In case the user chose not to save the dirty scenes we reload them ReloadUnsavedDirtyScene(); previousSceneSetup = EditorSceneManager.GetSceneManagerSetup(); scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); SceneManager.SetActiveScene(scene); return true; } private static void ReloadUnsavedDirtyScene() { for (var i = 0; i < SceneManager.sceneCount; i++) { var scene = SceneManager.GetSceneAt(i); var isSceneNotPersisted = string.IsNullOrEmpty(scene.path); var isSceneDirty = scene.isDirty; if (isSceneNotPersisted && isSceneDirty) { EditorSceneManager.ReloadScene(scene); } } } private static void RemoveUntitledScenes() { int sceneCount = SceneManager.sceneCount; var scenesToClose = new List(); for (var i = 0; i < sceneCount; i++) { var scene = SceneManager.GetSceneAt(i); var isSceneNotPersisted = string.IsNullOrEmpty(scene.path); if (isSceneNotPersisted) { scenesToClose.Add(scene); } } foreach (Scene scene in scenesToClose) { EditorSceneManager.CloseScene(scene, true); } } public class BackgroundListener : ScriptableObject, ITestRunnerListener { public void RunStarted(ITest testsToRun) { } public void RunFinished(ITestResult testResults) { IsRunning = false; } public void TestStarted(ITest test) { } public void TestFinished(ITestResult result) { } } public T AddEventHandler() where T : ScriptableObject, ITestRunnerListener { return m_EditModeRunner.AddEventHandler(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/EditModeLauncher.cs.meta ================================================ fileFormatVersion: 2 guid: ac68f5ae37c8957468562b8da42f9984 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/EditModeLauncherContextSettings.cs ================================================ using System; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { internal class EditModeLauncherContextSettings : IDisposable { private bool m_RunInBackground; public EditModeLauncherContextSettings() { SetupProjectParameters(); } public void Dispose() { CleanupProjectParameters(); } private void SetupProjectParameters() { m_RunInBackground = Application.runInBackground; Application.runInBackground = true; } private void CleanupProjectParameters() { Application.runInBackground = m_RunInBackground; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/EditModeLauncherContextSettings.cs.meta ================================================ fileFormatVersion: 2 guid: a582090813554df479fb9ca03e9857d3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/AndroidPlatformSetup.cs ================================================ using System; using UnityEngine; using System.Net; namespace UnityEditor.TestTools.TestRunner { internal class AndroidPlatformSetup : IPlatformSetup { private string m_oldApplicationIdentifier; private string m_oldDeviceSocketAddress; [SerializeField] private bool m_Stripping; public void Setup() { m_oldApplicationIdentifier = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android); PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, "com.UnityTestRunner.UnityTestRunner"); m_oldDeviceSocketAddress = EditorUserBuildSettings.androidDeviceSocketAddress; var androidDeviceConnection = Environment.GetEnvironmentVariable("ANDROID_DEVICE_CONNECTION"); EditorUserBuildSettings.waitForPlayerConnection = true; if (androidDeviceConnection != null) { EditorUserBuildSettings.androidDeviceSocketAddress = androidDeviceConnection; } m_Stripping = PlayerSettings.stripEngineCode; PlayerSettings.stripEngineCode = false; } public void PostBuildAction() { PlayerSettings.stripEngineCode = m_Stripping; } public void PostSuccessfulBuildAction() { var connectionResult = -1; var maxTryCount = 10; var tryCount = maxTryCount; while (tryCount-- > 0 && connectionResult == -1) { connectionResult = EditorConnectionInternal.ConnectPlayerProxy(IPAddress.Loopback.ToString(), 34999); if (EditorUtility.DisplayCancelableProgressBar("Editor Connection", "Connecting to the player", 1 - ((float)tryCount / maxTryCount))) { EditorUtility.ClearProgressBar(); throw new TestLaunchFailedException(); } } EditorUtility.ClearProgressBar(); if (connectionResult == -1) throw new TestLaunchFailedException( "Timed out trying to connect to the player. Player failed to launch or crashed soon after launching"); } public void CleanUp() { EditorUserBuildSettings.androidDeviceSocketAddress = m_oldDeviceSocketAddress; PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, m_oldApplicationIdentifier); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/AndroidPlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: 961642509dec50b44a293d26240140ec MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/ApplePlatformSetup.cs ================================================ using System; using System.Diagnostics; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class ApplePlatformSetup : IPlatformSetup { [SerializeField] private bool m_Stripping; public ApplePlatformSetup(BuildTarget buildTarget) { } public void Setup() { // Camera and fonts are stripped out and app crashes on iOS when test runner is trying to add a scene with... camera and text m_Stripping = PlayerSettings.stripEngineCode; PlayerSettings.stripEngineCode = false; } public void PostBuildAction() { // Restoring player setting as early as possible PlayerSettings.stripEngineCode = m_Stripping; } public void PostSuccessfulBuildAction() { } public void CleanUp() { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/ApplePlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: f6c189a159d3bde4c964cee562e508ea MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/IPlatformSetup.cs ================================================ namespace UnityEditor.TestTools.TestRunner { internal interface IPlatformSetup { void Setup(); void PostBuildAction(); void PostSuccessfulBuildAction(); void CleanUp(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/IPlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: 9d614808f9add8a4f8e4860db2c7af0d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/LuminPlatformSetup.cs ================================================ using System; using System.Threading; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { internal class LuminPlatformSetup : IPlatformSetup { private const string kDeviceAddress = "127.0.0.1"; private const int kDevicePort = 55000; public void Setup() { } public void PostBuildAction() { } public void PostSuccessfulBuildAction() { var connectionResult = -1; var maxTryCount = 100; var tryCount = maxTryCount; while (tryCount-- > 0 && connectionResult == -1) { Thread.Sleep(1000); connectionResult = EditorConnectionInternal.ConnectPlayerProxy(kDeviceAddress, kDevicePort); if (EditorUtility.DisplayCancelableProgressBar("Editor Connection", "Connecting to the player", 1 - ((float)tryCount / maxTryCount))) { EditorUtility.ClearProgressBar(); throw new TestLaunchFailedException(); } } EditorUtility.ClearProgressBar(); if (connectionResult == -1) throw new TestLaunchFailedException( "Timed out trying to connect to the player. Player failed to launch or crashed soon after launching"); } public void CleanUp() { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/LuminPlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: c38ae0585d6a55042a2d678330689685 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/PlatformSpecificSetup.cs ================================================ using System; using System.Collections.Generic; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class PlatformSpecificSetup { [SerializeField] private ApplePlatformSetup m_AppleiOSPlatformSetup = new ApplePlatformSetup(BuildTarget.iOS); [SerializeField] private ApplePlatformSetup m_AppleTvOSPlatformSetup = new ApplePlatformSetup(BuildTarget.tvOS); [SerializeField] private XboxOnePlatformSetup m_XboxOnePlatformSetup = new XboxOnePlatformSetup(); [SerializeField] private AndroidPlatformSetup m_AndroidPlatformSetup = new AndroidPlatformSetup(); [SerializeField] private SwitchPlatformSetup m_SwitchPlatformSetup = new SwitchPlatformSetup(); [SerializeField] private UwpPlatformSetup m_UwpPlatformSetup = new UwpPlatformSetup(); [SerializeField] private LuminPlatformSetup m_LuminPlatformSetup = new LuminPlatformSetup(); private IDictionary m_SetupTypes; [SerializeField] private BuildTarget m_Target; public PlatformSpecificSetup() { } public PlatformSpecificSetup(BuildTarget target) { m_Target = target; } public void Setup() { var dictionary = GetSetup(); if (!dictionary.ContainsKey(m_Target)) { return; } dictionary[m_Target].Setup(); } public void PostBuildAction() { var dictionary = GetSetup(); if (!dictionary.ContainsKey(m_Target)) { return; } dictionary[m_Target].PostBuildAction(); } public void PostSuccessfulBuildAction() { var dictionary = GetSetup(); if (!dictionary.ContainsKey(m_Target)) { return; } dictionary[m_Target].PostSuccessfulBuildAction(); } public void CleanUp() { var dictionary = GetSetup(); if (!dictionary.ContainsKey(m_Target)) { return; } dictionary[m_Target].CleanUp(); } private IDictionary GetSetup() { m_SetupTypes = new Dictionary() { {BuildTarget.iOS, m_AppleiOSPlatformSetup}, {BuildTarget.tvOS, m_AppleTvOSPlatformSetup}, {BuildTarget.XboxOne, m_XboxOnePlatformSetup}, {BuildTarget.Android, m_AndroidPlatformSetup}, {BuildTarget.WSAPlayer, m_UwpPlatformSetup}, {BuildTarget.Lumin, m_LuminPlatformSetup}, {BuildTarget.Switch, m_SwitchPlatformSetup} }; return m_SetupTypes; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/PlatformSpecificSetup.cs.meta ================================================ fileFormatVersion: 2 guid: 6cccd50ebf7384242bda4d7bcb282ebf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/SwitchPlatformSetup.cs ================================================ namespace UnityEditor.TestTools.TestRunner { internal class SwitchPlatformSetup : IPlatformSetup { public void Setup() { EditorUserBuildSettings.switchCreateRomFile = true; EditorUserBuildSettings.switchNVNGraphicsDebugger = false; EditorUserBuildSettings.switchNVNDrawValidation = true; // catches more graphics errors EditorUserBuildSettings.development = true; EditorUserBuildSettings.switchRedirectWritesToHostMount = true; // We can use these when more debugging is required: //EditorUserBuildSettings.switchNVNDrawValidation = false; // cannot be used with shader debug //EditorUserBuildSettings.switchNVNGraphicsDebugger = true; //EditorUserBuildSettings.switchNVNShaderDebugging = true; //EditorUserBuildSettings.switchCreateSolutionFile = true; // for shorter iteration time //EditorUserBuildSettings.allowDebugging = true; // managed debugger can be attached } public void PostBuildAction() { } public void PostSuccessfulBuildAction() { } public void CleanUp() { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/SwitchPlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: adf7bea9401c1834380d55601add6cfb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/UwpPlatformSetup.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner { internal class UwpPlatformSetup : IPlatformSetup { private const string k_SettingsBuildConfiguration = "BuildConfiguration"; private bool m_InternetClientServer; private bool m_PrivateNetworkClientServer; public void Setup() { m_InternetClientServer = PlayerSettings.WSA.GetCapability(PlayerSettings.WSACapability.InternetClientServer); m_PrivateNetworkClientServer = PlayerSettings.WSA.GetCapability(PlayerSettings.WSACapability.PrivateNetworkClientServer); PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.InternetClientServer, true); PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.PrivateNetworkClientServer, true); // This setting is initialized only when Window Store App is selected from the Build Settings window, and // is typically an empty strings when running tests via UTR on the command-line. bool wsaSettingNotInitialized = string.IsNullOrEmpty(EditorUserBuildSettings.wsaArchitecture); // If WSA build settings aren't fully initialized or running from a build machine, specify a default build configuration. // Otherwise we can use the existing configuration specified by the user in Build Settings. if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("UNITY_THISISABUILDMACHINE")) || wsaSettingNotInitialized) { EditorUserBuildSettings.wsaSubtarget = WSASubtarget.PC; EditorUserBuildSettings.wsaArchitecture = "x64"; EditorUserBuildSettings.SetPlatformSettings(BuildPipeline.GetBuildTargetName(BuildTarget.WSAPlayer), k_SettingsBuildConfiguration, WSABuildType.Debug.ToString()); EditorUserBuildSettings.wsaUWPBuildType = WSAUWPBuildType.ExecutableOnly; PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.WSA, Il2CppCompilerConfiguration.Debug); } } public void PostBuildAction() { } public void PostSuccessfulBuildAction() { } public void CleanUp() { PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.InternetClientServer, m_InternetClientServer); PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.PrivateNetworkClientServer, m_PrivateNetworkClientServer); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/UwpPlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: 667c6ad86a0b7a548aaa5c287f2c2861 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/XboxOnePlatformSetup.cs ================================================ namespace UnityEditor.TestTools.TestRunner { internal class XboxOnePlatformSetup : IPlatformSetup { private XboxOneDeployMethod oldXboxOneDeployMethod; private XboxOneDeployDrive oldXboxOneDeployDrive; private string oldXboxOneAdditionalDebugPorts; public void Setup() { oldXboxOneDeployMethod = EditorUserBuildSettings.xboxOneDeployMethod; oldXboxOneDeployDrive = EditorUserBuildSettings.xboxOneDeployDrive; oldXboxOneAdditionalDebugPorts = EditorUserBuildSettings.xboxOneAdditionalDebugPorts; EditorUserBuildSettings.xboxOneDeployMethod = XboxOneDeployMethod.Package; EditorUserBuildSettings.xboxOneDeployDrive = XboxOneDeployDrive.Default; // This causes the XboxOne post processing systems to open this port in your package manifest. // In addition it will open the ephemeral range for debug connections as well. // Failure to do this will cause connection problems. EditorUserBuildSettings.xboxOneAdditionalDebugPorts = "34999"; } public void PostBuildAction() { } public void PostSuccessfulBuildAction() { } public void CleanUp() { EditorUserBuildSettings.xboxOneDeployMethod = oldXboxOneDeployMethod; EditorUserBuildSettings.xboxOneDeployDrive = oldXboxOneDeployDrive; // This causes the XboxOne post processing systems to open this port in your package manifest. // In addition it will open the ephemeral range for debug connections as well. // Failure to do this will cause connection problems. EditorUserBuildSettings.xboxOneAdditionalDebugPorts = oldXboxOneAdditionalDebugPorts; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup/XboxOnePlatformSetup.cs.meta ================================================ fileFormatVersion: 2 guid: aed7ab02155e43341a2dbcb7bc17c160 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlatformSetup.meta ================================================ fileFormatVersion: 2 guid: ebc4d20cc106cea49b1df1153f0b3b5e folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlayerLauncher.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.TestRunner.TestLaunchers; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.TestRunner.Callbacks; namespace UnityEditor.TestTools.TestRunner { internal class TestLaunchFailedException : Exception { public TestLaunchFailedException() {} public TestLaunchFailedException(string message) : base(message) {} } [Serializable] internal class PlayerLauncher : RuntimeTestLauncherBase { private readonly PlaymodeTestsControllerSettings m_Settings; private readonly BuildTarget m_TargetPlatform; private string m_TempBuildLocation; private ITestRunSettings m_OverloadTestRunSettings; public PlayerLauncher(PlaymodeTestsControllerSettings settings, BuildTarget? targetPlatform, ITestRunSettings overloadTestRunSettings) { m_Settings = settings; m_TargetPlatform = targetPlatform ?? EditorUserBuildSettings.activeBuildTarget; m_OverloadTestRunSettings = overloadTestRunSettings; } protected override RuntimePlatform? TestTargetPlatform { get { return BuildTargetConverter.TryConvertToRuntimePlatform(m_TargetPlatform); } } public override void Run() { var editorConnectionTestCollector = RemoteTestRunController.instance; editorConnectionTestCollector.hideFlags = HideFlags.HideAndDontSave; editorConnectionTestCollector.Init(m_TargetPlatform); var remotePlayerLogController = RemotePlayerLogController.instance; remotePlayerLogController.hideFlags = HideFlags.HideAndDontSave; using (var settings = new PlayerLauncherContextSettings(m_OverloadTestRunSettings)) { var sceneName = CreateSceneName(); var scene = PrepareScene(sceneName); var filter = m_Settings.filter.BuildNUnitFilter(); var runner = LoadTests(filter); var exceptionThrown = ExecutePreBuildSetupMethods(runner.LoadedTest, filter); if (exceptionThrown) { ReopenOriginalScene(m_Settings.originalScene); AssetDatabase.DeleteAsset(sceneName); CallbacksDelegator.instance.RunFailed("Run Failed: One or more errors in a prebuild setup. See the editor log for details."); return; } var playerBuildOptions = GetBuildOptions(scene); var success = BuildAndRunPlayer(playerBuildOptions); editorConnectionTestCollector.PostBuildAction(); ExecutePostBuildCleanupMethods(runner.LoadedTest, filter); ReopenOriginalScene(m_Settings.originalScene); AssetDatabase.DeleteAsset(sceneName); if (!success) { ScriptableObject.DestroyImmediate(editorConnectionTestCollector); Debug.LogError("Player build failed"); throw new TestLaunchFailedException("Player build failed"); } editorConnectionTestCollector.PostSuccessfulBuildAction(); } } public Scene PrepareScene(string sceneName) { var scene = CreateBootstrapScene(sceneName, runner => { runner.AddEventHandlerMonoBehaviour(); runner.settings = m_Settings; runner.AddEventHandlerMonoBehaviour(); }); return scene; } private static bool BuildAndRunPlayer(PlayerLauncherBuildOptions buildOptions) { Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, "Building player with following options:\n{0}", buildOptions); // Android has to be in listen mode to establish player connection if (buildOptions.BuildPlayerOptions.target == BuildTarget.Android) { buildOptions.BuildPlayerOptions.options &= ~BuildOptions.ConnectToHost; } // For now, so does Lumin if (buildOptions.BuildPlayerOptions.target == BuildTarget.Lumin) { buildOptions.BuildPlayerOptions.options &= ~BuildOptions.ConnectToHost; } var result = BuildPipeline.BuildPlayer(buildOptions.BuildPlayerOptions); if (result.summary.result != Build.Reporting.BuildResult.Succeeded) Debug.LogError(result.SummarizeErrors()); return result.summary.result == Build.Reporting.BuildResult.Succeeded; } private PlayerLauncherBuildOptions GetBuildOptions(Scene scene) { var buildOptions = new BuildPlayerOptions(); var reduceBuildLocationPathLength = false; //Some platforms hit MAX_PATH limits during the build process, in these cases minimize the path length if ((m_TargetPlatform == BuildTarget.WSAPlayer) || (m_TargetPlatform == BuildTarget.XboxOne)) { reduceBuildLocationPathLength = true; } var scenes = new List() { scene.path }; scenes.AddRange(EditorBuildSettings.scenes.Select(x => x.path)); buildOptions.scenes = scenes.ToArray(); buildOptions.options |= BuildOptions.AutoRunPlayer | BuildOptions.Development | BuildOptions.ConnectToHost | BuildOptions.IncludeTestAssemblies | BuildOptions.StrictMode; buildOptions.target = m_TargetPlatform; if (EditorUserBuildSettings.waitForPlayerConnection) buildOptions.options |= BuildOptions.WaitForPlayerConnection; var buildTargetGroup = EditorUserBuildSettings.activeBuildTargetGroup; var uniqueTempPathInProject = FileUtil.GetUniqueTempPathInProject(); if (reduceBuildLocationPathLength) { uniqueTempPathInProject = Path.GetTempFileName(); File.Delete(uniqueTempPathInProject); Directory.CreateDirectory(uniqueTempPathInProject); } //Check if Lz4 is supported for the current buildtargetgroup and enable it if need be if (PostprocessBuildPlayer.SupportsLz4Compression(buildTargetGroup, m_TargetPlatform)) { if (EditorUserBuildSettings.GetCompressionType(buildTargetGroup) == Compression.Lz4) buildOptions.options |= BuildOptions.CompressWithLz4; else if (EditorUserBuildSettings.GetCompressionType(buildTargetGroup) == Compression.Lz4HC) buildOptions.options |= BuildOptions.CompressWithLz4HC; } m_TempBuildLocation = Path.GetFullPath(uniqueTempPathInProject); string extensionForBuildTarget = PostprocessBuildPlayer.GetExtensionForBuildTarget(buildTargetGroup, buildOptions.target, buildOptions.options); var playerExecutableName = "PlayerWithTests"; var playerDirectoryName = reduceBuildLocationPathLength ? "PwT" : "PlayerWithTests"; var locationPath = Path.Combine(m_TempBuildLocation, playerDirectoryName); if (!string.IsNullOrEmpty(extensionForBuildTarget)) { playerExecutableName += string.Format(".{0}", extensionForBuildTarget); locationPath = Path.Combine(locationPath, playerExecutableName); } buildOptions.locationPathName = locationPath; return new PlayerLauncherBuildOptions { BuildPlayerOptions = buildOptions, PlayerDirectory = Path.Combine(m_TempBuildLocation, playerDirectoryName), }; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlayerLauncher.cs.meta ================================================ fileFormatVersion: 2 guid: d973fc1524e4d724081553934c55958c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlayerLauncherBuildOptions.cs ================================================ using System.Text; namespace UnityEditor.TestTools.TestRunner { internal class PlayerLauncherBuildOptions { public BuildPlayerOptions BuildPlayerOptions; public string PlayerDirectory; public override string ToString() { var str = new StringBuilder(); str.AppendLine("locationPathName = " + BuildPlayerOptions.locationPathName); str.AppendLine("target = " + BuildPlayerOptions.target); str.AppendLine("scenes = " + string.Join(", ", BuildPlayerOptions.scenes)); str.AppendLine("assetBundleManifestPath = " + BuildPlayerOptions.assetBundleManifestPath); str.AppendLine("options.Development = " + ((BuildPlayerOptions.options & BuildOptions.Development) != 0)); str.AppendLine("options.AutoRunPlayer = " + ((BuildPlayerOptions.options & BuildOptions.AutoRunPlayer) != 0)); str.AppendLine("options.ForceEnableAssertions = " + ((BuildPlayerOptions.options & BuildOptions.ForceEnableAssertions) != 0)); return str.ToString(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlayerLauncherBuildOptions.cs.meta ================================================ fileFormatVersion: 2 guid: 2a0bd678385f98e4d8eabdfc07d62b4f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlayerLauncherContextSettings.cs ================================================ using System; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { internal class PlayerLauncherContextSettings : IDisposable { private ITestRunSettings m_OverloadSettings; private EditorBuildSettingsScene[] m_EditorBuildSettings; #pragma warning disable 618 private ResolutionDialogSetting m_DisplayResolutionDialog; #pragma warning restore 618 private bool m_RunInBackground; private FullScreenMode m_FullScreenMode; private bool m_ResizableWindow; private bool m_ShowUnitySplashScreen; private string m_OldproductName; private string m_OldAotOptions; private Lightmapping.GIWorkflowMode m_OldLightmapping; private bool m_explicitNullChecks; private bool m_Disposed; public PlayerLauncherContextSettings(ITestRunSettings overloadSettings) { m_OverloadSettings = overloadSettings; SetupProjectParameters(); if (overloadSettings != null) { overloadSettings.Apply(); } } public void Dispose() { if (!m_Disposed) { CleanupProjectParameters(); if (m_OverloadSettings != null) { m_OverloadSettings.Dispose(); } m_Disposed = true; } } private void SetupProjectParameters() { EditorApplication.LockReloadAssemblies(); m_EditorBuildSettings = EditorBuildSettings.scenes; #pragma warning disable 618 m_DisplayResolutionDialog = PlayerSettings.displayResolutionDialog; PlayerSettings.displayResolutionDialog = ResolutionDialogSetting.Disabled; #pragma warning restore 618 m_RunInBackground = PlayerSettings.runInBackground; PlayerSettings.runInBackground = true; m_FullScreenMode = PlayerSettings.fullScreenMode; PlayerSettings.fullScreenMode = FullScreenMode.Windowed; m_OldAotOptions = PlayerSettings.aotOptions; PlayerSettings.aotOptions = "nimt-trampolines=1024"; m_ResizableWindow = PlayerSettings.resizableWindow; PlayerSettings.resizableWindow = true; m_ShowUnitySplashScreen = PlayerSettings.SplashScreen.show; PlayerSettings.SplashScreen.show = false; m_OldproductName = PlayerSettings.productName; PlayerSettings.productName = "UnityTestFramework"; m_OldLightmapping = Lightmapping.giWorkflowMode; Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand; m_explicitNullChecks = EditorUserBuildSettings.explicitNullChecks; EditorUserBuildSettings.explicitNullChecks = true; } private void CleanupProjectParameters() { EditorBuildSettings.scenes = m_EditorBuildSettings; PlayerSettings.fullScreenMode = m_FullScreenMode; PlayerSettings.runInBackground = m_RunInBackground; #pragma warning disable 618 PlayerSettings.displayResolutionDialog = m_DisplayResolutionDialog; #pragma warning restore 618 PlayerSettings.resizableWindow = m_ResizableWindow; PlayerSettings.SplashScreen.show = m_ShowUnitySplashScreen; PlayerSettings.productName = m_OldproductName; PlayerSettings.aotOptions = m_OldAotOptions; Lightmapping.giWorkflowMode = m_OldLightmapping; EditorUserBuildSettings.explicitNullChecks = m_explicitNullChecks; EditorApplication.UnlockReloadAssemblies(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlayerLauncherContextSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 6965880f76f40194593cb53a88f74005 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlaymodeLauncher.cs ================================================ using System; using System.Collections.Generic; using NUnit.Framework.Interfaces; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.TestRunner.Callbacks; namespace UnityEditor.TestTools.TestRunner { internal class PlaymodeLauncher : RuntimeTestLauncherBase { public static bool IsRunning; private Scene m_Scene; private bool m_IsTestSetupPerformed; private readonly PlaymodeTestsControllerSettings m_Settings; private ITestFilter testFilter; [SerializeField] private List m_EventHandlers = new List(); public PlaymodeLauncher(PlaymodeTestsControllerSettings settings) { m_Settings = settings; } public override void Run() { IsRunning = true; ConsoleWindow.SetConsoleErrorPause(false); Application.runInBackground = true; var sceneName = CreateSceneName(); m_Scene = CreateBootstrapScene(sceneName, runner => { runner.AddEventHandlerMonoBehaviour(); runner.AddEventHandlerScriptableObject(); runner.AddEventHandlerScriptableObject(); foreach (var eventHandler in m_EventHandlers) { var obj = ScriptableObject.CreateInstance(eventHandler); runner.AddEventHandlerScriptableObject(obj as ITestRunnerListener); } runner.settings = m_Settings; }); if (m_Settings.sceneBased) { var newListOfScenes = new List {new EditorBuildSettingsScene(sceneName, true)}; newListOfScenes.AddRange(EditorBuildSettings.scenes); EditorBuildSettings.scenes = newListOfScenes.ToArray(); } EditorApplication.update += UpdateCallback; } public void UpdateCallback() { if (m_IsTestSetupPerformed) { if (m_Scene.IsValid()) SceneManager.SetActiveScene(m_Scene); EditorApplication.update -= UpdateCallback; EditorApplication.isPlaying = true; } else { testFilter = m_Settings.filter.BuildNUnitFilter(); var runner = LoadTests(testFilter); var exceptionThrown = ExecutePreBuildSetupMethods(runner.LoadedTest, testFilter); if (exceptionThrown) { EditorApplication.update -= UpdateCallback; IsRunning = false; var controller = PlaymodeTestsController.GetController(); ReopenOriginalScene(controller); AssetDatabase.DeleteAsset(controller.settings.bootstrapScene); CallbacksDelegator.instance.RunFailed("Run Failed: One or more errors in a prebuild setup. See the editor log for details."); return; } m_IsTestSetupPerformed = true; } } [InitializeOnLoad] public class BackgroundWatcher { static BackgroundWatcher() { EditorApplication.playModeStateChanged += OnPlayModeStateChanged; } private static void OnPlayModeStateChanged(PlayModeStateChange state) { if (!PlaymodeTestsController.IsControllerOnScene()) return; var runner = PlaymodeTestsController.GetController(); if (runner == null) return; if (state == PlayModeStateChange.ExitingPlayMode) { AssetDatabase.DeleteAsset(runner.settings.bootstrapScene); ExecutePostBuildCleanupMethods(runner.m_Runner.LoadedTest, runner.settings.filter.BuildNUnitFilter(), Application.platform); IsRunning = false; } else if (state == PlayModeStateChange.EnteredEditMode) { //reopen the original scene once we exit playmode ReopenOriginalScene(runner); } } } protected static void ReopenOriginalScene(PlaymodeTestsController runner) { ReopenOriginalScene(runner.settings.originalScene); } public void AddEventHandler() where T : ScriptableObject, ITestRunnerListener { m_EventHandlers.Add(typeof(T)); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PlaymodeLauncher.cs.meta ================================================ fileFormatVersion: 2 guid: d3217d58bbd1d2b4aaee933e2e8b9195 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PostbuildCleanupAttributeFinder.cs ================================================ using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class PostbuildCleanupAttributeFinder : AttributeFinderBase { public PostbuildCleanupAttributeFinder() : base(attribute => attribute.TargetClass) {} } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PostbuildCleanupAttributeFinder.cs.meta ================================================ fileFormatVersion: 2 guid: 2c2dfcbbb77359547bcaa7cdabd47ebb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PrebuildSetupAttributeFinder.cs ================================================ using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class PrebuildSetupAttributeFinder : AttributeFinderBase { public PrebuildSetupAttributeFinder() : base((attribute) => attribute.TargetClass) {} } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/PrebuildSetupAttributeFinder.cs.meta ================================================ fileFormatVersion: 2 guid: 3c4ccfb0896bcf44da13e152b267aa49 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RemotePlayerLogController.cs ================================================ using System; using System.Collections.Generic; using UnityEditor.DeploymentTargets; using UnityEditor.TestTools.TestRunner.CommandLineTest; using UnityEngine; namespace UnityEditor.TestRunner.TestLaunchers { [Serializable] internal class RemotePlayerLogController : ScriptableSingleton { private List m_LogWriters; private Dictionary m_Loggers; private string m_DeviceLogsDirectory; public void SetBuildTarget(BuildTarget buildTarget) { m_Loggers = GetDeploymentTargetLoggers(buildTarget); } public void SetLogsDirectory(string dir) { m_DeviceLogsDirectory = dir; } public void StartLogWriters() { if (m_DeviceLogsDirectory == null || m_Loggers == null) return; m_LogWriters = new List(); foreach (var logger in m_Loggers) { m_LogWriters.Add(new LogWriter(m_DeviceLogsDirectory, logger.Key, logger.Value)); logger.Value.Start(); } } public void StopLogWriters() { if (m_LogWriters == null) return; foreach (var logWriter in m_LogWriters) { logWriter.Stop(); } } private Dictionary GetDeploymentTargetLoggers(BuildTarget buildTarget) { DeploymentTargetManager deploymentTargetManager; try { deploymentTargetManager = DeploymentTargetManager.CreateInstance(EditorUserBuildSettings.activeBuildTargetGroup, buildTarget); } catch (NotSupportedException ex) { Debug.Log(ex.Message); Debug.Log("Deployment target logger not initialised"); return null; } var targets = deploymentTargetManager.GetKnownTargets(); var loggers = new Dictionary(); foreach (var target in targets) { if (target.status != DeploymentTargetStatus.Ready) continue; var logger = deploymentTargetManager.GetTargetLogger(target.id); logger.Clear(); loggers.Add(target.id, logger); } return loggers; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RemotePlayerLogController.cs.meta ================================================ fileFormatVersion: 2 guid: edd2a1fe1acbbde43aad39862bb3f4a8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RemotePlayerTestController.cs ================================================ using System; using UnityEditor.Networking.PlayerConnection; using UnityEditor.TestTools.TestRunner; using UnityEditor.TestTools.TestRunner.Api; using UnityEditor.TestTools.TestRunner.UnityTestProtocol; using UnityEngine; using UnityEngine.Networking.PlayerConnection; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEditor.TestRunner.TestLaunchers { [Serializable] internal class RemoteTestRunController : ScriptableSingleton { [SerializeField] private RemoteTestResultReciever m_RemoteTestResultReciever; [SerializeField] private PlatformSpecificSetup m_PlatformSpecificSetup; [SerializeField] private bool m_RegisteredConnectionCallbacks; public void Init(BuildTarget buildTarget) { m_PlatformSpecificSetup = new PlatformSpecificSetup(buildTarget); m_PlatformSpecificSetup.Setup(); m_RemoteTestResultReciever = new RemoteTestResultReciever(); EditorConnection.instance.Initialize(); if (!m_RegisteredConnectionCallbacks) { EditorConnection.instance.Initialize(); DelegateEditorConnectionEvents(); } } private void DelegateEditorConnectionEvents() { m_RegisteredConnectionCallbacks = true; //This is needed because RemoteTestResultReciever is not a ScriptableObject EditorConnection.instance.Register(PlayerConnectionMessageIds.runStartedMessageId, RunStarted); EditorConnection.instance.Register(PlayerConnectionMessageIds.runFinishedMessageId, RunFinished); EditorConnection.instance.Register(PlayerConnectionMessageIds.testStartedMessageId, TestStarted); EditorConnection.instance.Register(PlayerConnectionMessageIds.testFinishedMessageId, TestFinished); } private void RunStarted(MessageEventArgs messageEventArgs) { m_RemoteTestResultReciever.RunStarted(messageEventArgs); CallbacksDelegator.instance.RunStartedRemotely(messageEventArgs.data); } private void RunFinished(MessageEventArgs messageEventArgs) { m_RemoteTestResultReciever.RunFinished(messageEventArgs); m_PlatformSpecificSetup.CleanUp(); CallbacksDelegator.instance.RunFinishedRemotely(messageEventArgs.data); } private void TestStarted(MessageEventArgs messageEventArgs) { CallbacksDelegator.instance.TestStartedRemotely(messageEventArgs.data); } private void TestFinished(MessageEventArgs messageEventArgs) { CallbacksDelegator.instance.TestFinishedRemotely(messageEventArgs.data); } public void PostBuildAction() { m_PlatformSpecificSetup.PostBuildAction(); } public void PostSuccessfulBuildAction() { m_PlatformSpecificSetup.PostSuccessfulBuildAction(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RemotePlayerTestController.cs.meta ================================================ fileFormatVersion: 2 guid: 7d36034e63ad8254b9b2f55280fcc040 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RemoteTestResultReciever.cs ================================================ using System; using UnityEditor.Networking.PlayerConnection; using UnityEngine; using UnityEngine.Networking.PlayerConnection; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class RemoteTestResultReciever { public void RunStarted(MessageEventArgs messageEventArgs) { } public void RunFinished(MessageEventArgs messageEventArgs) { EditorConnection.instance.Send(PlayerConnectionMessageIds.runFinishedMessageId, null, messageEventArgs.playerId); EditorConnection.instance.DisconnectAll(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RemoteTestResultReciever.cs.meta ================================================ fileFormatVersion: 2 guid: fdb35ef8fc437e14fa4b6c74a0609e86 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RuntimeTestLauncherBase.cs ================================================ using System; using System.Linq; using NUnit.Framework.Interfaces; using UnityEditor.Events; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools; using UnityEngine.TestTools.NUnitExtensions; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.Utils; namespace UnityEditor.TestTools.TestRunner { internal abstract class RuntimeTestLauncherBase : TestLauncherBase { protected Scene CreateBootstrapScene(string sceneName, Action runnerSetup) { var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); var go = new GameObject(PlaymodeTestsController.kPlaymodeTestControllerName); var editorLoadedTestAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy()); var runner = go.AddComponent(); runnerSetup(runner); runner.settings.bootstrapScene = sceneName; runner.AssembliesWithTests = editorLoadedTestAssemblyProvider.GetAssembliesGroupedByType(TestPlatform.PlayMode).Select(x => x.Assembly.GetName().Name).ToList(); EditorSceneManager.MarkSceneDirty(scene); AssetDatabase.SaveAssets(); EditorSceneManager.SaveScene(scene, sceneName, false); return scene; } public string CreateSceneName() { return "Assets/InitTestScene" + DateTime.Now.Ticks + ".unity"; } protected UnityTestAssemblyRunner LoadTests(ITestFilter filter) { var editorLoadedTestAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy()); var assembliesWithTests = editorLoadedTestAssemblyProvider.GetAssembliesGroupedByType(TestPlatform.PlayMode).Select(x => x.Assembly.GetName().Name).ToList(); var nUnitTestAssemblyRunner = new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(), null); var assemblyProvider = new PlayerTestAssemblyProvider(new AssemblyLoadProxy(), assembliesWithTests); nUnitTestAssemblyRunner.Load(assemblyProvider.GetUserAssemblies().Select(a => a.Assembly).ToArray(), UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(TestPlatform.PlayMode)); return nUnitTestAssemblyRunner; } protected static void ReopenOriginalScene(string originalSceneName) { EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); if (!string.IsNullOrEmpty(originalSceneName)) { EditorSceneManager.OpenScene(originalSceneName); } } } internal static class PlaymodeTestsControllerExtensions { internal static T AddEventHandlerMonoBehaviour(this PlaymodeTestsController controller) where T : MonoBehaviour, ITestRunnerListener { var eventHandler = controller.gameObject.AddComponent(); SetListeners(controller, eventHandler); return eventHandler; } internal static T AddEventHandlerScriptableObject(this PlaymodeTestsController controller) where T : ScriptableObject, ITestRunnerListener { var eventListener = ScriptableObject.CreateInstance(); AddEventHandlerScriptableObject(controller, eventListener); return eventListener; } internal static void AddEventHandlerScriptableObject(this PlaymodeTestsController controller, ITestRunnerListener obj) { SetListeners(controller, obj); } private static void SetListeners(PlaymodeTestsController controller, ITestRunnerListener eventHandler) { UnityEventTools.AddPersistentListener(controller.testStartedEvent, eventHandler.TestStarted); UnityEventTools.AddPersistentListener(controller.testFinishedEvent, eventHandler.TestFinished); UnityEventTools.AddPersistentListener(controller.runStartedEvent, eventHandler.RunStarted); UnityEventTools.AddPersistentListener(controller.runFinishedEvent, eventHandler.RunFinished); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/RuntimeTestLauncherBase.cs.meta ================================================ fileFormatVersion: 2 guid: 0efb23ecb373b6d4bbe5217485785138 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/TestLauncherBase.cs ================================================ using System; using NUnit.Framework.Interfaces; using UnityEngine; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal abstract class TestLauncherBase { public abstract void Run(); protected virtual RuntimePlatform? TestTargetPlatform { get { return Application.platform; } } protected bool ExecutePreBuildSetupMethods(ITest tests, ITestFilter testRunnerFilter) { var attributeFinder = new PrebuildSetupAttributeFinder(); var logString = "Executing setup for: {0}"; return ExecuteMethods(tests, testRunnerFilter, attributeFinder, logString, targetClass => targetClass.Setup(), TestTargetPlatform); } public void ExecutePostBuildCleanupMethods(ITest tests, ITestFilter testRunnerFilter) { ExecutePostBuildCleanupMethods(tests, testRunnerFilter, TestTargetPlatform); } public static void ExecutePostBuildCleanupMethods(ITest tests, ITestFilter testRunnerFilter, RuntimePlatform? testTargetPlatform) { var attributeFinder = new PostbuildCleanupAttributeFinder(); var logString = "Executing cleanup for: {0}"; ExecuteMethods(tests, testRunnerFilter, attributeFinder, logString, targetClass => targetClass.Cleanup(), testTargetPlatform); } private static bool ExecuteMethods(ITest tests, ITestFilter testRunnerFilter, AttributeFinderBase attributeFinder, string logString, Action action, RuntimePlatform? testTargetPlatform) { var exceptionsThrown = false; if (testTargetPlatform == null) { Debug.LogError("Could not determine test target platform from build target " + EditorUserBuildSettings.activeBuildTarget); return true; } foreach (var targetClassType in attributeFinder.Search(tests, testRunnerFilter, testTargetPlatform.Value)) { try { var targetClass = (T)Activator.CreateInstance(targetClassType); Debug.LogFormat(logString, targetClassType.FullName); action(targetClass); } catch (InvalidCastException) {} catch (Exception e) { Debug.LogException(e); exceptionsThrown = true; } } return exceptionsThrown; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers/TestLauncherBase.cs.meta ================================================ fileFormatVersion: 2 guid: 1cddf785b0d07434d8e0607c97b09135 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestLaunchers.meta ================================================ fileFormatVersion: 2 guid: d64d92e4f04a13e4b99ea8d48e9e8ae9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestResultSerializer.cs ================================================ using System; using System.Reflection; using System.Text; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class TestResultSerializer { private static readonly BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy; [SerializeField] public string id; [SerializeField] public string fullName; [SerializeField] private double duration; [SerializeField] private string label; [SerializeField] private string message; [SerializeField] private string output; [SerializeField] private string site; [SerializeField] private string stacktrace; [SerializeField] private double startTimeAO; [SerializeField] private string status; public static TestResultSerializer MakeFromTestResult(ITestResult result) { var wrapper = new TestResultSerializer(); wrapper.id = result.Test.Id; wrapper.fullName = result.FullName; wrapper.status = result.ResultState.Status.ToString(); wrapper.label = result.ResultState.Label; wrapper.site = result.ResultState.Site.ToString(); wrapper.output = result.Output; wrapper.duration = result.Duration; wrapper.stacktrace = result.StackTrace; wrapper.message = result.Message; wrapper.startTimeAO = result.StartTime.ToOADate(); return wrapper; } public void RestoreTestResult(TestResult result) { var resultState = new ResultState((TestStatus)Enum.Parse(typeof(TestStatus), status), label, (FailureSite)Enum.Parse(typeof(FailureSite), site)); result.GetType().BaseType.GetField("_resultState", flags).SetValue(result, resultState); result.GetType().BaseType.GetField("_output", flags).SetValue(result, new StringBuilder(output)); result.GetType().BaseType.GetField("_duration", flags).SetValue(result, duration); result.GetType().BaseType.GetField("_message", flags).SetValue(result, message); result.GetType().BaseType.GetField("_stackTrace", flags).SetValue(result, stacktrace); result.GetType() .BaseType.GetProperty("StartTime", flags) .SetValue(result, DateTime.FromOADate(startTimeAO), null); } public bool IsPassed() { return status == TestStatus.Passed.ToString(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestResultSerializer.cs.meta ================================================ fileFormatVersion: 2 guid: 559482fe33c79e44882d3a6cedc55fb5 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/EditModeRunnerCallback.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.TestTools.TestRunner; namespace UnityEditor.TestTools.TestRunner { internal class EditModeRunnerCallback : ScriptableObject, ITestRunnerListener { private EditModeLauncherContextSettings m_Settings; public SceneSetup[] previousSceneSetup; public int undoGroup; public EditModeRunner runner; private bool m_Canceled; private ITest m_CurrentTest; private int m_TotalTests; [SerializeField] private List m_PendingTests; [SerializeField] private string m_LastCountedTestName; [SerializeField] private bool m_RunRestarted; public void OnDestroy() { CleanUp(); } public void RunStarted(ITest testsToRun) { Setup(); if (m_PendingTests == null) { m_PendingTests = GetTestsExpectedToRun(testsToRun, runner.GetFilter()); m_TotalTests = m_PendingTests.Count; } } public void OnEnable() { if (m_RunRestarted) { Setup(); } } private void Setup() { m_Settings = new EditModeLauncherContextSettings(); Application.logMessageReceivedThreaded += LogReceived; EditorApplication.playModeStateChanged += WaitForExitPlaymode; EditorApplication.update += DisplayProgressBar; AssemblyReloadEvents.beforeAssemblyReload += BeforeAssemblyReload; } private void BeforeAssemblyReload() { if (m_CurrentTest != null) { m_LastCountedTestName = m_CurrentTest.FullName; m_RunRestarted = true; } } private void DisplayProgressBar() { if (m_CurrentTest == null) return; if (!m_Canceled && EditorUtility.DisplayCancelableProgressBar("Test Runner", "Running test " + m_CurrentTest.Name, Math.Min(1.0f, (float)(m_TotalTests - m_PendingTests.Count) / m_TotalTests))) { EditorApplication.update -= DisplayProgressBar; m_Canceled = true; EditorUtility.ClearProgressBar(); runner.OnRunCancel(); } } private static void LogReceived(string message, string stacktrace, LogType type) { if (TestContext.Out != null) TestContext.Out.WriteLine(message); } private static void WaitForExitPlaymode(PlayModeStateChange state) { if (state == PlayModeStateChange.EnteredEditMode) { EditorApplication.playModeStateChanged -= WaitForExitPlaymode; //because logMessage is reset on Enter EditMode //we remove and add the callback //because Unity Application.logMessageReceivedThreaded -= LogReceived; Application.logMessageReceivedThreaded += LogReceived; } } public void RunFinished(ITestResult result) { if (previousSceneSetup != null && previousSceneSetup.Length > 0) { try { EditorSceneManager.RestoreSceneManagerSetup(previousSceneSetup); } catch (ArgumentException e) { Debug.LogWarning(e.Message); } } else { EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); } CleanUp(); PerformUndo(undoGroup); } private void CleanUp() { m_CurrentTest = null; EditorUtility.ClearProgressBar(); if (m_Settings != null) { m_Settings.Dispose(); } Application.logMessageReceivedThreaded -= LogReceived; EditorApplication.update -= DisplayProgressBar; } public void TestStarted(ITest test) { if (test.IsSuite || !(test is TestMethod)) { return; } m_CurrentTest = test; if (m_RunRestarted) { if (test.FullName == m_LastCountedTestName) m_RunRestarted = false; } } public void TestFinished(ITestResult result) { if (result.Test is TestMethod) { m_PendingTests.Remove(result.Test.FullName); } } private static void PerformUndo(int undoGroup) { EditorUtility.DisplayProgressBar("Undo", "Reverting changes to the scene", 0); var undoStartTime = DateTime.Now; Undo.RevertAllDownToGroup(undoGroup); if ((DateTime.Now - undoStartTime).TotalSeconds > 1) Debug.LogWarning("Undo after editor test run took " + (DateTime.Now - undoStartTime).Seconds + " seconds."); EditorUtility.ClearProgressBar(); } private static List GetTestsExpectedToRun(ITest test, ITestFilter filter) { var expectedTests = new List(); if (filter.Pass(test)) { if (test.IsSuite) { expectedTests.AddRange(test.Tests.SelectMany(subTest => GetTestsExpectedToRun(subTest, filter))); } else { expectedTests.Add(test.FullName); } } return expectedTests; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/EditModeRunnerCallback.cs.meta ================================================ fileFormatVersion: 2 guid: cc456ba93311a3a43ad896449fee9868 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/RerunCallback.cs ================================================ using UnityEditor.TestTools.TestRunner.Api; using UnityEditor.TestTools.TestRunner.CommandLineTest; using UnityEngine.TestTools.TestRunner.GUI; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { internal class RerunCallback : ScriptableObject, ICallbacks { public static bool useMockRunFilter = false; public static TestRunnerFilter mockRunFilter = null; public void RunFinished(ITestResultAdaptor result) { if (RerunCallbackData.instance.runFilter == null) RerunCallbackData.instance.runFilter = new TestRunnerFilter(); var runFilter = RerunCallbackData.instance.runFilter; if (useMockRunFilter) { runFilter = mockRunFilter; } runFilter.testRepetitions--; if (runFilter.testRepetitions <= 0 || result.TestStatus != TestStatus.Passed) { ExitCallbacks.preventExit = false; return; } ExitCallbacks.preventExit = true; if (EditorApplication.isPlaying) { EditorApplication.playModeStateChanged += WaitForExitPlaymode; return; } if (!useMockRunFilter) { ExecuteTestRunnerAPI(); } } private static void WaitForExitPlaymode(PlayModeStateChange state) { if (state == PlayModeStateChange.EnteredEditMode) { ExecuteTestRunnerAPI(); } } private static void ExecuteTestRunnerAPI() { var runFilter = RerunCallbackData.instance.runFilter; var testMode = RerunCallbackData.instance.testMode; var testRunnerApi = ScriptableObject.CreateInstance(); testRunnerApi.Execute(new Api.ExecutionSettings() { filter = new Filter() { categoryNames = runFilter.categoryNames, groupNames = runFilter.groupNames, testMode = testMode, testNames = runFilter.testNames } }); } public void TestStarted(ITestAdaptor test) { } public void TestFinished(ITestResultAdaptor result) { } public void RunStarted(ITestAdaptor testsToRun) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/RerunCallback.cs.meta ================================================ fileFormatVersion: 2 guid: b7ff2b2e91321ff4381d4ab45870a32e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/RerunCallbackData.cs ================================================ using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEditor.TestTools.TestRunner { internal class RerunCallbackData : ScriptableSingleton { [SerializeField] internal TestRunnerFilter runFilter; [SerializeField] internal TestMode testMode; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/RerunCallbackData.cs.meta ================================================ fileFormatVersion: 2 guid: 087cba9fa6ac867479a0b0fdc0a5864b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/RerunCallbackInitializer.cs ================================================ using UnityEngine; using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner { [InitializeOnLoad] static class RerunCallbackInitializer { static RerunCallbackInitializer() { var testRunnerApi = ScriptableObject.CreateInstance(); var rerunCallback = ScriptableObject.CreateInstance(); testRunnerApi.RegisterCallbacks(rerunCallback); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/RerunCallbackInitializer.cs.meta ================================================ fileFormatVersion: 2 guid: f73fc901e4b0f2d4daf11f46506054ba MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/TestRunnerCallback.cs ================================================ using NUnit.Framework.Interfaces; using UnityEngine; using UnityEngine.TestTools.TestRunner; namespace UnityEditor.TestTools.TestRunner { internal class TestRunnerCallback : ScriptableObject, ITestRunnerListener { public void RunStarted(ITest testsToRun) { EditorApplication.playModeStateChanged += OnPlayModeStateChanged; } private void OnPlayModeStateChanged(PlayModeStateChange state) { if (state == PlayModeStateChange.ExitingPlayMode) { EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; //We need to make sure we don't block NUnit thread in case we exit PlayMode earlier PlaymodeTestsController.TryCleanup(); } } public void RunFinished(ITestResult testResults) { EditorApplication.isPlaying = false; } public void TestStarted(ITest testName) { } public void TestFinished(ITestResult test) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/TestRunnerCallback.cs.meta ================================================ fileFormatVersion: 2 guid: d44e6804bc58be84ea71a619b468f150 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/WindowResultUpdater.cs ================================================ using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.GUI { internal class WindowResultUpdater : ICallbacks { public void RunStarted(ITestAdaptor testsToRun) { } public void RunFinished(ITestResultAdaptor testResults) { if (TestRunnerWindow.s_Instance != null) { TestRunnerWindow.s_Instance.RebuildUIFilter(); } } public void TestStarted(ITestAdaptor testName) { } public void TestFinished(ITestResultAdaptor test) { if (TestRunnerWindow.s_Instance == null) return; var result = new TestRunnerResult(test); TestRunnerWindow.s_Instance.m_SelectedTestTypes.UpdateResult(result); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks/WindowResultUpdater.cs.meta ================================================ fileFormatVersion: 2 guid: 6d468ee3657be7a43a2ef2178ec14239 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Callbacks.meta ================================================ fileFormatVersion: 2 guid: 5d7f0d6acfced954682a89e7002c04d9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditModePCHelper.cs ================================================ using System.Collections; using System.Reflection; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class EditModePcHelper : TestCommandPcHelper { public override void SetEnumeratorPC(IEnumerator enumerator, int pc) { GetPCFieldInfo(enumerator).SetValue(enumerator, pc); } public override int GetEnumeratorPC(IEnumerator enumerator) { if (enumerator == null) { return 0; } return (int)GetPCFieldInfo(enumerator).GetValue(enumerator); } private FieldInfo GetPCFieldInfo(IEnumerator enumerator) { var field = enumerator.GetType().GetField("$PC", BindingFlags.NonPublic | BindingFlags.Instance); if (field == null) // Roslyn field = enumerator.GetType().GetField("<>1__state", BindingFlags.NonPublic | BindingFlags.Instance); return field; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditModePCHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 6d16f2e78a356d34c9a32108929de932 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditModeRunner.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine; using UnityEngine.TestTools.NUnitExtensions; using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools; using UnityEngine.TestTools.TestRunner.GUI; using UnityEditor.Callbacks; using UnityEngine.TestRunner.NUnitExtensions; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEditor.TestTools.TestRunner { internal interface IUnityTestAssemblyRunnerFactory { IUnityTestAssemblyRunner Create(TestPlatform testPlatform, WorkItemFactory factory); } internal class UnityTestAssemblyRunnerFactory : IUnityTestAssemblyRunnerFactory { public IUnityTestAssemblyRunner Create(TestPlatform testPlatform, WorkItemFactory factory) { return new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(), factory); } } [Serializable] internal class EditModeRunner : ScriptableObject, IDisposable { [SerializeField] private TestRunnerFilter m_Filter; //The counter from the IEnumerator object [SerializeField] private int m_CurrentPC; [SerializeField] private bool m_ExecuteOnEnable; [SerializeField] private List m_AlreadyStartedTests; [SerializeField] private List m_ExecutedTests; [SerializeField] private List m_CallbackObjects = new List(); [SerializeField] private TestStartedEvent m_TestStartedEvent = new TestStartedEvent(); [SerializeField] private TestFinishedEvent m_TestFinishedEvent = new TestFinishedEvent(); [SerializeField] private RunStartedEvent m_RunStartedEvent = new RunStartedEvent(); [SerializeField] private RunFinishedEvent m_RunFinishedEvent = new RunFinishedEvent(); [SerializeField] private TestRunnerStateSerializer m_TestRunnerStateSerializer = new TestRunnerStateSerializer(); [SerializeField] private TestFileCleanupVerifier m_CleanupVerifier = new TestFileCleanupVerifier(); [SerializeField] private bool m_RunningTests; [SerializeField] private TestPlatform m_TestPlatform; [SerializeField] private object m_CurrentYieldObject; [SerializeField] private BeforeAfterTestCommandState m_SetUpTearDownState; [SerializeField] private BeforeAfterTestCommandState m_OuterUnityTestActionState; internal IUnityTestAssemblyRunner m_Runner; private ConstructDelegator m_ConstructDelegator; private IEnumerator m_RunStep; public IUnityTestAssemblyRunnerFactory UnityTestAssemblyRunnerFactory { get; set; } public void Init(TestRunnerFilter filter, TestPlatform platform) { m_Filter = filter; m_TestPlatform = platform; m_AlreadyStartedTests = new List(); m_ExecutedTests = new List(); InitRunner(); } private void InitRunner() { //We give the EditMode platform here so we dont suddenly create Playmode work items in the test Runner. m_Runner = (UnityTestAssemblyRunnerFactory ?? new UnityTestAssemblyRunnerFactory()).Create(TestPlatform.EditMode, new EditmodeWorkItemFactory()); var testAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy()); var loadedTests = m_Runner.Load( testAssemblyProvider.GetAssembliesGroupedByType(m_TestPlatform).Select(x => x.Assembly).ToArray(), UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(m_TestPlatform)); loadedTests.ParseForNameDuplicates(); hideFlags |= HideFlags.DontSave; EnumerableSetUpTearDownCommand.ActivePcHelper = new EditModePcHelper(); OuterUnityTestActionCommand.ActivePcHelper = new EditModePcHelper(); } public void OnEnable() { if (m_ExecuteOnEnable) { InitRunner(); m_ExecuteOnEnable = false; foreach (var callback in m_CallbackObjects) { AddListeners(callback as ITestRunnerListener); } m_ConstructDelegator = new ConstructDelegator(m_TestRunnerStateSerializer); EnumeratorStepHelper.SetEnumeratorPC(m_CurrentPC); UnityWorkItemDataHolder.alreadyExecutedTests = m_ExecutedTests.Select(x => x.fullName).ToList(); UnityWorkItemDataHolder.alreadyStartedTests = m_AlreadyStartedTests; Run(); } } public void TestStartedEvent(ITest test) { m_AlreadyStartedTests.Add(test.FullName); } public void TestFinishedEvent(ITestResult testResult) { m_AlreadyStartedTests.Remove(testResult.FullName); m_ExecutedTests.Add(TestResultSerializer.MakeFromTestResult(testResult)); } public void Run() { EditModeTestCallbacks.RestoringTestContext += OnRestoringTest; var context = m_Runner.GetCurrentContext(); if (m_SetUpTearDownState == null) { m_SetUpTearDownState = CreateInstance(); } context.SetUpTearDownState = m_SetUpTearDownState; if (m_OuterUnityTestActionState == null) { m_OuterUnityTestActionState = CreateInstance(); } context.OuterUnityTestActionState = m_OuterUnityTestActionState; m_CleanupVerifier.RegisterExistingFiles(); if (!m_RunningTests) { m_RunStartedEvent.Invoke(m_Runner.LoadedTest); } if (m_ConstructDelegator == null) m_ConstructDelegator = new ConstructDelegator(m_TestRunnerStateSerializer); Reflect.ConstructorCallWrapper = m_ConstructDelegator.Delegate; m_TestStartedEvent.AddListener(TestStartedEvent); m_TestFinishedEvent.AddListener(TestFinishedEvent); AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload; RunningTests = true; EditorApplication.LockReloadAssemblies(); var testListenerWrapper = new TestListenerWrapper(m_TestStartedEvent, m_TestFinishedEvent); m_RunStep = m_Runner.Run(testListenerWrapper, m_Filter.BuildNUnitFilter()).GetEnumerator(); m_RunningTests = true; EditorApplication.update += TestConsumer; } private void OnBeforeAssemblyReload() { EditorApplication.update -= TestConsumer; if (m_ExecuteOnEnable) { AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload; return; } if (m_Runner != null && m_Runner.TopLevelWorkItem != null) m_Runner.TopLevelWorkItem.ResultedInDomainReload = true; if (RunningTests) { Debug.LogError("TestRunner: Unexpected assembly reload happened while running tests"); EditorUtility.ClearProgressBar(); if (m_Runner.GetCurrentContext() != null && m_Runner.GetCurrentContext().CurrentResult != null) { m_Runner.GetCurrentContext().CurrentResult.SetResult(ResultState.Cancelled, "Unexpected assembly reload happened"); } OnRunCancel(); } } private bool RunningTests; private Stack StepStack = new Stack(); private bool MoveNextAndUpdateYieldObject() { var result = m_RunStep.MoveNext(); if (result) { m_CurrentYieldObject = m_RunStep.Current; while (m_CurrentYieldObject is IEnumerator) // going deeper { var currentEnumerator = (IEnumerator)m_CurrentYieldObject; // go deeper and add parent to stack StepStack.Push(m_RunStep); m_RunStep = currentEnumerator; m_CurrentYieldObject = m_RunStep.Current; } if (StepStack.Count > 0 && m_CurrentYieldObject != null) // not null and not IEnumerator, nested { Debug.LogError("EditMode test can only yield null, but not <" + m_CurrentYieldObject.GetType().Name + ">"); } return true; } if (StepStack.Count == 0) // done return false; m_RunStep = StepStack.Pop(); // going up return MoveNextAndUpdateYieldObject(); } private void TestConsumer() { var moveNext = MoveNextAndUpdateYieldObject(); if (m_CurrentYieldObject != null) { InvokeDelegator(); } if (!moveNext && !m_Runner.IsTestComplete) { CompleteTestRun(); throw new IndexOutOfRangeException("There are no more elements to process and IsTestComplete is false"); } if (m_Runner.IsTestComplete) { CompleteTestRun(); } } private void CompleteTestRun() { EditorApplication.update -= TestConsumer; TestLauncherBase.ExecutePostBuildCleanupMethods(this.GetLoadedTests(), this.GetFilter(), Application.platform); m_CleanupVerifier.VerifyNoNewFilesAdded(); m_RunFinishedEvent.Invoke(m_Runner.Result); if (m_ConstructDelegator != null) m_ConstructDelegator.DestroyCurrentTestObjectIfExists(); Dispose(); UnityWorkItemDataHolder.alreadyExecutedTests = null; } private void OnRestoringTest() { var item = m_ExecutedTests.Find(t => t.fullName == UnityTestExecutionContext.CurrentContext.CurrentTest.FullName); if (item != null) { item.RestoreTestResult(UnityTestExecutionContext.CurrentContext.CurrentResult); } } private static bool IsCancelled() { return UnityTestExecutionContext.CurrentContext.ExecutionStatus == TestExecutionStatus.AbortRequested || UnityTestExecutionContext.CurrentContext.ExecutionStatus == TestExecutionStatus.StopRequested; } private void InvokeDelegator() { if (m_CurrentYieldObject == null) { return; } if (IsCancelled()) { return; } if (m_CurrentYieldObject is RestoreTestContextAfterDomainReload) { if (m_TestRunnerStateSerializer.ShouldRestore()) { m_TestRunnerStateSerializer.RestoreContext(); } return; } try { if (m_CurrentYieldObject is IEditModeTestYieldInstruction) { var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)m_CurrentYieldObject; if (editModeTestYieldInstruction.ExpectDomainReload) { PrepareForDomainReload(); } return; } } catch (Exception e) { UnityTestExecutionContext.CurrentContext.CurrentResult.RecordException(e); return; } Debug.LogError("EditMode test can only yield null"); } private void CompilationFailureWatch() { if (EditorApplication.isCompiling) return; EditorApplication.update -= CompilationFailureWatch; if (EditorUtility.scriptCompilationFailed) { EditorUtility.ClearProgressBar(); OnRunCancel(); } } private void PrepareForDomainReload() { m_TestRunnerStateSerializer.SaveContext(); m_CurrentPC = EnumeratorStepHelper.GetEnumeratorPC(TestEnumerator.Enumerator); m_ExecuteOnEnable = true; RunningTests = false; } public T AddEventHandler() where T : ScriptableObject, ITestRunnerListener { var eventHandler = CreateInstance(); eventHandler.hideFlags |= HideFlags.DontSave; m_CallbackObjects.Add(eventHandler); AddListeners(eventHandler); return eventHandler; } private void AddListeners(ITestRunnerListener eventHandler) { m_TestStartedEvent.AddListener(eventHandler.TestStarted); m_TestFinishedEvent.AddListener(eventHandler.TestFinished); m_RunStartedEvent.AddListener(eventHandler.RunStarted); m_RunFinishedEvent.AddListener(eventHandler.RunFinished); } public void Dispose() { Reflect.MethodCallWrapper = null; EditorApplication.update -= TestConsumer; DestroyImmediate(this); if (m_CallbackObjects != null) { foreach (var obj in m_CallbackObjects) { DestroyImmediate(obj); } m_CallbackObjects.Clear(); } RunningTests = false; EditorApplication.UnlockReloadAssemblies(); } public void OnRunCancel() { UnityWorkItemDataHolder.alreadyExecutedTests = null; m_ExecuteOnEnable = false; m_Runner.StopRun(); } public ITest GetLoadedTests() { return m_Runner.LoadedTest; } public ITestFilter GetFilter() { return m_Filter.BuildNUnitFilter(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditModeRunner.cs.meta ================================================ fileFormatVersion: 2 guid: c9219e99d466b7741a057132d1994f35 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditmodeWorkItemFactory.cs ================================================ using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEditor.TestTools.TestRunner { internal class EditmodeWorkItemFactory : WorkItemFactory { protected override UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest) { return new EditorEnumeratorTestWorkItem(method, filter); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditmodeWorkItemFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 3dde15f260b0dd1469e60d16eaa795dc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditorEnumeratorTestWorkItem.cs ================================================ using System; using System.Collections; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Execution; using UnityEngine; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class EditorEnumeratorTestWorkItem : UnityWorkItem { private TestCommand m_Command; public EditorEnumeratorTestWorkItem(TestMethod test, ITestFilter filter) : base(test, null) { m_Command = test.RunState == RunState.Runnable || test.RunState == RunState.Explicit && filter.IsExplicitMatch(test) ? CommandBuilder.MakeTestCommand(test) : CommandBuilder.MakeSkipCommand(test); } private static IEnumerableTestMethodCommand FindFirstIEnumerableTestMethodCommand(TestCommand command) { if (command == null) { return null; } if (command is IEnumerableTestMethodCommand) { return (IEnumerableTestMethodCommand)command; } if (command is DelegatingTestCommand) { var delegatingTestCommand = (DelegatingTestCommand)command; return FindFirstIEnumerableTestMethodCommand(delegatingTestCommand.GetInnerCommand()); } return null; } protected override IEnumerable PerformWork() { if (IsCancelledRun()) { yield break; } if (m_DontRunRestoringResult) { if (EditModeTestCallbacks.RestoringTestContext == null) { throw new NullReferenceException("RestoringTestContext is not set"); } EditModeTestCallbacks.RestoringTestContext(); Result = Context.CurrentResult; yield break; } try { if (IsCancelledRun()) { yield break; } if (m_Command is SkipCommand) { m_Command.Execute(Context); Result = Context.CurrentResult; yield break; } //Check if we can execute this test var firstEnumerableCommand = FindFirstIEnumerableTestMethodCommand(m_Command); if (firstEnumerableCommand == null) { Context.CurrentResult.SetResult(ResultState.Error, "Returning IEnumerator but not using test attribute supporting this"); yield break; } if (m_Command.Test.Method.ReturnType.IsType(typeof(IEnumerator))) { if (m_Command is ApplyChangesToContextCommand) { var applyChangesToContextCommand = ((ApplyChangesToContextCommand)m_Command); applyChangesToContextCommand.ApplyChanges(Context); m_Command = applyChangesToContextCommand.GetInnerCommand(); } var innerCommand = (IEnumerableTestMethodCommand)m_Command; if (innerCommand == null) { Debug.Log("failed getting innerCommand"); throw new Exception("Tests returning IEnumerator can only use test attributes handling those"); } foreach (var workItemStep in innerCommand.ExecuteEnumerable(Context)) { if (IsCancelledRun()) { yield break; } if (workItemStep is TestEnumerator) { if (EnumeratorStepHelper.UpdateEnumeratorPcIfNeeded(TestEnumerator.Enumerator)) { yield return new RestoreTestContextAfterDomainReload(); } continue; } if (workItemStep is AsyncOperation) { var asyncOperation = (AsyncOperation)workItemStep; while (!asyncOperation.isDone) { if (IsCancelledRun()) { yield break; } yield return null; } continue; } ResultedInDomainReload = false; if (workItemStep is IEditModeTestYieldInstruction) { var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)workItemStep; yield return editModeTestYieldInstruction; var enumerator = editModeTestYieldInstruction.Perform(); while (true) { bool moveNext; try { moveNext = enumerator.MoveNext(); } catch (Exception e) { Context.CurrentResult.RecordException(e); break; } if (!moveNext) { break; } yield return null; } } else { yield return workItemStep; } } Result = Context.CurrentResult; EditorApplication.isPlaying = false; yield return null; } } finally { WorkItemComplete(); } } private bool IsCancelledRun() { return Context.ExecutionStatus == TestExecutionStatus.AbortRequested || Context.ExecutionStatus == TestExecutionStatus.StopRequested; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EditorEnumeratorTestWorkItem.cs.meta ================================================ fileFormatVersion: 2 guid: 1ebc1994f9a3d5649a1201d3a84b38df MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EnumeratorStepHelper.cs ================================================ using System.Collections; using System.Reflection; namespace UnityEditor.TestTools.TestRunner { internal class EnumeratorStepHelper { private static int m_PC; public static void SetEnumeratorPC(int pc) { m_PC = pc; } /// /// Gets the current enumerator PC /// /// /// The PC /// 0 if no current Enumeration /// public static int GetEnumeratorPC(IEnumerator enumerator) { if (enumerator == null) { return 0; } return (int)GetPCFieldInfo(enumerator).GetValue(enumerator); } public static bool UpdateEnumeratorPcIfNeeded(IEnumerator enumerator) { if (m_PC > 0) { GetPCFieldInfo(enumerator).SetValue(enumerator, m_PC); m_PC = 0; return true; } return false; } private static FieldInfo GetPCFieldInfo(IEnumerator enumerator) { var field = enumerator.GetType().GetField("$PC", BindingFlags.NonPublic | BindingFlags.Instance); if (field == null) // Roslyn field = enumerator.GetType().GetField("<>1__state", BindingFlags.NonPublic | BindingFlags.Instance); return field; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/EnumeratorStepHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 901b761c5c1e22d4e8a3ba7d95bc1f5d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/EnterPlayMode.cs ================================================ using System; using System.Collections; using UnityEditor; namespace UnityEngine.TestTools { public class EnterPlayMode : IEditModeTestYieldInstruction { public bool ExpectDomainReload { get; } public bool ExpectedPlaymodeState { get; private set; } public EnterPlayMode(bool expectDomainReload = true) { ExpectDomainReload = expectDomainReload; } public IEnumerator Perform() { if (EditorApplication.isPlaying) { throw new Exception("Editor is already in PlayMode"); } if (EditorUtility.scriptCompilationFailed) { throw new Exception("Script compilation failed"); } yield return null; ExpectedPlaymodeState = true; EditorApplication.UnlockReloadAssemblies(); EditorApplication.isPlaying = true; while (!EditorApplication.isPlaying) { yield return null; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/EnterPlayMode.cs.meta ================================================ fileFormatVersion: 2 guid: 9bd5a110ed89025499ddee8c7e73778e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/ExitPlayMode.cs ================================================ using System; using System.Collections; using UnityEditor; namespace UnityEngine.TestTools { public class ExitPlayMode : IEditModeTestYieldInstruction { public bool ExpectDomainReload { get; } public bool ExpectedPlaymodeState { get; private set; } public ExitPlayMode() { ExpectDomainReload = false; ExpectedPlaymodeState = false; } public IEnumerator Perform() { if (!EditorApplication.isPlayingOrWillChangePlaymode) { throw new Exception("Editor is already in EditMode"); } EditorApplication.isPlaying = false; while (EditorApplication.isPlaying) { yield return null; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/ExitPlayMode.cs.meta ================================================ fileFormatVersion: 2 guid: 408674d91d506a54aac9a7f07951c018 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/RecompileScripts.cs ================================================ using System; using System.Collections; using UnityEditor; namespace UnityEngine.TestTools { internal class RecompileScripts : IEditModeTestYieldInstruction { public RecompileScripts() : this(true) { } public RecompileScripts(bool expectScriptCompilation) : this(expectScriptCompilation, true) { } public RecompileScripts(bool expectScriptCompilation, bool expectScriptCompilationSuccess) { ExpectScriptCompilation = expectScriptCompilation; ExpectScriptCompilationSuccess = expectScriptCompilationSuccess; ExpectDomainReload = true; } public bool ExpectDomainReload { get; private set; } public bool ExpectedPlaymodeState { get; } public bool ExpectScriptCompilation { get; private set; } public bool ExpectScriptCompilationSuccess { get; private set; } public static RecompileScripts Current { get; private set; } public IEnumerator Perform() { Current = this; // We need to yield, to give the test runner a chance to prepare for the domain reload // If the script compilation happens very fast, then EditModeRunner.MoveNextAndUpdateYieldObject will not have a chance to set m_CurrentYieldObject // This really should be fixed in EditModeRunner.MoveNextAndUpdateYieldObject yield return null; AssetDatabase.Refresh(); if (ExpectScriptCompilation && !EditorApplication.isCompiling) { Current = null; throw new Exception("Editor does not need to recompile scripts"); } EditorApplication.UnlockReloadAssemblies(); while (EditorApplication.isCompiling) { yield return null; } Current = null; if (ExpectScriptCompilationSuccess && EditorUtility.scriptCompilationFailed) { EditorApplication.LockReloadAssemblies(); throw new Exception("Script compilation failed"); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/RecompileScripts.cs.meta ================================================ fileFormatVersion: 2 guid: 9202fbba95ea8294cb5e718f028f21b0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/WaitForDomainReload.cs ================================================ using System; using System.Collections; using UnityEditor; namespace UnityEngine.TestTools { internal class WaitForDomainReload : IEditModeTestYieldInstruction { public WaitForDomainReload() { ExpectDomainReload = true; } public bool ExpectDomainReload { get;  } public bool ExpectedPlaymodeState { get; } public IEnumerator Perform() { EditorApplication.UnlockReloadAssemblies(); // Detect if AssetDatabase.Refresh was called (true) or if it will be called on next tick bool isAsync = EditorApplication.isCompiling; yield return null; if (!isAsync) { EditorApplication.LockReloadAssemblies(); throw new Exception("Expected domain reload, but it did not occur"); } while (EditorApplication.isCompiling) { yield return null; } if (EditorUtility.scriptCompilationFailed) { EditorApplication.LockReloadAssemblies(); throw new Exception("Script compilation failed"); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages/WaitForDomainReload.cs.meta ================================================ fileFormatVersion: 2 guid: 5df3c21c5237c994db89660fbdfee07d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Messages.meta ================================================ fileFormatVersion: 2 guid: d9682e749d3efc642af54d789d9090a6 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/TestFileCleanupVerifier.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class TestFileCleanupVerifier { const string k_Indent = " "; [SerializeField] List m_ExistingFiles; [SerializeField] bool m_ExistingFilesScanned; public Action logAction = Debug.LogWarning; private Func getAllAssetPathsAction; public Func GetAllAssetPathsAction { get { if (getAllAssetPathsAction != null) { return getAllAssetPathsAction; } return AssetDatabase.GetAllAssetPaths; } set { getAllAssetPathsAction = value; } } public void RegisterExistingFiles() { if (m_ExistingFilesScanned) { return; } m_ExistingFiles = GetAllFilesInAssetsDirectory().ToList(); m_ExistingFilesScanned = true; } public void VerifyNoNewFilesAdded() { var currentFiles = GetAllFilesInAssetsDirectory().ToList(); //Expect that if its the same amount of files, there havent been any changes //This is to optimize if there are many files if (currentFiles.Count != m_ExistingFiles.Count) { LogWarningForFilesIfAny(currentFiles.Except(m_ExistingFiles)); } } void LogWarningForFilesIfAny(IEnumerable filePaths) { if (!filePaths.Any()) { return; } var stringWriter = new StringWriter(); stringWriter.WriteLine("Files generated by test without cleanup."); stringWriter.WriteLine(k_Indent + "Found {0} new files.", filePaths.Count()); foreach (var filePath in filePaths) { stringWriter.WriteLine(k_Indent + filePath); } LogAction(stringWriter.ToString()); } private void LogAction(object obj) { if (this.logAction != null) { this.logAction(obj); } else { Debug.LogWarning(obj); } } private IEnumerable GetAllFilesInAssetsDirectory() { return GetAllAssetPathsAction(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/TestFileCleanupVerifier.cs.meta ================================================ fileFormatVersion: 2 guid: d6e23541e3b2fea489be46f704b64707 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/CachingTestListProvider.cs ================================================ using System; using System.Collections.Generic; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestRunner.NUnitExtensions; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class CachingTestListProvider { private readonly ITestListProvider m_InnerTestListProvider; private readonly ITestListCache m_TestListCache; private readonly ITestAdaptorFactory m_TestAdaptorFactory; public CachingTestListProvider(ITestListProvider innerTestListProvider, ITestListCache testListCache, ITestAdaptorFactory testAdaptorFactory) { m_InnerTestListProvider = innerTestListProvider; m_TestListCache = testListCache; m_TestAdaptorFactory = testAdaptorFactory; } public IEnumerator GetTestListAsync(TestPlatform platform) { var testFromCache = m_TestListCache.GetTestFromCacheAsync(platform); while (testFromCache.MoveNext()) { yield return null; } if (testFromCache.Current != null) { yield return testFromCache.Current; } else { var test = m_InnerTestListProvider.GetTestListAsync(platform); while (test.MoveNext()) { yield return null; } test.Current.ParseForNameDuplicates(); m_TestListCache.CacheTest(platform, test.Current); yield return m_TestAdaptorFactory.Create(test.Current); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/CachingTestListProvider.cs.meta ================================================ fileFormatVersion: 2 guid: 26f3e7301af463c4ca72fa98d59b429e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorAssembliesProxy.cs ================================================ using System.Linq; using UnityEngine.TestTools.Utils; namespace UnityEditor.TestTools.TestRunner { internal class EditorAssembliesProxy : IEditorAssembliesProxy { public IAssemblyWrapper[] loadedAssemblies { get { return EditorAssemblies.loadedAssemblies.Select(x => new EditorAssemblyWrapper(x)).ToArray(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorAssembliesProxy.cs.meta ================================================ fileFormatVersion: 2 guid: f96d0ea807c081145a1170ed1b6d71e0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorAssemblyWrapper.cs ================================================ using System.Reflection; using UnityEngine.TestTools.Utils; namespace UnityEditor.TestTools.TestRunner { internal class EditorAssemblyWrapper : AssemblyWrapper { public EditorAssemblyWrapper(Assembly assembly) : base(assembly) {} public override AssemblyName[] GetReferencedAssemblies() { return Assembly.GetReferencedAssemblies(); } public override string Location { get { return Assembly.Location; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorAssemblyWrapper.cs.meta ================================================ fileFormatVersion: 2 guid: 20cdb37e6fea6d946bbb84d2c923db85 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorCompilationInterfaceProxy.cs ================================================ using UnityEditor.Scripting.ScriptCompilation; namespace UnityEditor.TestTools.TestRunner { internal class EditorCompilationInterfaceProxy : IEditorCompilationInterfaceProxy { public ScriptAssembly[] GetAllEditorScriptAssemblies() { return EditorCompilationInterface.Instance.GetAllEditorScriptAssemblies(EditorCompilationInterface.GetAdditionalEditorScriptCompilationOptions()); } public PrecompiledAssembly[] GetAllPrecompiledAssemblies() { return EditorCompilationInterface.Instance.GetAllPrecompiledAssemblies(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorCompilationInterfaceProxy.cs.meta ================================================ fileFormatVersion: 2 guid: c9b23632c77de204abfe8bf7168d48c0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorLoadedTestAssemblyProvider.cs ================================================ using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor.Scripting.ScriptCompilation; using UnityEngine.TestTools; using UnityEngine.TestTools.Utils; namespace UnityEditor.TestTools.TestRunner { internal class EditorLoadedTestAssemblyProvider { private const string k_NunitAssemblyName = "nunit.framework"; private const string k_TestRunnerAssemblyName = "UnityEngine.TestRunner"; internal const string k_PerformanceTestingAssemblyName = "Unity.PerformanceTesting"; private readonly IEditorAssembliesProxy m_EditorAssembliesProxy; private readonly ScriptAssembly[] m_AllEditorScriptAssemblies; private readonly PrecompiledAssembly[] m_AllPrecompiledAssemblies; public EditorLoadedTestAssemblyProvider(IEditorCompilationInterfaceProxy compilationInterfaceProxy, IEditorAssembliesProxy editorAssembliesProxy) { m_EditorAssembliesProxy = editorAssembliesProxy; m_AllEditorScriptAssemblies = compilationInterfaceProxy.GetAllEditorScriptAssemblies(); m_AllPrecompiledAssemblies = compilationInterfaceProxy.GetAllPrecompiledAssemblies(); } public List GetAssembliesGroupedByType(TestPlatform mode) { var assemblies = GetAssembliesGroupedByTypeAsync(mode); while (assemblies.MoveNext()) { } return assemblies.Current; } public IEnumerator> GetAssembliesGroupedByTypeAsync(TestPlatform mode) { IAssemblyWrapper[] loadedAssemblies = m_EditorAssembliesProxy.loadedAssemblies; IDictionary> result = new Dictionary>() { {TestPlatform.EditMode, new List() }, {TestPlatform.PlayMode, new List() } }; foreach (var loadedAssembly in loadedAssemblies) { if (loadedAssembly.GetReferencedAssemblies().Any(x => x.Name == k_NunitAssemblyName || x.Name == k_TestRunnerAssemblyName || x.Name == k_PerformanceTestingAssemblyName)) { var assemblyName = new FileInfo(loadedAssembly.Location).Name; var scriptAssemblies = m_AllEditorScriptAssemblies.Where(x => x.Filename == assemblyName).ToList(); var precompiledAssemblies = m_AllPrecompiledAssemblies.Where(x => new FileInfo(x.Path).Name == assemblyName).ToList(); if (scriptAssemblies.Count < 1 && precompiledAssemblies.Count < 1) { continue; } var assemblyFlags = scriptAssemblies.Any() ? scriptAssemblies.Single().Flags : precompiledAssemblies.Single().Flags; var assemblyType = (assemblyFlags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly ? TestPlatform.EditMode : TestPlatform.PlayMode; result[assemblyType].Add(loadedAssembly); yield return null; } } yield return result[mode]; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/EditorLoadedTestAssemblyProvider.cs.meta ================================================ fileFormatVersion: 2 guid: 033c884ba52437d49bc55935939ef1c6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/IEditorAssembliesProxy.cs ================================================ using UnityEngine.TestTools.Utils; namespace UnityEditor.TestTools.TestRunner { internal interface IEditorAssembliesProxy { IAssemblyWrapper[] loadedAssemblies { get; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/IEditorAssembliesProxy.cs.meta ================================================ fileFormatVersion: 2 guid: 98808b11e78f6c84a841a6b4bc5a29d2 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/IEditorCompilationInterfaceProxy.cs ================================================ using UnityEditor.Scripting.ScriptCompilation; namespace UnityEditor.TestTools.TestRunner { internal interface IEditorCompilationInterfaceProxy { ScriptAssembly[] GetAllEditorScriptAssemblies(); PrecompiledAssembly[] GetAllPrecompiledAssemblies(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/IEditorCompilationInterfaceProxy.cs.meta ================================================ fileFormatVersion: 2 guid: 28c8fcb831e6e734a9f564bc4f495eba MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/ITestListCache.cs ================================================ using System.Collections.Generic; using NUnit.Framework.Interfaces; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { interface ITestListCache { void CacheTest(TestPlatform platform, ITest test); IEnumerator GetTestFromCacheAsync(TestPlatform platform); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/ITestListCache.cs.meta ================================================ fileFormatVersion: 2 guid: a704c010bcdb1ec4a9f3417b3c393164 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/ITestListCacheData.cs ================================================ using System.Collections.Generic; using UnityEngine.TestRunner.TestLaunchers; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { interface ITestListCacheData { List platforms { get; } List cachedData { get; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/ITestListCacheData.cs.meta ================================================ fileFormatVersion: 2 guid: 7043e9a330ac2d84a80a965ada4589ad MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/ITestListProvider.cs ================================================ using System.Collections.Generic; using NUnit.Framework.Interfaces; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { interface ITestListProvider { IEnumerator GetTestListAsync(TestPlatform platform); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/ITestListProvider.cs.meta ================================================ fileFormatVersion: 2 guid: 64689f8b25eadac4da519e96f514b653 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListCache.cs ================================================ using System.Collections.Generic; using NUnit.Framework.Interfaces; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestRunner.TestLaunchers; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class TestListCache : ITestListCache { private readonly ITestAdaptorFactory m_TestAdaptorFactory; private readonly IRemoteTestResultDataFactory m_TestResultDataFactory; private readonly ITestListCacheData m_TestListCacheData; public TestListCache(ITestAdaptorFactory testAdaptorFactory, IRemoteTestResultDataFactory testResultDataFactory, ITestListCacheData testListCacheData) { m_TestAdaptorFactory = testAdaptorFactory; m_TestResultDataFactory = testResultDataFactory; m_TestListCacheData = testListCacheData; } public void CacheTest(TestPlatform platform, ITest test) { var data = m_TestResultDataFactory.CreateFromTest(test); var index = m_TestListCacheData.platforms.IndexOf(platform); if (index < 0) { m_TestListCacheData.cachedData.Add(data); m_TestListCacheData.platforms.Add(platform); } else { m_TestListCacheData.cachedData[index] = data; } } public IEnumerator GetTestFromCacheAsync(TestPlatform platform) { var index = m_TestListCacheData.platforms.IndexOf(platform); if (index < 0) { yield return null; yield break; } var testData = m_TestListCacheData.cachedData[index]; var test = m_TestAdaptorFactory.BuildTreeAsync(testData); while (test.MoveNext()) { yield return null; } yield return test.Current; } [Callbacks.DidReloadScripts] private static void ScriptReloaded() { TestListCacheData.instance.cachedData.Clear(); TestListCacheData.instance.platforms.Clear(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListCache.cs.meta ================================================ fileFormatVersion: 2 guid: d685d97a1eb004f49afea0cc982ff728 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListCacheData.cs ================================================ using System.Collections.Generic; using UnityEngine; using UnityEngine.TestRunner.TestLaunchers; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class TestListCacheData : ScriptableSingleton, ITestListCacheData { [SerializeField] private List m_Platforms = new List(); [SerializeField] private List m_CachedData = new List(); public List platforms { get { return m_Platforms; } } public List cachedData { get { return m_CachedData; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListCacheData.cs.meta ================================================ fileFormatVersion: 2 guid: f1b6399349763114d9361bc6dfcd025b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListJob.cs ================================================ using System; using System.Collections.Generic; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal class TestListJob { private CachingTestListProvider m_TestListProvider; private TestPlatform m_Platform; private Action m_Callback; private IEnumerator m_ResultEnumerator; public TestListJob(CachingTestListProvider testListProvider, TestPlatform platform, Action callback) { m_TestListProvider = testListProvider; m_Platform = platform; m_Callback = callback; } public void Start() { m_ResultEnumerator = m_TestListProvider.GetTestListAsync(m_Platform); EditorApplication.update += EditorUpdate; } private void EditorUpdate() { if (!m_ResultEnumerator.MoveNext()) { m_Callback(m_ResultEnumerator.Current); EditorApplication.update -= EditorUpdate; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListJob.cs.meta ================================================ fileFormatVersion: 2 guid: dec9066d4afefe444be0dad3f137730d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListProvider.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine.TestTools; using UnityEngine.TestTools.NUnitExtensions; namespace UnityEditor.TestTools.TestRunner { internal class TestListProvider : ITestListProvider { private readonly EditorLoadedTestAssemblyProvider m_AssemblyProvider; private readonly UnityTestAssemblyBuilder m_AssemblyBuilder; public TestListProvider(EditorLoadedTestAssemblyProvider assemblyProvider, UnityTestAssemblyBuilder assemblyBuilder) { m_AssemblyProvider = assemblyProvider; m_AssemblyBuilder = assemblyBuilder; } public IEnumerator GetTestListAsync(TestPlatform platform) { var assemblies = m_AssemblyProvider.GetAssembliesGroupedByTypeAsync(platform); while (assemblies.MoveNext()) { yield return null; } var settings = UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(platform); var test = m_AssemblyBuilder.BuildAsync(assemblies.Current.Select(x => x.Assembly).ToArray(), settings); while (test.MoveNext()) { yield return null; } yield return test.Current; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils/TestListProvider.cs.meta ================================================ fileFormatVersion: 2 guid: f15cbb987069826429540d0ea0937442 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner/Utils.meta ================================================ fileFormatVersion: 2 guid: 1f5bbb88ca730434483440cbc0278ef6 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunner.meta ================================================ fileFormatVersion: 2 guid: 49d4c2ab7ff0f4442af256bad7c9d57c folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunnerWindow.cs ================================================ using System; using UnityEditor.Callbacks; using UnityEditor.TestTools.TestRunner.Api; using UnityEditor.TestTools.TestRunner.GUI; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { [Serializable] internal class TestRunnerWindow : EditorWindow, IHasCustomMenu { internal static class Styles { public static GUIStyle info; public static GUIStyle testList; static Styles() { info = new GUIStyle(EditorStyles.wordWrappedLabel); info.wordWrap = false; info.stretchHeight = true; info.margin.right = 15; testList = new GUIStyle("CN Box"); testList.margin.top = 0; testList.padding.left = 3; } } private readonly GUIContent m_GUIHorizontalSplit = EditorGUIUtility.TrTextContent("Horizontal layout"); private readonly GUIContent m_GUIVerticalSplit = EditorGUIUtility.TrTextContent("Vertical layout"); private readonly GUIContent m_GUIEnableaPlaymodeTestsRunner = EditorGUIUtility.TrTextContent("Enable playmode tests for all assemblies"); private readonly GUIContent m_GUIDisablePlaymodeTestsRunner = EditorGUIUtility.TrTextContent("Disable playmode tests for all assemblies"); private readonly GUIContent m_GUIRunPlayModeTestAsEditModeTests = EditorGUIUtility.TrTextContent("Run playmode tests as editmode tests"); internal static TestRunnerWindow s_Instance; private bool m_IsBuilding; [NonSerialized] private bool m_Enabled; public TestFilterSettings filterSettings; private readonly SplitterState m_Spl = new SplitterState(new float[] { 75, 25 }, new[] { 32, 32 }, null); private TestRunnerWindowSettings m_Settings; private enum TestRunnerMenuLabels { PlayMode = 0, EditMode = 1 } [SerializeField] private int m_TestTypeToolbarIndex = (int)TestRunnerMenuLabels.EditMode; [SerializeField] private PlayModeTestListGUI m_PlayModeTestListGUI; [SerializeField] private EditModeTestListGUI m_EditModeTestListGUI; internal TestListGUI m_SelectedTestTypes; private ITestRunnerApi m_testRunnerApi; private WindowResultUpdater m_WindowResultUpdater; [MenuItem("Window/General/Test Runner", false, 201, false)] public static void ShowPlaymodeTestsRunnerWindowCodeBased() { if (s_Instance != null) { try { s_Instance.Close(); } catch (Exception exception) { Debug.LogException(exception); } } s_Instance = GetWindow("Test Runner"); s_Instance.Show(); } static TestRunnerWindow() { InitBackgroundRunners(); } private static void InitBackgroundRunners() { EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; } [DidReloadScripts] private static void CompilationCallback() { UpdateWindow(); } private static void OnPlayModeStateChanged(PlayModeStateChange state) { if (s_Instance && state == PlayModeStateChange.EnteredEditMode && s_Instance.m_SelectedTestTypes.HasTreeData()) { //repaint message details after exit playmode s_Instance.m_SelectedTestTypes.TestSelectionCallback(s_Instance.m_SelectedTestTypes.m_TestListState.selectedIDs.ToArray()); s_Instance.Repaint(); } } public void OnDestroy() { EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; if (m_testRunnerApi != null) { m_testRunnerApi.UnregisterCallbacks(m_WindowResultUpdater); } } private void OnEnable() { s_Instance = this; SelectTestListGUI(m_TestTypeToolbarIndex); m_testRunnerApi = ScriptableObject.CreateInstance(); m_WindowResultUpdater = new WindowResultUpdater(); m_testRunnerApi.RegisterCallbacks(m_WindowResultUpdater); } private void Enable() { m_Settings = new TestRunnerWindowSettings("UnityEditor.PlaymodeTestsRunnerWindow"); filterSettings = new TestFilterSettings("UnityTest.IntegrationTestsRunnerWindow"); if (m_SelectedTestTypes == null) { SelectTestListGUI(m_TestTypeToolbarIndex); } StartRetrieveTestList(); m_SelectedTestTypes.Reload(); m_Enabled = true; } private void SelectTestListGUI(int testTypeToolbarIndex) { if (testTypeToolbarIndex == (int)TestRunnerMenuLabels.PlayMode) { if (m_PlayModeTestListGUI == null) { m_PlayModeTestListGUI = new PlayModeTestListGUI(); } m_SelectedTestTypes = m_PlayModeTestListGUI; } else if (testTypeToolbarIndex == (int)TestRunnerMenuLabels.EditMode) { if (m_EditModeTestListGUI == null) { m_EditModeTestListGUI = new EditModeTestListGUI(); } m_SelectedTestTypes = m_EditModeTestListGUI; } } private void StartRetrieveTestList() { if (!m_SelectedTestTypes.HasTreeData()) { m_testRunnerApi.RetrieveTestList(new ExecutionSettings() { filter = new Filter() { testMode = m_SelectedTestTypes.TestMode } }, (rootTest) => { m_SelectedTestTypes.Init(this, rootTest); m_SelectedTestTypes.Reload(); }); } } public void OnGUI() { if (!m_Enabled) { Enable(); } if (BuildPipeline.isBuildingPlayer) { m_IsBuilding = true; } else if (m_IsBuilding) { m_IsBuilding = false; Repaint(); } EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); var selectedIndex = m_TestTypeToolbarIndex; m_TestTypeToolbarIndex = GUILayout.Toolbar(m_TestTypeToolbarIndex, Enum.GetNames(typeof(TestRunnerMenuLabels)), "LargeButton", UnityEngine.GUI.ToolbarButtonSize.FitToContents); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (selectedIndex != m_TestTypeToolbarIndex) { SelectTestListGUI(m_TestTypeToolbarIndex); StartRetrieveTestList(); } EditorGUILayout.BeginVertical(); using (new EditorGUI.DisabledScope(EditorApplication.isPlayingOrWillChangePlaymode)) { m_SelectedTestTypes.PrintHeadPanel(); } EditorGUILayout.EndVertical(); if (m_Settings.verticalSplit) SplitterGUILayout.BeginVerticalSplit(m_Spl); else SplitterGUILayout.BeginHorizontalSplit(m_Spl); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginVertical(Styles.testList); m_SelectedTestTypes.RenderTestList(); EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical(); m_SelectedTestTypes.RenderDetails(); if (m_Settings.verticalSplit) SplitterGUILayout.EndVerticalSplit(); else SplitterGUILayout.EndHorizontalSplit(); } public void AddItemsToMenu(GenericMenu menu) { menu.AddItem(m_GUIVerticalSplit, m_Settings.verticalSplit, m_Settings.ToggleVerticalSplit); menu.AddItem(m_GUIHorizontalSplit, !m_Settings.verticalSplit, m_Settings.ToggleVerticalSplit); menu.AddSeparator(null); var playModeTestRunnerEnabled = PlayerSettings.playModeTestRunnerEnabled; var currentActive = playModeTestRunnerEnabled ? m_GUIDisablePlaymodeTestsRunner : m_GUIEnableaPlaymodeTestsRunner; if (EditorPrefs.GetBool("InternalMode", false)) { menu.AddItem(m_GUIRunPlayModeTestAsEditModeTests, PlayerSettings.runPlayModeTestAsEditModeTest, () => { PlayerSettings.runPlayModeTestAsEditModeTest = !PlayerSettings.runPlayModeTestAsEditModeTest; }); } menu.AddItem(currentActive, false, () => { PlayerSettings.playModeTestRunnerEnabled = !playModeTestRunnerEnabled; EditorUtility.DisplayDialog(currentActive.text, "You need to restart the editor now", "Ok"); }); } public void RebuildUIFilter() { if (m_SelectedTestTypes != null && m_SelectedTestTypes.HasTreeData()) { m_SelectedTestTypes.RebuildUIFilter(); } } public static void UpdateWindow() { if (s_Instance != null && s_Instance.m_SelectedTestTypes != null) { s_Instance.m_SelectedTestTypes.Repaint(); s_Instance.Repaint(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunnerWindow.cs.meta ================================================ fileFormatVersion: 2 guid: 4dfcd3a631f61d248b7cc0b845d40345 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunnerWindowSettings.cs ================================================ namespace UnityEditor.TestTools.TestRunner { internal class TestRunnerWindowSettings { public bool verticalSplit; private readonly string m_PrefsKey; public TestRunnerWindowSettings(string prefsKey) { m_PrefsKey = prefsKey; verticalSplit = EditorPrefs.GetBool(m_PrefsKey + ".verticalSplit", true); } public void ToggleVerticalSplit() { verticalSplit = !verticalSplit; Save(); } private void Save() { EditorPrefs.SetBool(m_PrefsKey + ".verticalSplit", verticalSplit); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestRunnerWindowSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 2b301b727225f1941974d69e61a55620 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/ITestSettings.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner { internal interface ITestSettings : IDisposable { ScriptingImplementation? scriptingBackend { get; set; } string Architecture { get; set; } ApiCompatibilityLevel? apiProfile { get; set; } bool? appleEnableAutomaticSigning { get; set; } string appleDeveloperTeamID { get; set; } ProvisioningProfileType? iOSManualProvisioningProfileType { get; set; } string iOSManualProvisioningProfileID { get; set; } ProvisioningProfileType? tvOSManualProvisioningProfileType { get; set; } string tvOSManualProvisioningProfileID { get; set; } void SetupProjectParameters(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/ITestSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 83eda34b7da01e04aa894f268158b0c0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/ITestSettingsDeserializer.cs ================================================ namespace UnityEditor.TestTools.TestRunner { interface ITestSettingsDeserializer { ITestSettings GetSettingsFromJsonFile(string jsonFilePath); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/ITestSettingsDeserializer.cs.meta ================================================ fileFormatVersion: 2 guid: d208a1684f8aa6a40ad91d6aa9600c14 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/TestSettings.cs ================================================ using System; namespace UnityEditor.TestTools.TestRunner { internal class TestSettings : ITestSettings { private readonly TestSetting[] m_Settings = { new TestSetting( settings => settings.scriptingBackend, () => PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.activeBuildTargetGroup), implementation => PlayerSettings.SetScriptingBackend(EditorUserBuildSettings.activeBuildTargetGroup, implementation.Value)), new TestSetting( settings => settings.Architecture, () => EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android ? PlayerSettings.Android.targetArchitectures.ToString() : null, architecture => { if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android) { if (!string.IsNullOrEmpty(architecture)) { var targetArchitectures = (AndroidArchitecture)Enum.Parse(typeof(AndroidArchitecture), architecture, true); PlayerSettings.Android.targetArchitectures = targetArchitectures; } } }), new TestSetting( settings => settings.apiProfile, () => PlayerSettings.GetApiCompatibilityLevel(EditorUserBuildSettings.activeBuildTargetGroup), implementation => { if (Enum.IsDefined(typeof(ApiCompatibilityLevel), implementation.Value)) { PlayerSettings.SetApiCompatibilityLevel(EditorUserBuildSettings.activeBuildTargetGroup, implementation.Value); } }), new TestSetting( settings => settings.appleEnableAutomaticSigning, () => PlayerSettings.iOS.appleEnableAutomaticSigning, enableAutomaticSigning => { if (enableAutomaticSigning != null) PlayerSettings.iOS.appleEnableAutomaticSigning = enableAutomaticSigning.Value; }), new TestSetting( settings => settings.appleDeveloperTeamID, () => PlayerSettings.iOS.appleDeveloperTeamID, developerTeam => { if (developerTeam != null) PlayerSettings.iOS.appleDeveloperTeamID = developerTeam; }), new TestSetting( settings => settings.iOSManualProvisioningProfileType, () => PlayerSettings.iOS.iOSManualProvisioningProfileType, profileType => { if (profileType != null) PlayerSettings.iOS.iOSManualProvisioningProfileType = profileType.Value; }), new TestSetting( settings => settings.iOSManualProvisioningProfileID, () => PlayerSettings.iOS.iOSManualProvisioningProfileID, provisioningUUID => { if (provisioningUUID != null) PlayerSettings.iOS.iOSManualProvisioningProfileID = provisioningUUID; }), new TestSetting( settings => settings.tvOSManualProvisioningProfileType, () => PlayerSettings.iOS.tvOSManualProvisioningProfileType, profileType => { if (profileType != null) PlayerSettings.iOS.tvOSManualProvisioningProfileType = profileType.Value; }), new TestSetting( settings => settings.tvOSManualProvisioningProfileID, () => PlayerSettings.iOS.tvOSManualProvisioningProfileID, provisioningUUID => { if (provisioningUUID != null) PlayerSettings.iOS.tvOSManualProvisioningProfileID = provisioningUUID; }), }; private bool m_Disposed; public ScriptingImplementation? scriptingBackend { get; set; } public string Architecture { get; set; } public ApiCompatibilityLevel? apiProfile { get; set; } public bool? appleEnableAutomaticSigning { get; set; } public string appleDeveloperTeamID { get; set; } public ProvisioningProfileType? iOSManualProvisioningProfileType { get; set; } public string iOSManualProvisioningProfileID { get; set; } public ProvisioningProfileType? tvOSManualProvisioningProfileType { get; set; } public string tvOSManualProvisioningProfileID { get; set; } public void Dispose() { if (!m_Disposed) { foreach (var testSetting in m_Settings) { testSetting.Cleanup(); } m_Disposed = true; } } public void SetupProjectParameters() { foreach (var testSetting in m_Settings) { testSetting.Setup(this); } } private abstract class TestSetting { public abstract void Setup(TestSettings settings); public abstract void Cleanup(); } private class TestSetting : TestSetting { private T m_ValueBeforeSetup; private Func m_GetFromSettings; private Func m_GetCurrentValue; private Action m_SetValue; public TestSetting(Func getFromSettings, Func getCurrentValue, Action setValue) { m_GetFromSettings = getFromSettings; m_GetCurrentValue = getCurrentValue; m_SetValue = setValue; } public override void Setup(TestSettings settings) { m_ValueBeforeSetup = m_GetCurrentValue(); var newValue = m_GetFromSettings(settings); if (newValue != null) { m_SetValue(newValue); } } public override void Cleanup() { m_SetValue(m_ValueBeforeSetup); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/TestSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 6b32b6725087a0d4bb1670818d26996e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/TestSettingsDeserializer.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; namespace UnityEditor.TestTools.TestRunner { /// /// Handles deserialization of TestSettings from a provided json file path. /// internal class TestSettingsDeserializer : ITestSettingsDeserializer { private static readonly SettingsMap[] s_SettingsMapping = { new SettingsMap("scriptingBackend", (settings, value) => settings.scriptingBackend = value), new SettingsMap("architecture", (settings, value) => settings.Architecture = value), new SettingsMap("apiProfile", (settings, value) => settings.apiProfile = value), new SettingsMap("appleEnableAutomaticSigning", (settings, value) => settings.appleEnableAutomaticSigning = value), new SettingsMap("appleDeveloperTeamID", (settings, value) => settings.appleDeveloperTeamID = value), new SettingsMap("iOSManualProvisioningProfileType", (settings, value) => settings.iOSManualProvisioningProfileType = value), new SettingsMap("iOSManualProvisioningProfileID", (settings, value) => settings.iOSManualProvisioningProfileID = value), new SettingsMap("tvOSManualProvisioningProfileType", (settings, value) => settings.tvOSManualProvisioningProfileType = value), new SettingsMap("tvOSManualProvisioningProfileID", (settings, value) => settings.tvOSManualProvisioningProfileID = value), }; private readonly Func m_TestSettingsFactory; public TestSettingsDeserializer(Func testSettingsFactory) { m_TestSettingsFactory = testSettingsFactory; } public ITestSettings GetSettingsFromJsonFile(string jsonFilePath) { var text = File.ReadAllText(jsonFilePath); var settingsDictionary = Json.Deserialize(text) as Dictionary; var testSettings = m_TestSettingsFactory(); if (settingsDictionary == null) { return testSettings; } foreach (var settingsMap in s_SettingsMapping) { if (!settingsDictionary.ContainsKey(settingsMap.Key)) { continue; } if (settingsMap.Type.IsEnum) { SetEnumValue(settingsMap.Key, settingsDictionary[settingsMap.Key], settingsMap.Type, value => settingsMap.ApplyToSettings(testSettings, value)); } else { SetValue(settingsMap.Key, settingsDictionary[settingsMap.Key], settingsMap.Type, value => settingsMap.ApplyToSettings(testSettings, value)); } } return testSettings; } private abstract class SettingsMap { public string Key { get; } public Type Type { get; } protected SettingsMap(string key, Type type) { Key = key; Type = type; } public abstract void ApplyToSettings(ITestSettings settings, object value); } private class SettingsMap : SettingsMap { private Action m_Setter; public SettingsMap(string key, Action setter) : base(key, typeof(T)) { m_Setter = setter; } public override void ApplyToSettings(ITestSettings settings, object value) { m_Setter(settings, (T)value); } } private static void SetEnumValue(string key, object value, Type type, Action setter) { object enumValue; if (TryGetEnum(value as string, type, out enumValue)) { setter(enumValue); return; } var acceptedValues = string.Join(", ", Enum.GetValues(type).OfType().Select(val => val.ToString()).ToArray()); Debug.LogFormat("Could not convert '{0}' argument '{1}' to a valid {2}. Accepted values: {3}.", key, value, type.Name, acceptedValues); } private static bool TryGetEnum(string value, Type type, out object enumValue) { try { enumValue = Enum.Parse(type, value, true); return true; } catch (Exception) { enumValue = null; return false; } } private static void SetValue(string key, object value, Type type, Action setter) { if (type.IsInstanceOfType(value)) { setter(value); return; } Debug.LogFormat("Could not convert '{0}' argument '{1}' to a valid {2}.", key, value, type.Name); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings/TestSettingsDeserializer.cs.meta ================================================ fileFormatVersion: 2 guid: 75e7d7a9a57458841a85fe42d9c9141f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/TestSettings.meta ================================================ fileFormatVersion: 2 guid: 95b719082a664ea45bb56759eed1f271 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityEditor.TestRunner.asmdef ================================================ { "name": "UnityEditor.TestRunner", "references": [ "UnityEngine.TestRunner" ], "includePlatforms": [ "Editor" ], "excludePlatforms": [], "allowUnsafeCode": false, "overrideReferences": true, "precompiledReferences": [ "nunit.framework.dll", "Mono.Cecil.dll", "Mono.Cecil.Pdb.dll", "Mono.Cecil.Mdb.dll", "Mono.Cecil.Rocks.dll" ], "autoReferenced": false, "defineConstraints": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityEditor.TestRunner.asmdef.meta ================================================ fileFormatVersion: 2 guid: 0acc523941302664db1f4e527237feb3 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/AssemblyCompilationErrorsMessage.cs ================================================ namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class AssemblyCompilationErrorsMessage : Message { public string assembly; public string[] errors; public AssemblyCompilationErrorsMessage() { type = "AssemblyCompilationErrors"; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/AssemblyCompilationErrorsMessage.cs.meta ================================================ fileFormatVersion: 2 guid: c346a7445959bba46a96de0747e77c2a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/ITestRunnerApiMapper.cs ================================================ using System.Collections.Generic; using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { interface ITestRunnerApiMapper { string GetRunStateFromResultNunitXml(ITestResultAdaptor result); TestState GetTestStateFromResult(ITestResultAdaptor result); List FlattenTestNames(ITestAdaptor testsToRun); TestPlanMessage MapTestToTestPlanMessage(ITestAdaptor testsToRun); TestStartedMessage MapTestToTestStartedMessage(ITestAdaptor test); TestFinishedMessage TestResultToTestFinishedMessage(ITestResultAdaptor result); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/ITestRunnerApiMapper.cs.meta ================================================ fileFormatVersion: 2 guid: 6de79ae237e51554da96fd28f68b66a6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/IUtpLogger.cs ================================================ namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { interface IUtpLogger { void Log(Message msg); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/IUtpLogger.cs.meta ================================================ fileFormatVersion: 2 guid: 9014630255533ed42915965b4065cde8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/IUtpMessageReporter.cs ================================================ using System.Collections.Generic; using UnityEditor.Compilation; using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal interface IUtpMessageReporter { void ReportAssemblyCompilationErrors(string assembly, IEnumerable errorCompilerMessages); void ReportTestFinished(ITestResultAdaptor result); void ReportTestRunStarted(ITestAdaptor testsToRun); void ReportTestStarted(ITestAdaptor test); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/IUtpMessageReporter.cs.meta ================================================ fileFormatVersion: 2 guid: 952b3dc7b47846947b37c8d3ae46579a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/Message.cs ================================================ using System; using System.Diagnostics; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { [Serializable] internal abstract class Message { public string type; // Milliseconds since unix epoch public ulong time; public int version; public string phase; public int processId; protected Message() { version = 2; phase = "Immediate"; processId = Process.GetCurrentProcess().Id; AddTimeStamp(); } public void AddTimeStamp() { time = Convert.ToUInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/Message.cs.meta ================================================ fileFormatVersion: 2 guid: 321dc2c0720f8dd4f9396ecdc12b8746 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestFinishedMessage.cs ================================================ namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class TestFinishedMessage : Message { public string name; public TestState state; public string message; public ulong duration; // milliseconds public ulong durationMicroseconds; public TestFinishedMessage() { type = "TestStatus"; phase = "End"; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestFinishedMessage.cs.meta ================================================ fileFormatVersion: 2 guid: 423fe2ef878fa1140a7e1f7f9e365815 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestPlanMessage.cs ================================================ using System.Collections.Generic; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class TestPlanMessage : Message { public List tests; public TestPlanMessage() { type = "TestPlan"; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestPlanMessage.cs.meta ================================================ fileFormatVersion: 2 guid: 28f79a0d7e64c2345bc46f8c4cf788f8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestRunnerApiMapper.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Xml; using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class TestRunnerApiMapper : ITestRunnerApiMapper { public TestPlanMessage MapTestToTestPlanMessage(ITestAdaptor testsToRun) { var testsNames = testsToRun != null ? FlattenTestNames(testsToRun) : new List(); var msg = new TestPlanMessage { tests = testsNames }; return msg; } public TestStartedMessage MapTestToTestStartedMessage(ITestAdaptor test) { return new TestStartedMessage { name = test.FullName }; } public TestFinishedMessage TestResultToTestFinishedMessage(ITestResultAdaptor result) { return new TestFinishedMessage { name = result.Test.FullName, duration = Convert.ToUInt64(result.Duration * 1000), durationMicroseconds = Convert.ToUInt64(result.Duration * 1000000), message = result.Message, state = GetTestStateFromResult(result) }; } public string GetRunStateFromResultNunitXml(ITestResultAdaptor result) { var doc = new XmlDocument(); doc.LoadXml(result.ToXml().OuterXml); return doc.FirstChild.Attributes["runstate"].Value; } public TestState GetTestStateFromResult(ITestResultAdaptor result) { var state = TestState.Failure; if (result.TestStatus == TestStatus.Passed) { state = TestState.Success; var runstate = GetRunStateFromResultNunitXml(result); runstate = runstate ?? String.Empty; if (runstate.ToLowerInvariant().Equals("explicit")) state = TestState.Skipped; } else if (result.TestStatus == TestStatus.Skipped) { state = TestState.Skipped; if (result.ResultState.ToLowerInvariant().EndsWith("ignored")) state = TestState.Ignored; } else { if (result.ResultState.ToLowerInvariant().Equals("inconclusive")) state = TestState.Inconclusive; if (result.ResultState.ToLowerInvariant().EndsWith("cancelled") || result.ResultState.ToLowerInvariant().EndsWith("error")) state = TestState.Error; } return state; } public List FlattenTestNames(ITestAdaptor test) { var results = new List(); if (!test.IsSuite) results.Add(test.FullName); if (test.Children != null && test.Children.Any()) foreach (var child in test.Children) results.AddRange(FlattenTestNames(child)); return results; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestRunnerApiMapper.cs.meta ================================================ fileFormatVersion: 2 guid: 2011a59d3f76b3d4a85cb53f945fceee MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestStartedMessage.cs ================================================ namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class TestStartedMessage : Message { public string name; public TestState state; public TestStartedMessage() { type = "TestStatus"; phase = "Begin"; state = TestState.Inconclusive; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestStartedMessage.cs.meta ================================================ fileFormatVersion: 2 guid: bd3e81baa10021f4d877fa36382bab16 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestState.cs ================================================ namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { // This matches the state definitions expected by the Perl code, which in turn matches the NUnit 2 values... internal enum TestState { Inconclusive = 0, Skipped = 2, Ignored = 3, Success = 4, Failure = 5, Error = 6 } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/TestState.cs.meta ================================================ fileFormatVersion: 2 guid: 77f432980bb30084299a138e15c6f571 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UnityTestProtocolListener.cs ================================================ using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class UnityTestProtocolListener : ScriptableObject, ICallbacks { private IUtpMessageReporter m_UtpMessageReporter; public UnityTestProtocolListener() { m_UtpMessageReporter = new UtpMessageReporter(new UtpDebugLogger()); } public void RunStarted(ITestAdaptor testsToRun) { m_UtpMessageReporter.ReportTestRunStarted(testsToRun); } public void RunFinished(ITestResultAdaptor testResults) { // Apparently does nothing :) } public void TestStarted(ITestAdaptor test) { m_UtpMessageReporter.ReportTestStarted(test); } public void TestFinished(ITestResultAdaptor result) { m_UtpMessageReporter.ReportTestFinished(result); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UnityTestProtocolListener.cs.meta ================================================ fileFormatVersion: 2 guid: 900aac3710bc14542a8d164e3f0ff820 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UnityTestProtocolStarter.cs ================================================ using System; using System.Linq; using UnityEditor.Compilation; using UnityEditor.TestTools.TestRunner.Api; using UnityEngine; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { [InitializeOnLoad] internal static class UnityTestProtocolStarter { static UnityTestProtocolStarter() { var commandLineArgs = Environment.GetCommandLineArgs(); if (commandLineArgs.Contains("-automated") && commandLineArgs.Contains("-runTests")) // wanna have it only for utr run { var api = ScriptableObject.CreateInstance(); var listener = ScriptableObject.CreateInstance(); api.RegisterCallbacks(listener); CompilationPipeline.assemblyCompilationFinished += OnAssemblyCompilationFinished; } } public static void OnAssemblyCompilationFinished(string assembly, CompilerMessage[] messages) { bool checkCompileErrors = RecompileScripts.Current == null || RecompileScripts.Current.ExpectScriptCompilationSuccess; if (checkCompileErrors && messages.Any(x => x.type == CompilerMessageType.Error)) { var compilerErrorMessages = messages.Where(x => x.type == CompilerMessageType.Error); var utpMessageReporter = new UtpMessageReporter(new UtpDebugLogger()); utpMessageReporter.ReportAssemblyCompilationErrors(assembly, compilerErrorMessages); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UnityTestProtocolStarter.cs.meta ================================================ fileFormatVersion: 2 guid: 1ac58cb55fc8daf4abd3945a2bbbb0c5 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UtpDebuglogger.cs ================================================ using UnityEngine; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { class UtpDebugLogger : IUtpLogger { public void Log(Message msg) { var msgJson = JsonUtility.ToJson(msg); Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, "\n##utp:{0}", msgJson); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UtpDebuglogger.cs.meta ================================================ fileFormatVersion: 2 guid: d0abdd8cb6b29a24c8ee19626ef741b9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UtpMessageReporter.cs ================================================ using System.Collections.Generic; using System.Linq; using UnityEditor.Compilation; using UnityEditor.TestTools.TestRunner.Api; namespace UnityEditor.TestTools.TestRunner.UnityTestProtocol { internal class UtpMessageReporter : IUtpMessageReporter { public ITestRunnerApiMapper TestRunnerApiMapper; public IUtpLogger Logger; public UtpMessageReporter(IUtpLogger utpLogger) { TestRunnerApiMapper = new TestRunnerApiMapper(); Logger = utpLogger; } public void ReportAssemblyCompilationErrors(string assembly, IEnumerable errorCompilerMessages) { var compilationErrorMessage = new AssemblyCompilationErrorsMessage { assembly = assembly, errors = errorCompilerMessages.Select(x => x.message).ToArray() }; Logger.Log(compilationErrorMessage); } public void ReportTestRunStarted(ITestAdaptor testsToRun) { var msg = TestRunnerApiMapper.MapTestToTestPlanMessage(testsToRun); Logger.Log(msg); } public void ReportTestStarted(ITestAdaptor test) { if (test.IsSuite) return; var msg = TestRunnerApiMapper.MapTestToTestStartedMessage(test); Logger.Log(msg); } public void ReportTestFinished(ITestResultAdaptor result) { if (result.Test.IsSuite) return; var msg = TestRunnerApiMapper.TestResultToTestFinishedMessage(result); Logger.Log(msg); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol/UtpMessageReporter.cs.meta ================================================ fileFormatVersion: 2 guid: ebcc5f899d9277642868aeda9a17cbaf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner/UnityTestProtocol.meta ================================================ fileFormatVersion: 2 guid: 936c6340f3468444ebb1785b4c311126 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEditor.TestRunner.meta ================================================ fileFormatVersion: 2 guid: 95cdf27b47eb82747ba9e51f41e72a35 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("UnityEngine.TestRunner")] [assembly: InternalsVisibleTo("UnityEditor.TestRunner")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("Unity.PerformanceTesting")] [assembly: InternalsVisibleTo("Unity.PerformanceTesting.Editor")] [assembly: InternalsVisibleTo("Assembly-CSharp-testable")] [assembly: InternalsVisibleTo("Assembly-CSharp-Editor-testable")] [assembly: InternalsVisibleTo("UnityEngine.TestRunner.Tests")] [assembly: InternalsVisibleTo("UnityEditor.TestRunner.Tests")] [assembly: InternalsVisibleTo("Unity.PackageManagerUI.Editor")] [assembly: AssemblyVersion("1.0.0")] ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/AssemblyInfo.cs.meta ================================================ fileFormatVersion: 2 guid: cc22cc13b69c1094c85e176c008b9ef8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/AllocatingGCMemoryConstraint.cs ================================================ using System; using NUnit.Framework; using NUnit.Framework.Constraints; using UnityEngine.Profiling; namespace UnityEngine.TestTools.Constraints { public class AllocatingGCMemoryConstraint : Constraint { private class AllocatingGCMemoryResult : ConstraintResult { private readonly int diff; public AllocatingGCMemoryResult(IConstraint constraint, object actualValue, int diff) : base(constraint, actualValue, diff > 0) { this.diff = diff; } public override void WriteMessageTo(MessageWriter writer) { if (diff == 0) writer.WriteMessageLine("The provided delegate did not make any GC allocations."); else writer.WriteMessageLine("The provided delegate made {0} GC allocation(s).", diff); } } private ConstraintResult ApplyTo(Action action, object original) { var recorder = Recorder.Get("GC.Alloc"); // The recorder was created enabled, which means it captured the creation of the Recorder object itself, etc. // Disabling it flushes its data, so that we can retrieve the sample block count and have it correctly account // for these initial allocations. recorder.enabled = false; #if !UNITY_WEBGL recorder.FilterToCurrentThread(); #endif recorder.enabled = true; try { action(); } finally { recorder.enabled = false; #if !UNITY_WEBGL recorder.CollectFromAllThreads(); #endif } return new AllocatingGCMemoryResult(this, original, recorder.sampleBlockCount); } public override ConstraintResult ApplyTo(object obj) { if (obj == null) throw new ArgumentNullException(); TestDelegate d = obj as TestDelegate; if (d == null) throw new ArgumentException(string.Format("The actual value must be a TestDelegate but was {0}", obj.GetType())); return ApplyTo(() => d.Invoke(), obj); } public override ConstraintResult ApplyTo(ActualValueDelegate del) { if (del == null) throw new ArgumentNullException(); return ApplyTo(() => del.Invoke(), del); } public override string Description { get { return "allocates GC memory"; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/AllocatingGCMemoryConstraint.cs.meta ================================================ fileFormatVersion: 2 guid: d09858396dd7adb4bbdb22ea0c8c3a37 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/ConstraintsExtensions.cs ================================================ using NUnit.Framework.Constraints; namespace UnityEngine.TestTools.Constraints { public static class ConstraintExtensions { public static AllocatingGCMemoryConstraint AllocatingGCMemory(this ConstraintExpression chain) { var constraint = new AllocatingGCMemoryConstraint(); chain.Append(constraint); return constraint; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/ConstraintsExtensions.cs.meta ================================================ fileFormatVersion: 2 guid: 68a48d1900320ed458e118415857faf6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/InvalidSignatureException.cs ================================================ using NUnit.Framework; using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools.TestRunner { internal class InvalidSignatureException : ResultStateException { public InvalidSignatureException(string message) : base(message) { } public override ResultState ResultState { get { return ResultState.NotRunnable; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/InvalidSignatureException.cs.meta ================================================ fileFormatVersion: 2 guid: 9650d910fcaefb34cb45f121c1993892 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/Is.cs ================================================ namespace UnityEngine.TestTools.Constraints { public class Is : NUnit.Framework.Is { public static AllocatingGCMemoryConstraint AllocatingGCMemory() { return new AllocatingGCMemoryConstraint(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/Is.cs.meta ================================================ fileFormatVersion: 2 guid: 6d5833966abeadb429de247e4316eef4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogAssert.cs ================================================ using System.Text.RegularExpressions; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestTools { public static class LogAssert { public static void Expect(LogType type, string message) { LogScope.Current.ExpectedLogs.Enqueue(new LogMatch() { LogType = type, Message = message }); } public static void Expect(LogType type, Regex message) { LogScope.Current.ExpectedLogs.Enqueue(new LogMatch() { LogType = type, MessageRegex = message }); } public static void NoUnexpectedReceived() { LogScope.Current.ProcessExpectedLogs(); var isAllLogsHandled = LogScope.Current.IsAllLogsHandled(); if (isAllLogsHandled) { return; } var unhandledLog = LogScope.Current.GetUnhandledLog(); throw new UnhandledLogMessageException(unhandledLog); } public static bool ignoreFailingMessages { get { return LogScope.Current.IgnoreFailingMessages; } set { LogScope.Current.IgnoreFailingMessages = value; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogAssert.cs.meta ================================================ fileFormatVersion: 2 guid: c97b794b51780d349a16826a4c7898d7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/ILogScope.cs ================================================ using System; using System.Collections.Generic; namespace UnityEngine.TestTools.Logging { internal interface ILogScope : IDisposable { List LogEvents { get; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/ILogScope.cs.meta ================================================ fileFormatVersion: 2 guid: 3504aa04cda851b44a65973f9aead6f7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/LogEvent.cs ================================================ namespace UnityEngine.TestTools.Logging { internal class LogEvent { public string Message { get; set; } public string StackTrace { get; set; } public LogType LogType { get; set; } public bool IsHandled { get; set; } public override string ToString() { return string.Format("[{0}] {1}", LogType, Message); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/LogEvent.cs.meta ================================================ fileFormatVersion: 2 guid: 0c56471f08a0f6846afc792f0b4205b9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/LogMatch.cs ================================================ using System; using System.Text.RegularExpressions; namespace UnityEngine.TestTools.Logging { [Serializable] internal class LogMatch { [SerializeField] private bool m_UseRegex; [SerializeField] private string m_Message; [SerializeField] private string m_MessageRegex; [SerializeField] private string m_LogType; public string Message { get { return m_Message; } set { m_Message = value; m_UseRegex = false; } } public Regex MessageRegex { get { if (!m_UseRegex) { return null; } return new Regex(m_MessageRegex); } set { if (value != null) { m_MessageRegex = value.ToString(); m_UseRegex = true; } else { m_MessageRegex = null; m_UseRegex = false; } } } public LogType? LogType { get { if (!string.IsNullOrEmpty(m_LogType)) { return Enum.Parse(typeof(LogType), m_LogType) as LogType ? ; } return null; } set { if (value != null) { m_LogType = value.Value.ToString(); } else { m_LogType = null; } } } public bool Matches(LogEvent log) { if (LogType != null && LogType != log.LogType) { return false; } if (m_UseRegex) { return MessageRegex.IsMatch(log.Message); } else { return Message.Equals(log.Message); } } public override string ToString() { if (m_UseRegex) return string.Format("[{0}] Regex: {1}", LogType, MessageRegex); else return string.Format("[{0}] {1}", LogType, Message); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/LogMatch.cs.meta ================================================ fileFormatVersion: 2 guid: 9945ffed4692c6044b6d3acf81efd694 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/LogScope.cs ================================================ using System; using System.Collections.Generic; using System.Linq; namespace UnityEngine.TestTools.Logging { internal class LogScope : IDisposable { private bool m_Disposed; private readonly object _lock = new object(); public Queue ExpectedLogs { get; set; } public List AllLogs { get; } public List FailingLogs { get; } public bool IgnoreFailingMessages { get; set; } public bool IsNUnitException { get; private set; } public bool IsNUnitSuccessException { get; private set; } public bool IsNUnitInconclusiveException { get; private set; } public bool IsNUnitIgnoreException { get; private set; } public string NUnitExceptionMessage { get; private set; } private bool m_NeedToProcessLogs; private static List s_ActiveScopes = new List(); internal static LogScope Current { get { if (s_ActiveScopes.Count == 0) throw new InvalidOperationException("No log scope is available"); return s_ActiveScopes[0]; } } internal static bool HasCurrentLogScope() { return s_ActiveScopes.Count > 0; } public LogScope() { AllLogs = new List(); FailingLogs = new List(); ExpectedLogs = new Queue(); IgnoreFailingMessages = false; Activate(); } private void Activate() { s_ActiveScopes.Insert(0, this); RegisterScope(this); Application.logMessageReceivedThreaded -= AddLog; Application.logMessageReceivedThreaded += AddLog; } private void Deactivate() { Application.logMessageReceivedThreaded -= AddLog; s_ActiveScopes.Remove(this); UnregisterScope(this); } private static void RegisterScope(LogScope logScope) { Application.logMessageReceivedThreaded += logScope.AddLog; } private static void UnregisterScope(LogScope logScope) { Application.logMessageReceivedThreaded -= logScope.AddLog; } public void AddLog(string message, string stacktrace, LogType type) { lock (_lock) { m_NeedToProcessLogs = true; var log = new LogEvent { LogType = type, Message = message, StackTrace = stacktrace, }; AllLogs.Add(log); if (IsNUnitResultStateException(stacktrace, type)) { if (message.StartsWith("SuccessException")) { IsNUnitException = true; IsNUnitSuccessException = true; if (message.StartsWith("SuccessException: ")) { NUnitExceptionMessage = message.Substring("SuccessException: ".Length); return; } } else if (message.StartsWith("InconclusiveException")) { IsNUnitException = true; IsNUnitInconclusiveException = true; if (message.StartsWith("InconclusiveException: ")) { NUnitExceptionMessage = message.Substring("InconclusiveException: ".Length); return; } } else if (message.StartsWith("IgnoreException")) { IsNUnitException = true; IsNUnitIgnoreException = true; if (message.StartsWith("IgnoreException: ")) { NUnitExceptionMessage = message.Substring("IgnoreException: ".Length); return; } } } if (IsFailingLog(type) && !IgnoreFailingMessages) { FailingLogs.Add(log); } } } public bool IsAllLogsHandled() { lock (_lock) { return AllLogs.All(x => x.IsHandled); } } public LogEvent GetUnhandledLog() { lock (_lock) { return AllLogs.First(x => !x.IsHandled); } } private static bool IsNUnitResultStateException(string stacktrace, LogType logType) { if (logType != LogType.Exception) return false; return string.IsNullOrEmpty(stacktrace) || stacktrace.StartsWith("NUnit.Framework.Assert."); } private static bool IsFailingLog(LogType type) { switch (type) { case LogType.Assert: case LogType.Error: case LogType.Exception: return true; default: return false; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (m_Disposed) { return; } m_Disposed = true; if (disposing) { Deactivate(); } } internal bool AnyFailingLogs() { ProcessExpectedLogs(); return FailingLogs.Any(); } internal void ProcessExpectedLogs() { lock (_lock) { if (!m_NeedToProcessLogs || !ExpectedLogs.Any()) return; LogMatch expectedLog = null; foreach (var logEvent in AllLogs) { if (!ExpectedLogs.Any()) break; if (expectedLog == null && ExpectedLogs.Any()) expectedLog = ExpectedLogs.Peek(); if (expectedLog != null && expectedLog.Matches(logEvent)) { ExpectedLogs.Dequeue(); logEvent.IsHandled = true; if (FailingLogs.Any(expectedLog.Matches)) { var failingLog = FailingLogs.First(expectedLog.Matches); FailingLogs.Remove(failingLog); } expectedLog = null; } } m_NeedToProcessLogs = false; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope/LogScope.cs.meta ================================================ fileFormatVersion: 2 guid: 4bbc17b35884fdf468e4b52ae4222882 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/LogScope.meta ================================================ fileFormatVersion: 2 guid: b1d8465ba1376b148bdab58965101f47 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/UnexpectedLogMessageException.cs ================================================ using NUnit.Framework; using NUnit.Framework.Interfaces; using UnityEngine.TestTools.Logging; namespace UnityEngine.TestTools.TestRunner { internal class UnexpectedLogMessageException : ResultStateException { public LogMatch LogEvent; public UnexpectedLogMessageException(LogMatch log) : base(BuildMessage(log)) { LogEvent = log; } private static string BuildMessage(LogMatch log) { return string.Format("Expected log did not appear: {0}", log); } public override ResultState ResultState { get { return ResultState.Failure; } } public override string StackTrace { get { return null; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/UnexpectedLogMessageException.cs.meta ================================================ fileFormatVersion: 2 guid: 5b2eeca598284bd4abb4a15c30df1576 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/UnhandledLogMessageException.cs ================================================ using NUnit.Framework; using NUnit.Framework.Interfaces; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.Utils; namespace UnityEngine.TestTools.TestRunner { internal class UnhandledLogMessageException : ResultStateException { public LogEvent LogEvent; private readonly string m_CustomStackTrace; public UnhandledLogMessageException(LogEvent log) : base(BuildMessage(log)) { LogEvent = log; m_CustomStackTrace = StackTraceFilter.Filter(log.StackTrace); } private static string BuildMessage(LogEvent log) { return string.Format("Unhandled log message: '{0}'. Use UnityEngine.TestTools.LogAssert.Expect", log); } public override ResultState ResultState { get { return ResultState.Failure; } } public override string StackTrace { get { return m_CustomStackTrace; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/UnhandledLogMessageException.cs.meta ================================================ fileFormatVersion: 2 guid: a8ed4063f2beecd41a234a582202f3c4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/UnityTestTimeoutException.cs ================================================ using NUnit.Framework; using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools.TestRunner { internal class UnityTestTimeoutException : ResultStateException { public UnityTestTimeoutException(int timeout) : base(BuildMessage(timeout)) { } private static string BuildMessage(int timeout) { return string.Format("UnityTest exceeded Timeout value of {0}ms", timeout); } public override ResultState ResultState { get { return ResultState.Failure; } } public override string StackTrace { get { return ""; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions/UnityTestTimeoutException.cs.meta ================================================ fileFormatVersion: 2 guid: ffb335140c799c4408411d81789fb05c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Assertions.meta ================================================ fileFormatVersion: 2 guid: 1ad55f5ad04d1d045a1f287409c650dd folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/ActionDelegator.cs ================================================ using System; using System.Linq; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestTools.NUnitExtensions { /// /// This class delegates actions from the NUnit thread that should be executed on the main thread. /// NUnit thread calls Delegate which blocks the execution on the thread until the action is executed. /// The main thread will poll for awaiting actions (HasAction) and invoke them (Execute). /// Once the action is executed, the main thread releases the lock and executino on the NUnit thread is continued. /// internal class ActionDelegator : BaseDelegator { private Func m_Action; public object Delegate(Action action) { return Delegate(() => { action(); return null; }); } public object Delegate(Func action) { if (m_Aborted) { return null; } AssertState(); m_Context = UnityTestExecutionContext.CurrentContext; m_Signal.Reset(); m_Action = action; WaitForSignal(); return HandleResult(); } private void AssertState() { if (m_Action != null) { throw new Exception("Action not executed yet"); } } public bool HasAction() { return m_Action != null; } public void Execute(LogScope logScope) { try { SetCurrentTestContext(); m_Result = m_Action(); if (logScope.AnyFailingLogs()) { var failingLog = logScope.FailingLogs.First(); throw new UnhandledLogMessageException(failingLog); } if (logScope.ExpectedLogs.Any()) throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek()); } catch (Exception e) { m_Exception = e; } finally { m_Action = null; m_Signal.Set(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/ActionDelegator.cs.meta ================================================ fileFormatVersion: 2 guid: 4f939b9e23a0946439b812551e07ac81 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs ================================================ using System; using System.Collections; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestTools { internal class TestEnumerator { private readonly ITestExecutionContext m_Context; private static IEnumerator m_TestEnumerator; public static IEnumerator Enumerator { get { return m_TestEnumerator; } } public TestEnumerator(ITestExecutionContext context, IEnumerator testEnumerator) { m_Context = context; m_TestEnumerator = testEnumerator; } public IEnumerator Execute() { m_Context.CurrentResult.SetResult(ResultState.Success); while (true) { object current = null; try { if (!m_TestEnumerator.MoveNext()) { yield break; } if (!m_Context.CurrentResult.ResultState.Equals(ResultState.Success)) { yield break; } current = m_TestEnumerator.Current; } catch (Exception exception) { m_Context.CurrentResult.RecordException(exception); yield break; } yield return current; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs.meta ================================================ fileFormatVersion: 2 guid: 750aad009559b814dbc27001341fc1c3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityCombinatorialStrategy.cs ================================================ using System.Collections; using System.Collections.Generic; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal.Builders; namespace UnityEngine.TestTools { internal class UnityCombinatorialStrategy : CombinatorialStrategy, ICombiningStrategy { public new IEnumerable GetTestCases(IEnumerable[] sources) { var testCases = base.GetTestCases(sources); foreach (var testCase in testCases) { testCase.GetType().GetProperty("ExpectedResult").SetValue(testCase, new object(), null); } return testCases; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityCombinatorialStrategy.cs.meta ================================================ fileFormatVersion: 2 guid: 7af6ac3e6b51b8d4aab04adc85b8de2f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityPlatformAttribute.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestTools { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public class UnityPlatformAttribute : NUnitAttribute, IApplyToTest { public RuntimePlatform[] include { get; set; } public RuntimePlatform[] exclude { get; set; } private string m_skippedReason; public UnityPlatformAttribute() { include = new List().ToArray(); exclude = new List().ToArray(); } public UnityPlatformAttribute(params RuntimePlatform[] include) : this() { this.include = include; } public void ApplyToTest(Test test) { if (test.RunState == RunState.NotRunnable || test.RunState == RunState.Ignored || IsPlatformSupported(Application.platform)) { return; } test.RunState = RunState.Skipped; test.Properties.Add("_SKIPREASON", m_skippedReason); } internal bool IsPlatformSupported(RuntimePlatform testTargetPlatform) { if (include.Any() && !include.Any(x => x == testTargetPlatform)) { m_skippedReason = string.Format("Only supported on {0}", string.Join(", ", include.Select(x => x.ToString()).ToArray())); return false; } if (exclude.Any(x => x == testTargetPlatform)) { m_skippedReason = string.Format("Not supported on {0}", string.Join(", ", include.Select(x => x.ToString()).ToArray())); return false; } return true; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityPlatformAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: 5440c1153b397e14c9c7b1d6eb83b9f9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnitySetUpAttribute.cs ================================================ using System; using NUnit.Framework; namespace UnityEngine.TestTools { [AttributeUsage(AttributeTargets.Method)] public class UnitySetUpAttribute : NUnitAttribute { } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnitySetUpAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: cc6401f13df54ba44bfd7cdc93c7d64d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityTearDownAttribute.cs ================================================ using System; using NUnit.Framework; namespace UnityEngine.TestTools { [AttributeUsage(AttributeTargets.Method)] public class UnityTearDownAttribute : NUnitAttribute { } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityTearDownAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: 600f4b74746dbf944901257f81a8af6d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityTestAttribute.cs ================================================ using System; using NUnit.Framework; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Builders; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { [AttributeUsage(AttributeTargets.Method)] public class UnityTestAttribute : CombiningStrategyAttribute, IWrapSetUpTearDown, ISimpleTestBuilder, IImplyFixture { public UnityTestAttribute() : base(new UnityCombinatorialStrategy(), new ParameterDataSourceProvider()) {} private readonly NUnitTestCaseBuilder _builder = new NUnitTestCaseBuilder(); TestMethod ISimpleTestBuilder.BuildFrom(IMethodInfo method, Test suite) { TestCaseParameters parms = new TestCaseParameters { ExpectedResult = new object(), HasExpectedResult = true }; var t = _builder.BuildTestMethod(method, suite, parms); if (t.parms != null) t.parms.HasExpectedResult = false; return t; } public TestCommand Wrap(TestCommand command) { return new OuterUnityTestActionCommand( new EnumerableSetUpTearDownCommand( new SetUpTearDownCommand( new TestActionCommand( new UnityLogCheckDelegatingCommand( new EnumerableTestMethodCommand((TestMethod)command.Test)))))); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes/UnityTestAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: fedb0f9e5006b1943abae52f52f08a1a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Attributes.meta ================================================ fileFormatVersion: 2 guid: 0cb14878543cf3d4f8472b15f7ecf0e3 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/BaseDelegator.cs ================================================ using System; using System.Threading; using NUnit.Framework.Internal; namespace UnityEngine.TestTools.NUnitExtensions { internal abstract class BaseDelegator { protected ManualResetEvent m_Signal = new ManualResetEvent(false); protected object m_Result; protected Exception m_Exception; protected ITestExecutionContext m_Context; protected bool m_Aborted; protected object HandleResult() { SetCurrentTestContext(); if (m_Exception != null) { var temp = m_Exception; m_Exception = null; throw temp; } var tempResult = m_Result; m_Result = null; return tempResult; } protected void WaitForSignal() { while (!m_Signal.WaitOne(100)) { if (m_Aborted) { m_Aborted = false; Reflect.MethodCallWrapper = null; throw new Exception(); } } } public void Abort() { m_Aborted = true; } protected void SetCurrentTestContext() { var prop = typeof(TestExecutionContext).GetProperty("CurrentContext"); if (prop != null) { prop.SetValue(null, m_Context, null); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/BaseDelegator.cs.meta ================================================ fileFormatVersion: 2 guid: 37cea569bfefafe49a1513c4d7f0e9eb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/BeforeAfterTestCommandBase.cs ================================================ using System; using System.Collections; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestRunner.NUnitExtensions; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestTools { internal abstract class BeforeAfterTestCommandBase : DelegatingTestCommand, IEnumerableTestMethodCommand { private string m_BeforeErrorPrefix; private string m_AfterErrorPrefix; private bool m_SkipYieldAfterActions; protected BeforeAfterTestCommandBase(TestCommand innerCommand, string beforeErrorPrefix, string afterErrorPrefix, bool skipYieldAfterActions = false) : base(innerCommand) { m_BeforeErrorPrefix = beforeErrorPrefix; m_AfterErrorPrefix = afterErrorPrefix; m_SkipYieldAfterActions = skipYieldAfterActions; } protected T[] BeforeActions = new T[0]; protected T[] AfterActions = new T[0]; protected abstract IEnumerator InvokeBefore(T action, Test test, UnityTestExecutionContext context); protected abstract IEnumerator InvokeAfter(T action, Test test, UnityTestExecutionContext context); protected abstract BeforeAfterTestCommandState GetState(UnityTestExecutionContext context); public IEnumerable ExecuteEnumerable(ITestExecutionContext context) { var unityContext = (UnityTestExecutionContext)context; var state = GetState(unityContext); if (state == null) { // We do not expect a state to exist in playmode state = ScriptableObject.CreateInstance(); } state.ApplyTestResult(context.CurrentResult); while (state.NextBeforeStepIndex < BeforeActions.Length) { var action = BeforeActions[state.NextBeforeStepIndex]; var enumerator = InvokeBefore(action, Test, unityContext); ActivePcHelper.SetEnumeratorPC(enumerator, state.NextBeforeStepPc); using (var logScope = new LogScope()) { while (true) { try { if (!enumerator.MoveNext()) { break; } } catch (Exception ex) { state.TestHasRun = true; context.CurrentResult.RecordPrefixedException(m_BeforeErrorPrefix, ex); state.StoreTestResult(context.CurrentResult); break; } state.NextBeforeStepPc = ActivePcHelper.GetEnumeratorPC(enumerator); state.StoreTestResult(context.CurrentResult); if (m_SkipYieldAfterActions) { break; } else { yield return enumerator.Current; } } if (logScope.AnyFailingLogs()) { state.TestHasRun = true; context.CurrentResult.RecordPrefixedError(m_BeforeErrorPrefix, new UnhandledLogMessageException(logScope.FailingLogs.First()).Message); state.StoreTestResult(context.CurrentResult); } } state.NextBeforeStepIndex++; state.NextBeforeStepPc = 0; } if (!state.TestHasRun) { if (innerCommand is IEnumerableTestMethodCommand) { var executeEnumerable = ((IEnumerableTestMethodCommand)innerCommand).ExecuteEnumerable(context); foreach (var iterator in executeEnumerable) { state.StoreTestResult(context.CurrentResult); yield return iterator; } } else { context.CurrentResult = innerCommand.Execute(context); state.StoreTestResult(context.CurrentResult); } state.TestHasRun = true; } while (state.NextAfterStepIndex < AfterActions.Length) { state.TestAfterStarted = true; var action = AfterActions[state.NextAfterStepIndex]; var enumerator = InvokeAfter(action, Test, unityContext); ActivePcHelper.SetEnumeratorPC(enumerator, state.NextAfterStepPc); using (var logScope = new LogScope()) { while (true) { try { if (!enumerator.MoveNext()) { break; } } catch (Exception ex) { context.CurrentResult.RecordPrefixedException(m_AfterErrorPrefix, ex); state.StoreTestResult(context.CurrentResult); break; } state.NextAfterStepPc = ActivePcHelper.GetEnumeratorPC(enumerator); state.StoreTestResult(context.CurrentResult); if (m_SkipYieldAfterActions) { break; } else { yield return enumerator.Current; } } if (logScope.AnyFailingLogs()) { state.TestHasRun = true; context.CurrentResult.RecordPrefixedError(m_AfterErrorPrefix, new UnhandledLogMessageException(logScope.FailingLogs.First()).Message); state.StoreTestResult(context.CurrentResult); } } state.NextAfterStepIndex++; state.NextAfterStepPc = 0; } state.Reset(); } public override TestResult Execute(ITestExecutionContext context) { throw new NotImplementedException("Use ExecuteEnumerable"); } private static TestCommandPcHelper pcHelper; internal static TestCommandPcHelper ActivePcHelper { get { if (pcHelper == null) { pcHelper = new TestCommandPcHelper(); } return pcHelper; } set { pcHelper = value; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/BeforeAfterTestCommandBase.cs.meta ================================================ fileFormatVersion: 2 guid: cbbca1d8a0434be4bbc7f165523763ac MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/BeforeAfterTestCommandState.cs ================================================ using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestTools { internal class BeforeAfterTestCommandState : ScriptableObject { public int NextBeforeStepIndex; public int NextBeforeStepPc; public int NextAfterStepIndex; public int NextAfterStepPc; public bool TestHasRun; public TestStatus CurrentTestResultStatus; public string CurrentTestResultLabel; public FailureSite CurrentTestResultSite; public string CurrentTestMessage; public string CurrentTestStrackTrace; public bool TestAfterStarted; public void Reset() { NextBeforeStepIndex = 0; NextBeforeStepPc = 0; NextAfterStepIndex = 0; NextAfterStepPc = 0; TestHasRun = false; CurrentTestResultStatus = TestStatus.Inconclusive; CurrentTestResultLabel = null; CurrentTestResultSite = default(FailureSite); CurrentTestMessage = null; CurrentTestStrackTrace = null; TestAfterStarted = false; } public void StoreTestResult(TestResult result) { CurrentTestResultStatus = result.ResultState.Status; CurrentTestResultLabel = result.ResultState.Label; CurrentTestResultSite = result.ResultState.Site; CurrentTestMessage = result.Message; CurrentTestStrackTrace = result.StackTrace; } public void ApplyTestResult(TestResult result) { result.SetResult(new ResultState(CurrentTestResultStatus, CurrentTestResultLabel, CurrentTestResultSite), CurrentTestMessage, CurrentTestStrackTrace); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/BeforeAfterTestCommandState.cs.meta ================================================ fileFormatVersion: 2 guid: 7f65567c9026afb4db5de3355accc636 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/EnumerableApplyChangesToContextCommand.cs ================================================ using System.Collections; using System.Collections.Generic; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { internal class EnumerableApplyChangesToContextCommand : ApplyChangesToContextCommand, IEnumerableTestMethodCommand { public EnumerableApplyChangesToContextCommand(TestCommand innerCommand, IEnumerable changes) : base(innerCommand, changes) { } public IEnumerable ExecuteEnumerable(ITestExecutionContext context) { ApplyChanges(context); if (innerCommand is IEnumerableTestMethodCommand) { var executeEnumerable = ((IEnumerableTestMethodCommand)innerCommand).ExecuteEnumerable(context); foreach (var iterator in executeEnumerable) { yield return iterator; } } else { context.CurrentResult = innerCommand.Execute(context); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/EnumerableApplyChangesToContextCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 3b4429eff9fcffb48b006e8edcc90338 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/EnumerableSetUpTearDownCommand.cs ================================================ using System; using System.Collections; using System.Linq; using System.Reflection; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { internal class EnumerableSetUpTearDownCommand : BeforeAfterTestCommandBase { public EnumerableSetUpTearDownCommand(TestCommand innerCommand) : base(innerCommand, "SetUp", "TearDown") { if (Test.TypeInfo.Type != null) { BeforeActions = GetMethodsWithAttributeFromFixture(Test.TypeInfo.Type, typeof(UnitySetUpAttribute)); AfterActions = GetMethodsWithAttributeFromFixture(Test.TypeInfo.Type, typeof(UnityTearDownAttribute)).Reverse().ToArray(); } } private static MethodInfo[] GetMethodsWithAttributeFromFixture(Type fixtureType, Type setUpType) { MethodInfo[] methodsWithAttribute = Reflect.GetMethodsWithAttribute(fixtureType, setUpType, true); return methodsWithAttribute.Where(x => x.ReturnType == typeof(IEnumerator)).ToArray(); } protected override IEnumerator InvokeBefore(MethodInfo action, Test test, UnityTestExecutionContext context) { return (IEnumerator)Reflect.InvokeMethod(action, context.TestObject); } protected override IEnumerator InvokeAfter(MethodInfo action, Test test, UnityTestExecutionContext context) { return (IEnumerator)Reflect.InvokeMethod(action, context.TestObject); } protected override BeforeAfterTestCommandState GetState(UnityTestExecutionContext context) { return context.SetUpTearDownState; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/EnumerableSetUpTearDownCommand.cs.meta ================================================ fileFormatVersion: 2 guid: dd85a35169d313840a0874aea1a28629 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/EnumerableTestMethodCommand.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Execution; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestTools { internal class EnumerableTestMethodCommand : TestCommand, IEnumerableTestMethodCommand { private readonly TestMethod testMethod; public EnumerableTestMethodCommand(TestMethod testMethod) : base(testMethod) { this.testMethod = testMethod; } public IEnumerable ExecuteEnumerable(ITestExecutionContext context) { yield return null; var currentExecutingTestEnumerator = new TestEnumeratorWrapper(testMethod).GetEnumerator(context); if (currentExecutingTestEnumerator != null) { var testEnumeraterYieldInstruction = new TestEnumerator(context, currentExecutingTestEnumerator); yield return testEnumeraterYieldInstruction; var enumerator = testEnumeraterYieldInstruction.Execute(); var executingEnumerator = ExecuteEnumerableAndRecordExceptions(enumerator, context); while (executingEnumerator.MoveNext()) { yield return executingEnumerator.Current; } } else { if (context.CurrentResult.ResultState != ResultState.Ignored) { context.CurrentResult.SetResult(ResultState.Success); } } } private static IEnumerator ExecuteEnumerableAndRecordExceptions(IEnumerator enumerator, ITestExecutionContext context) { while (true) { try { if (!enumerator.MoveNext()) { break; } } catch (Exception ex) { context.CurrentResult.RecordException(ex); break; } if (enumerator.Current is IEnumerator) { var current = (IEnumerator)enumerator.Current; yield return ExecuteEnumerableAndRecordExceptions(current, context); } else { yield return enumerator.Current; } } } public override TestResult Execute(ITestExecutionContext context) { throw new NotImplementedException("Use ExecuteEnumerable"); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/EnumerableTestMethodCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 19a6f000f81e24c4a826c1abd43e77c7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/ImmediateEnumerableCommand.cs ================================================ using System; using System.Collections; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { internal class ImmediateEnumerableCommand : DelegatingTestCommand { public ImmediateEnumerableCommand(TestCommand innerCommand) : base(innerCommand) { } public override TestResult Execute(ITestExecutionContext context) { if (innerCommand is IEnumerableTestMethodCommand) { var executeEnumerable = ((IEnumerableTestMethodCommand)innerCommand).ExecuteEnumerable(context); foreach (var iterator in executeEnumerable) { if (iterator != null) { throw new Exception("Only null can be yielded at this point."); } } return context.CurrentResult; } return innerCommand.Execute(context); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/ImmediateEnumerableCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 8349e42a2b30c7a4abd8678c203428ba MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/OuterUnityTestActionCommand.cs ================================================ using System.Collections; using System.Collections.Generic; using System.Reflection; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { internal class OuterUnityTestActionCommand : BeforeAfterTestCommandBase { public OuterUnityTestActionCommand(TestCommand innerCommand) : base(innerCommand, "BeforeTest", "AfterTest") { if (Test.TypeInfo.Type != null) { BeforeActions = GetUnityTestActionsFromMethod(Test.Method.MethodInfo); AfterActions = BeforeActions; } } private static IOuterUnityTestAction[] GetUnityTestActionsFromMethod(MethodInfo method) { var attributes = method.GetCustomAttributes(false); List actions = new List(); foreach (var attribute in attributes) { if (attribute is IOuterUnityTestAction) actions.Add(attribute as IOuterUnityTestAction); } return actions.ToArray(); } protected override IEnumerator InvokeBefore(IOuterUnityTestAction action, Test test, UnityTestExecutionContext context) { return action.BeforeTest(test); } protected override IEnumerator InvokeAfter(IOuterUnityTestAction action, Test test, UnityTestExecutionContext context) { return action.AfterTest(test); } protected override BeforeAfterTestCommandState GetState(UnityTestExecutionContext context) { return context.OuterUnityTestActionState; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/OuterUnityTestActionCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 0d4fc309a0784294c8ab658b53b12320 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/SetUpTearDownCommand.cs ================================================ using System; using System.Collections; using System.Linq; using System.Reflection; using NUnit.Framework; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Execution; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { internal class SetUpTearDownCommand : BeforeAfterTestCommandBase { public SetUpTearDownCommand(TestCommand innerCommand) : base(innerCommand, "SetUp", "TearDown", true) { if (Test.TypeInfo.Type != null) { BeforeActions = GetMethodsWithAttributeFromFixture(Test.TypeInfo.Type, typeof(SetUpAttribute)); AfterActions = GetMethodsWithAttributeFromFixture(Test.TypeInfo.Type, typeof(TearDownAttribute)).Reverse().ToArray(); } } private static MethodInfo[] GetMethodsWithAttributeFromFixture(Type fixtureType, Type setUpType) { MethodInfo[] methodsWithAttribute = Reflect.GetMethodsWithAttribute(fixtureType, setUpType, true); return methodsWithAttribute.Where(x => x.ReturnType == typeof(void)).ToArray(); } protected override IEnumerator InvokeBefore(MethodInfo action, Test test, UnityTestExecutionContext context) { Reflect.InvokeMethod(action, context.TestObject); yield return null; } protected override IEnumerator InvokeAfter(MethodInfo action, Test test, UnityTestExecutionContext context) { Reflect.InvokeMethod(action, context.TestObject); yield return null; } protected override BeforeAfterTestCommandState GetState(UnityTestExecutionContext context) { return null; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/SetUpTearDownCommand.cs.meta ================================================ fileFormatVersion: 2 guid: e0db3f3921670cd4ca2e925737c3fba4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/TestActionCommand.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using NUnit.Framework; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools { internal class TestActionCommand : BeforeAfterTestCommandBase { public TestActionCommand(TestCommand innerCommand) : base(innerCommand, "BeforeTest", "AfterTest", true) { if (Test.TypeInfo.Type != null) { BeforeActions = GetTestActionsFromMethod(Test.Method.MethodInfo); AfterActions = BeforeActions; } } private static ITestAction[] GetTestActionsFromMethod(MethodInfo method) { var attributes = method.GetCustomAttributes(false); List actions = new List(); foreach (var attribute in attributes) { if (attribute is ITestAction) actions.Add(attribute as ITestAction); } return actions.ToArray(); } protected override IEnumerator InvokeBefore(ITestAction action, Test test, UnityTestExecutionContext context) { action.BeforeTest(test); yield return null; } protected override IEnumerator InvokeAfter(ITestAction action, Test test, UnityTestExecutionContext context) { action.AfterTest(test); yield return null; } protected override BeforeAfterTestCommandState GetState(UnityTestExecutionContext context) { return null; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/TestActionCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 2de8ba3b840049641897e0da7ce1d5cd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/TestCommandPcHelper.cs ================================================ using System; using System.Collections; namespace UnityEngine.TestTools { internal class TestCommandPcHelper { public virtual void SetEnumeratorPC(IEnumerator enumerator, int pc) { // Noop implementation used in playmode. } public virtual int GetEnumeratorPC(IEnumerator enumerator) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands/TestCommandPcHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 33e6b78c96bb0694e96383e3c56b7b54 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Commands.meta ================================================ fileFormatVersion: 2 guid: 6b72875690e0f7343911e06af3145bd5 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/ConstructDelegator.cs ================================================ using System; using System.Linq; using NUnit.Framework.Internal; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestTools.NUnitExtensions { /// /// Specialization of BaseDelegator that makes sure objects are created on the MainThread. /// It also deals with ScriptableObjects so that tests can survive assembly reload. /// internal class ConstructDelegator { private Type m_RequestedType; private object[] m_Arguments; private ScriptableObject m_CurrentRunningTest; private readonly IStateSerializer m_StateSerializer; protected Exception m_Exception; protected object m_Result; protected ITestExecutionContext m_Context; public ConstructDelegator(IStateSerializer stateSerializer) { m_StateSerializer = stateSerializer; } protected object HandleResult() { SetCurrentTestContext(); if (m_Exception != null) { var temp = m_Exception; m_Exception = null; throw temp; } var tempResult = m_Result; m_Result = null; return tempResult; } protected void SetCurrentTestContext() { var prop = typeof(UnityTestExecutionContext).GetProperty("CurrentContext"); if (prop != null) { prop.SetValue(null, m_Context, null); } } public object Delegate(Type type, object[] arguments) { AssertState(); m_Context = UnityTestExecutionContext.CurrentContext; m_RequestedType = type; m_Arguments = arguments; using (var logScope = new LogScope()) { Execute(logScope); } return HandleResult(); } private void AssertState() { if (m_RequestedType != null) { throw new Exception("Constructor not executed yet"); } } public bool HasAction() { return m_RequestedType != null; } public void Execute(LogScope logScope) { try { if (typeof(ScriptableObject).IsAssignableFrom(m_RequestedType)) { if (m_CurrentRunningTest != null && m_RequestedType != m_CurrentRunningTest.GetType()) { DestroyCurrentTestObjectIfExists(); } if (m_CurrentRunningTest == null) { if (m_StateSerializer.CanRestoreFromScriptableObject(m_RequestedType)) { m_CurrentRunningTest = m_StateSerializer.RestoreScriptableObjectInstance(); } else { m_CurrentRunningTest = ScriptableObject.CreateInstance(m_RequestedType); } } m_Result = m_CurrentRunningTest; } else { DestroyCurrentTestObjectIfExists(); m_Result = Activator.CreateInstance(m_RequestedType, m_Arguments); if (m_StateSerializer.CanRestoreFromJson(m_RequestedType)) { m_StateSerializer.RestoreClassFromJson(ref m_Result); } } if (logScope.AnyFailingLogs()) { var failingLog = logScope.FailingLogs.First(); throw new UnhandledLogMessageException(failingLog); } if (logScope.ExpectedLogs.Any()) throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek()); } catch (Exception e) { m_Exception = e; } finally { m_RequestedType = null; m_Arguments = null; } } public void DestroyCurrentTestObjectIfExists() { if (m_CurrentRunningTest == null) return; Object.DestroyImmediate(m_CurrentRunningTest); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/ConstructDelegator.cs.meta ================================================ fileFormatVersion: 2 guid: b42e1db66fe9c634798674cb9e1df2ca MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Filters/AssemblyNameFilter.cs ================================================ using System; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal.Filters; namespace UnityEngine.TestRunner.NUnitExtensions.Filters { internal class AssemblyNameFilter : ValueMatchFilter { public AssemblyNameFilter(string assemblyName) : base(assemblyName) {} public override bool Match(ITest test) { string assemblyName = string.Empty; //Assembly fullname is in the format "Assembly-name, meta data ...", so extract the name by looking for the comma if (test.TypeInfo != null && test.TypeInfo.Assembly != null && test.TypeInfo.FullName != null) assemblyName = test.TypeInfo.Assembly.FullName.Substring(0, test.TypeInfo.Assembly.FullName.IndexOf(',')).TrimEnd(','); return ExpectedValue.Equals(assemblyName, StringComparison.OrdinalIgnoreCase); } protected override string ElementName { get { return "id"; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Filters/AssemblyNameFilter.cs.meta ================================================ fileFormatVersion: 2 guid: 91319408591cec1478efd3c62f9f418a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Filters/CategoryFilterExtended.cs ================================================ using System.Collections; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Filters; namespace UnityEngine.TestRunner.NUnitExtensions.Filters { internal class CategoryFilterExtended : CategoryFilter { public static string k_DefaultCategory = "Uncategorized"; public CategoryFilterExtended(string name) : base(name) { } public override bool Match(ITest test) { IList testCategories = test.Properties[PropertyNames.Category].Cast().ToList(); if (test is TestMethod) { // Do not count tests with no attribute as Uncategorized if test fixture class has at least one attribute // The test inherits the attribute from the test fixture IList fixtureCategories = test.Parent.Properties[PropertyNames.Category].Cast().ToList(); if (fixtureCategories.Count > 0) return false; } if (testCategories.Count == 0 && ExpectedValue == k_DefaultCategory && test is TestMethod) return true; return base.Match(test); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Filters/CategoryFilterExtended.cs.meta ================================================ fileFormatVersion: 2 guid: ebeedaa04bb53e24ba2e7fb6745e3fd3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Filters.meta ================================================ fileFormatVersion: 2 guid: c3de99f9efc582a48995bc8e8c2df418 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/IStateSerializer.cs ================================================ using System; namespace UnityEngine.TestTools.NUnitExtensions { internal interface IStateSerializer { ScriptableObject RestoreScriptableObjectInstance(); void RestoreClassFromJson(ref object instance); bool CanRestoreFromJson(Type requestedType); bool CanRestoreFromScriptableObject(Type requestedType); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/IStateSerializer.cs.meta ================================================ fileFormatVersion: 2 guid: 5f875a14565308a40a5262d2504da705 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/CompositeWorkItem.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Execution; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class CompositeWorkItem : UnityWorkItem { private readonly TestSuite _suite; private readonly TestSuiteResult _suiteResult; private readonly ITestFilter _childFilter; private TestCommand _setupCommand; private TestCommand _teardownCommand; public List Children { get; private set; } private int _countOrder; private CountdownEvent _childTestCountdown; public CompositeWorkItem(TestSuite suite, ITestFilter childFilter, WorkItemFactory factory) : base(suite, factory) { _suite = suite; _suiteResult = Result as TestSuiteResult; _childFilter = childFilter; _countOrder = 0; } protected override IEnumerable PerformWork() { InitializeSetUpAndTearDownCommands(); if (UnityTestExecutionContext.CurrentContext != null && m_DontRunRestoringResult && EditModeTestCallbacks.RestoringTestContext != null) { EditModeTestCallbacks.RestoringTestContext(); } if (!CheckForCancellation()) if (Test.RunState == RunState.Explicit && !_childFilter.IsExplicitMatch(Test)) SkipFixture(ResultState.Explicit, GetSkipReason(), null); else switch (Test.RunState) { default: case RunState.Runnable: case RunState.Explicit: Result.SetResult(ResultState.Success); CreateChildWorkItems(); if (Children.Count > 0) { if (!m_DontRunRestoringResult) { //This is needed to give the editor a chance to go out of playmode if needed before creating objects. //If we do not, the objects could be automatically destroyed when exiting playmode and could result in errors later on yield return null; PerformOneTimeSetUp(); } if (!CheckForCancellation()) { switch (Result.ResultState.Status) { case TestStatus.Passed: foreach (var child in RunChildren()) { if (CheckForCancellation()) { yield break; } yield return child; } break; case TestStatus.Skipped: case TestStatus.Inconclusive: case TestStatus.Failed: SkipChildren(_suite, Result.ResultState.WithSite(FailureSite.Parent), "OneTimeSetUp: " + Result.Message); break; } } if (Context.ExecutionStatus != TestExecutionStatus.AbortRequested && !m_DontRunRestoringResult) { PerformOneTimeTearDown(); } } break; case RunState.Skipped: SkipFixture(ResultState.Skipped, GetSkipReason(), null); break; case RunState.Ignored: SkipFixture(ResultState.Ignored, GetSkipReason(), null); break; case RunState.NotRunnable: SkipFixture(ResultState.NotRunnable, GetSkipReason(), GetProviderStackTrace()); break; } if (!ResultedInDomainReload) { WorkItemComplete(); } } private bool CheckForCancellation() { if (Context.ExecutionStatus != TestExecutionStatus.Running) { Result.SetResult(ResultState.Cancelled, "Test cancelled by user"); return true; } return false; } private void InitializeSetUpAndTearDownCommands() { List setUpTearDownItems = _suite.TypeInfo != null ? CommandBuilder.BuildSetUpTearDownList(_suite.TypeInfo.Type, typeof(OneTimeSetUpAttribute), typeof(OneTimeTearDownAttribute)) : new List(); var actionItems = new List(); foreach (ITestAction action in Actions) { bool applyToSuite = (action.Targets & ActionTargets.Suite) == ActionTargets.Suite || action.Targets == ActionTargets.Default && !(Test is ParameterizedMethodSuite); bool applyToTest = (action.Targets & ActionTargets.Test) == ActionTargets.Test && !(Test is ParameterizedMethodSuite); if (applyToSuite) actionItems.Add(new TestActionItem(action)); if (applyToTest) Context.UpstreamActions.Add(action); } _setupCommand = CommandBuilder.MakeOneTimeSetUpCommand(_suite, setUpTearDownItems, actionItems); _teardownCommand = CommandBuilder.MakeOneTimeTearDownCommand(_suite, setUpTearDownItems, actionItems); } private void PerformOneTimeSetUp() { var logScope = new LogScope(); try { _setupCommand.Execute(Context); } catch (Exception ex) { if (ex is NUnitException || ex is TargetInvocationException) ex = ex.InnerException; Result.RecordException(ex, FailureSite.SetUp); } if (logScope.AnyFailingLogs()) { Result.RecordException(new UnhandledLogMessageException(logScope.FailingLogs.First())); } logScope.Dispose(); } private IEnumerable RunChildren() { int childCount = Children.Count; if (childCount == 0) throw new InvalidOperationException("RunChildren called but item has no children"); _childTestCountdown = new CountdownEvent(childCount); foreach (UnityWorkItem child in Children) { if (CheckForCancellation()) { yield break; } var unityTestExecutionContext = new UnityTestExecutionContext(Context); child.InitializeContext(unityTestExecutionContext); var enumerable = child.Execute().GetEnumerator(); while (true) { if (!enumerable.MoveNext()) { break; } ResultedInDomainReload |= child.ResultedInDomainReload; yield return enumerable.Current; } _suiteResult.AddResult(child.Result); childCount--; } if (childCount > 0) { while (childCount-- > 0) CountDownChildTest(); } } private void CreateChildWorkItems() { Children = new List(); var testSuite = _suite; foreach (ITest test in testSuite.Tests) { if (_childFilter.Pass(test)) { var child = m_Factory.Create(test, _childFilter); if (test.Properties.ContainsKey(PropertyNames.Order)) { Children.Insert(0, child); _countOrder++; } else { Children.Add(child); } } } if (_countOrder != 0) SortChildren(); } private class UnityWorkItemOrderComparer : IComparer { public int Compare(UnityWorkItem x, UnityWorkItem y) { var xKey = int.MaxValue; var yKey = int.MaxValue; if (x.Test.Properties.ContainsKey(PropertyNames.Order)) xKey = (int)x.Test.Properties[PropertyNames.Order][0]; if (y.Test.Properties.ContainsKey(PropertyNames.Order)) yKey = (int)y.Test.Properties[PropertyNames.Order][0]; return xKey.CompareTo(yKey); } } private void SortChildren() { Children.Sort(0, _countOrder, new UnityWorkItemOrderComparer()); } private void SkipFixture(ResultState resultState, string message, string stackTrace) { Result.SetResult(resultState.WithSite(FailureSite.SetUp), message, StackFilter.Filter(stackTrace)); SkipChildren(_suite, resultState.WithSite(FailureSite.Parent), "OneTimeSetUp: " + message); } private void SkipChildren(TestSuite suite, ResultState resultState, string message) { foreach (Test child in suite.Tests) { if (_childFilter.Pass(child)) { Context.Listener.TestStarted(child); TestResult childResult = child.MakeTestResult(); childResult.SetResult(resultState, message); _suiteResult.AddResult(childResult); if (child.IsSuite) SkipChildren((TestSuite)child, resultState, message); Context.Listener.TestFinished(childResult); } } } private void PerformOneTimeTearDown() { _teardownCommand.Execute(Context); } private string GetSkipReason() { return (string)Test.Properties.Get(PropertyNames.SkipReason); } private string GetProviderStackTrace() { return (string)Test.Properties.Get(PropertyNames.ProviderStackTrace); } private void CountDownChildTest() { _childTestCountdown.Signal(); if (_childTestCountdown.CurrentCount == 0) { if (Context.ExecutionStatus != TestExecutionStatus.AbortRequested) PerformOneTimeTearDown(); foreach (var childResult in _suiteResult.Children) if (childResult.ResultState == ResultState.Cancelled) { this.Result.SetResult(ResultState.Cancelled, "Cancelled by user"); break; } WorkItemComplete(); } } public override void Cancel(bool force) { if (Children == null) return; foreach (var child in Children) { var ctx = child.Context; if (ctx != null) ctx.ExecutionStatus = force ? TestExecutionStatus.AbortRequested : TestExecutionStatus.StopRequested; if (child.State == WorkItemState.Running) child.Cancel(force); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/CompositeWorkItem.cs.meta ================================================ fileFormatVersion: 2 guid: 110d5035a36a6a34580fb65bb40cd78f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/CoroutineTestWorkItem.cs ================================================ using System; using System.Collections; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Execution; using UnityEngine.TestTools.Utils; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class CoroutineTestWorkItem : UnityWorkItem { private static MonoBehaviour m_MonoBehaviourCoroutineRunner; private TestCommand m_Command; public static MonoBehaviour monoBehaviourCoroutineRunner { get { if (m_MonoBehaviourCoroutineRunner == null) { throw new NullReferenceException("MonoBehaviour coroutine runner not set"); } return m_MonoBehaviourCoroutineRunner; } set { m_MonoBehaviourCoroutineRunner = value; } } public CoroutineTestWorkItem(TestMethod test, ITestFilter filter) : base(test, null) { m_Command = test.RunState == RunState.Runnable || test.RunState == RunState.Explicit && filter.IsExplicitMatch(test) ? CommandBuilder.MakeTestCommand(test) : CommandBuilder.MakeSkipCommand(test); } protected override IEnumerable PerformWork() { if (m_Command is SkipCommand) { m_Command.Execute(Context); Result = Context.CurrentResult; WorkItemComplete(); yield break; } if (m_Command is ApplyChangesToContextCommand) { var applyChangesToContextCommand = (ApplyChangesToContextCommand)m_Command; applyChangesToContextCommand.ApplyChanges(Context); m_Command = applyChangesToContextCommand.GetInnerCommand(); } var enumerableTestMethodCommand = (IEnumerableTestMethodCommand)m_Command; try { var executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(Context).GetEnumerator(); var coroutineRunner = new CoroutineRunner(monoBehaviourCoroutineRunner, Context); yield return coroutineRunner.HandleEnumerableTest(executeEnumerable); if (coroutineRunner.HasFailedWithTimeout()) { Context.CurrentResult.SetResult(ResultState.Failure, string.Format("Test exceeded Timeout value of {0}ms", Context.TestCaseTimeout)); } while (executeEnumerable.MoveNext()) {} Result = Context.CurrentResult; } finally { WorkItemComplete(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/CoroutineTestWorkItem.cs.meta ================================================ fileFormatVersion: 2 guid: b557515fff172984e8c4400b43f1c631 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/DefaultTestWorkItem.cs ================================================ using System; using System.Collections; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Execution; using UnityEngine.TestTools; using SetUpTearDownCommand = NUnit.Framework.Internal.Commands.SetUpTearDownCommand; using TestActionCommand = NUnit.Framework.Internal.Commands.TestActionCommand; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class EditModeTestCallbacks { public static Action RestoringTestContext { get; set; } } internal class DefaultTestWorkItem : UnityWorkItem { private TestCommand _command; public DefaultTestWorkItem(TestMethod test, ITestFilter filter) : base(test, null) { _command = test.RunState == RunState.Runnable || test.RunState == RunState.Explicit && filter.IsExplicitMatch(test) ? BuildTestCommand(test) : new SkipCommand(test); } private static TestCommand BuildTestCommand(TestMethod test) { var command = (TestCommand)new TestMethodCommand(test); command = new UnityLogCheckDelegatingCommand(command); foreach (var wrapper in test.Method.GetCustomAttributes(true)) { command = wrapper.Wrap(command); if (command == null) { var message = string.Format("IWrapTestMethod implementation '{0}' returned null as command.", wrapper.GetType().FullName); return new FailCommand(test, ResultState.Failure, message); } } command = new TestTools.TestActionCommand(command); command = new TestTools.SetUpTearDownCommand(command); command = new ImmediateEnumerableCommand(command); foreach (var wrapper in test.Method.GetCustomAttributes(true)) { command = wrapper.Wrap(command); if (command == null) { var message = string.Format("IWrapSetUpTearDown implementation '{0}' returned null as command.", wrapper.GetType().FullName); return new FailCommand(test, ResultState.Failure, message); } } command = new EnumerableSetUpTearDownCommand(command); command = new OuterUnityTestActionCommand(command); IApplyToContext[] changes = test.Method.GetCustomAttributes(true); if (changes.Length > 0) { command = new EnumerableApplyChangesToContextCommand(command, changes); } return command; } protected override IEnumerable PerformWork() { if (m_DontRunRestoringResult && EditModeTestCallbacks.RestoringTestContext != null) { EditModeTestCallbacks.RestoringTestContext(); Result = Context.CurrentResult; yield break; } try { if (_command is SkipCommand || _command is FailCommand) { Result = _command.Execute(Context); yield break; } if (!(_command is IEnumerableTestMethodCommand)) { Debug.LogError("Cannot perform work on " + _command.GetType().Name); yield break; } foreach (var workItemStep in ((IEnumerableTestMethodCommand)_command).ExecuteEnumerable(Context)) { ResultedInDomainReload = false; if (workItemStep is IEditModeTestYieldInstruction) { var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)workItemStep; yield return editModeTestYieldInstruction; var enumerator = editModeTestYieldInstruction.Perform(); while (true) { bool moveNext; try { moveNext = enumerator.MoveNext(); } catch (Exception e) { Context.CurrentResult.RecordException(e); break; } if (!moveNext) { break; } yield return null; } } else { yield return workItemStep; } } Result = Context.CurrentResult; } finally { WorkItemComplete(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/DefaultTestWorkItem.cs.meta ================================================ fileFormatVersion: 2 guid: c7cfda246e604b945b12b7afedb094ce MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/FailCommand.cs ================================================ using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class FailCommand : TestCommand { private ResultState m_ResultState; private string m_Message; public FailCommand(Test test, ResultState resultState, string message) : base(test) { m_ResultState = resultState; m_Message = message; } public override TestResult Execute(ITestExecutionContext context) { context.CurrentResult.SetResult(m_ResultState, m_Message); return context.CurrentResult; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/FailCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 68e5dc8bfd5d72647a93b7f2e1da831a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/IEnumerableTestMethodCommand.cs ================================================ using System.Collections; using NUnit.Framework.Internal; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal interface IEnumerableTestMethodCommand { IEnumerable ExecuteEnumerable(ITestExecutionContext context); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/IEnumerableTestMethodCommand.cs.meta ================================================ fileFormatVersion: 2 guid: dbd43d8a3b8122d4e89b055f53382b11 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/PlaymodeWorkItemFactory.cs ================================================ using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class PlaymodeWorkItemFactory : WorkItemFactory { protected override UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest) { return new CoroutineTestWorkItem(method, filter); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/PlaymodeWorkItemFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 7ef6801a8b664544aa9f2ab1bc1f8b60 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/RestoreTestContextAfterDomainReload.cs ================================================ namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class RestoreTestContextAfterDomainReload {} } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/RestoreTestContextAfterDomainReload.cs.meta ================================================ fileFormatVersion: 2 guid: 26721f9940339264fb14bdbfe1290e21 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityLogCheckDelegatingCommand.cs ================================================ using System; using System.Collections; using System.Linq; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.TestRunner; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class UnityLogCheckDelegatingCommand : DelegatingTestCommand, IEnumerableTestMethodCommand { public UnityLogCheckDelegatingCommand(TestCommand innerCommand) : base(innerCommand) {} public override TestResult Execute(ITestExecutionContext context) { var logCollector = new LogScope(); try { innerCommand.Execute(context); if (logCollector.AnyFailingLogs()) { var failingLog = logCollector.FailingLogs.First(); throw new UnhandledLogMessageException(failingLog); } if (logCollector.ExpectedLogs.Any()) { throw new UnexpectedLogMessageException(logCollector.ExpectedLogs.Peek()); } } catch (Exception exception) { context.CurrentResult.RecordException(exception); } logCollector.Dispose(); return context.CurrentResult; } public IEnumerable ExecuteEnumerable(ITestExecutionContext context) { var logCollector = new LogScope(); if (!(innerCommand is IEnumerableTestMethodCommand)) { Execute(context); yield break; } var enumerableTestMethodCommand = (IEnumerableTestMethodCommand)innerCommand; IEnumerable executeEnumerable; try { executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(context); } catch (Exception e) { context.CurrentResult.RecordException(e); yield break; } foreach (var step in executeEnumerable) { try { if (logCollector.AnyFailingLogs()) { var failingLog = logCollector.FailingLogs.First(); throw new UnhandledLogMessageException(failingLog); } } catch (Exception e) { context.CurrentResult.RecordException(e); break; } yield return step; } try { if (logCollector.AnyFailingLogs()) { var failingLog = logCollector.FailingLogs.First(); throw new UnhandledLogMessageException(failingLog); } logCollector.ProcessExpectedLogs(); if (logCollector.ExpectedLogs.Any()) { throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek()); } } catch (Exception exception) { context.CurrentResult.RecordException(exception); } logCollector.Dispose(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityLogCheckDelegatingCommand.cs.meta ================================================ fileFormatVersion: 2 guid: 48230e4e90fb4d14a9d56bddea898413 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityTestAssemblyRunner.cs ================================================ using System.Collections; using System.Collections.Generic; using System.Reflection; using NUnit; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine.TestTools.NUnitExtensions; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal interface IUnityTestAssemblyRunner { ITest LoadedTest { get; } ITestResult Result { get; } bool IsTestLoaded { get; } bool IsTestRunning { get; } bool IsTestComplete { get; } UnityWorkItem TopLevelWorkItem { get; set; } UnityTestExecutionContext GetCurrentContext(); ITest Load(Assembly[] assemblies, IDictionary settings); IEnumerable Run(ITestListener listener, ITestFilter filter); void StopRun(); } internal class UnityTestAssemblyRunner : IUnityTestAssemblyRunner { private readonly UnityTestAssemblyBuilder unityBuilder; private readonly WorkItemFactory m_Factory; protected UnityTestExecutionContext Context { get; set; } public UnityTestExecutionContext GetCurrentContext() { return UnityTestExecutionContext.CurrentContext; } protected IDictionary Settings { get; set; } public ITest LoadedTest { get; protected set; } public ITestResult Result { get { return TopLevelWorkItem == null ? null : TopLevelWorkItem.Result; } } public bool IsTestLoaded { get { return LoadedTest != null; } } public bool IsTestRunning { get { return TopLevelWorkItem != null && TopLevelWorkItem.State == NUnit.Framework.Internal.Execution.WorkItemState.Running; } } public bool IsTestComplete { get { return TopLevelWorkItem != null && TopLevelWorkItem.State == NUnit.Framework.Internal.Execution.WorkItemState.Complete; } } public UnityTestAssemblyRunner(UnityTestAssemblyBuilder builder, WorkItemFactory factory) { unityBuilder = builder; m_Factory = factory; Context = new UnityTestExecutionContext(); } public ITest Load(Assembly[] assemblies, IDictionary settings) { Settings = settings; if (settings.ContainsKey(FrameworkPackageSettings.RandomSeed)) Randomizer.InitialSeed = (int)settings[FrameworkPackageSettings.RandomSeed]; return LoadedTest = unityBuilder.Build(assemblies, settings); } public IEnumerable Run(ITestListener listener, ITestFilter filter) { TopLevelWorkItem = m_Factory.Create(LoadedTest, filter); TopLevelWorkItem.InitializeContext(Context); UnityTestExecutionContext.CurrentContext = Context; Context.Listener = listener; return TopLevelWorkItem.Execute(); } public UnityWorkItem TopLevelWorkItem { get; set; } public void StopRun() { if (IsTestRunning) { TopLevelWorkItem.Cancel(false); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityTestAssemblyRunner.cs.meta ================================================ fileFormatVersion: 2 guid: 874e40a588dbb1e48bc128d686337d4e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityTestExecutionContext.cs ================================================ using System; using System.Collections.Generic; using System.Globalization; using System.IO; using NUnit.Framework; using NUnit.Framework.Constraints; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Execution; using UnityEngine.TestTools; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class UnityTestExecutionContext : ITestExecutionContext { private readonly UnityTestExecutionContext _priorContext; private TestResult _currentResult; private int _assertCount; public static UnityTestExecutionContext CurrentContext { get; set; } public UnityTestExecutionContext Context { get; private set; } public Test CurrentTest { get; set; } public DateTime StartTime { get; set; } public long StartTicks { get; set; } public TestResult CurrentResult { get { return _currentResult; } set { _currentResult = value; if (value != null) OutWriter = value.OutWriter; } } public object TestObject { get; set; } public string WorkDirectory { get; set; } private TestExecutionStatus _executionStatus; public TestExecutionStatus ExecutionStatus { get { // ExecutionStatus may have been set to StopRequested or AbortRequested // in a prior context. If so, reflect the same setting in this context. if (_executionStatus == TestExecutionStatus.Running && _priorContext != null) _executionStatus = _priorContext.ExecutionStatus; return _executionStatus; } set { _executionStatus = value; // Push the same setting up to all prior contexts if (_priorContext != null) _priorContext.ExecutionStatus = value; } } public List UpstreamActions { get; private set; } public int TestCaseTimeout { get; set; } public CultureInfo CurrentCulture { get; set; } public CultureInfo CurrentUICulture { get; set; } public ITestListener Listener { get; set; } public UnityTestExecutionContext() { UpstreamActions = new List(); CurrentContext = this; } public UnityTestExecutionContext(UnityTestExecutionContext other) { _priorContext = other; CurrentTest = other.CurrentTest; CurrentResult = other.CurrentResult; TestObject = other.TestObject; WorkDirectory = other.WorkDirectory; Listener = other.Listener; TestCaseTimeout = other.TestCaseTimeout; UpstreamActions = new List(other.UpstreamActions); SetUpTearDownState = other.SetUpTearDownState; OuterUnityTestActionState = other.OuterUnityTestActionState; TestContext.CurrentTestExecutionContext = this; CurrentCulture = other.CurrentCulture; CurrentUICulture = other.CurrentUICulture; CurrentContext = this; } public TextWriter OutWriter { get; private set; } public bool StopOnError { get; set; } public IWorkItemDispatcher Dispatcher { get; set; } public ParallelScope ParallelScope { get; set; } public string WorkerId { get; private set; } public Randomizer RandomGenerator { get; private set; } public ValueFormatter CurrentValueFormatter { get; private set; } public bool IsSingleThreaded { get; set; } public BeforeAfterTestCommandState SetUpTearDownState { get; set; } public BeforeAfterTestCommandState OuterUnityTestActionState { get; set; } internal int AssertCount { get { return _assertCount; } } public void IncrementAssertCount() { _assertCount += 1; } public void AddFormatter(ValueFormatterFactory formatterFactory) { throw new NotImplementedException(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityTestExecutionContext.cs.meta ================================================ fileFormatVersion: 2 guid: 59ff995fabb3bac45afa0f96f333e5dc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityWorkItem.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Execution; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal abstract class UnityWorkItem { protected readonly WorkItemFactory m_Factory; protected bool m_ExecuteTestStartEvent; protected bool m_DontRunRestoringResult; public event EventHandler Completed; public bool ResultedInDomainReload { get; internal set; } public UnityTestExecutionContext Context { get; private set; } public Test Test { get; private set; } public TestResult Result { get; protected set; } public WorkItemState State { get; private set; } public List Actions { get; private set; } protected UnityWorkItem(Test test, WorkItemFactory factory) { m_Factory = factory; Test = test; Actions = new List(); Result = test.MakeTestResult(); State = WorkItemState.Ready; m_ExecuteTestStartEvent = ShouldExecuteStartEvent(); m_DontRunRestoringResult = ShouldRestore(test); } protected static bool ShouldRestore(ITest loadedTest) { return UnityWorkItemDataHolder.alreadyExecutedTests != null && UnityWorkItemDataHolder.alreadyExecutedTests.Contains(loadedTest.FullName); } protected bool ShouldExecuteStartEvent() { return UnityWorkItemDataHolder.alreadyStartedTests != null && UnityWorkItemDataHolder.alreadyStartedTests.All(x => x != Test.FullName) && !ShouldRestore(Test); } protected abstract IEnumerable PerformWork(); public void InitializeContext(UnityTestExecutionContext context) { Context = context; if (Test is TestAssembly) Actions.AddRange(ActionsHelper.GetActionsFromTestAssembly((TestAssembly)Test)); else if (Test is ParameterizedMethodSuite) Actions.AddRange(ActionsHelper.GetActionsFromTestMethodInfo(Test.Method)); else if (Test.TypeInfo != null) Actions.AddRange(ActionsHelper.GetActionsFromTypesAttributes(Test.TypeInfo.Type)); } public virtual IEnumerable Execute() { Context.CurrentTest = this.Test; Context.CurrentResult = this.Result; if (m_ExecuteTestStartEvent) { Context.Listener.TestStarted(Test); } Context.StartTime = DateTime.UtcNow; Context.StartTicks = Stopwatch.GetTimestamp(); State = WorkItemState.Running; return PerformWork(); } protected void WorkItemComplete() { State = WorkItemState.Complete; Result.StartTime = Context.StartTime; Result.EndTime = DateTime.UtcNow; long tickCount = Stopwatch.GetTimestamp() - Context.StartTicks; double seconds = (double)tickCount / Stopwatch.Frequency; Result.Duration = seconds; //Result.AssertCount += Context.AssertCount; Context.Listener.TestFinished(Result); if (Completed != null) Completed(this, EventArgs.Empty); Context.TestObject = null; Test.Fixture = null; } public virtual void Cancel(bool force) { Context.Listener.TestFinished(Result); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityWorkItem.cs.meta ================================================ fileFormatVersion: 2 guid: 79ced2556f0af814a840b86232613ff1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityWorkItemDataHolder.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal class UnityWorkItemDataHolder { public static List alreadyStartedTests = new List(); public static List alreadyExecutedTests; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/UnityWorkItemDataHolder.cs.meta ================================================ fileFormatVersion: 2 guid: 5b3e90046c38f1d4dad2e0d5a79e871c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/WorkItemFactory.cs ================================================ using System.Collections; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestRunner.NUnitExtensions.Runner { internal abstract class WorkItemFactory { public UnityWorkItem Create(ITest loadedTest, ITestFilter filter) { TestSuite suite = loadedTest as TestSuite; if (suite != null) { return new CompositeWorkItem(suite, filter, this); } var testMethod = (TestMethod)loadedTest; if (testMethod.Method.ReturnType.Type != typeof(IEnumerator)) { return new DefaultTestWorkItem(testMethod, filter); } return Create(testMethod, filter, loadedTest); } protected abstract UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner/WorkItemFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 5c15bf0966eb95847a4260d830a30d30 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/Runner.meta ================================================ fileFormatVersion: 2 guid: 37888acc09d9ee848bf9559f06645c45 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/TestExtensions.cs ================================================ using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine.TestRunner.NUnitExtensions.Filters; namespace UnityEngine.TestRunner.NUnitExtensions { internal static class TestExtensions { private static IEnumerable GetTestCategories(this ITest test) { var categories = test.Properties[PropertyNames.Category].Cast().ToList(); if (categories.Count == 0 && test is TestMethod) { // only mark tests as Uncategorized if the test fixture doesn't have a category, // otherwise the test inherits the Fixture category var fixtureCategories = test.Parent.Properties[PropertyNames.Category].Cast().ToList(); if (fixtureCategories.Count == 0) categories.Add(CategoryFilterExtended.k_DefaultCategory); } return categories; } public static bool HasCategory(this ITest test, string[] categoryFilter) { var categories = test.GetAllCategoriesFromTest().Distinct(); return categoryFilter.Any(c => categories.Any(r => r == c)); } public static List GetAllCategoriesFromTest(this ITest test) { if (test.Parent == null) return test.GetTestCategories().ToList(); var categories = GetAllCategoriesFromTest(test.Parent); categories.AddRange(test.GetTestCategories()); return categories; } public static void ParseForNameDuplicates(this ITest test) { var duplicates = new Dictionary(); for (var i = 0; i < test.Tests.Count; i++) { var child = test.Tests[i]; int count; if (duplicates.TryGetValue(child.FullName, out count)) { count++; child.Properties.Add("childIndex", count); duplicates[child.FullName] = count; } else { duplicates.Add(child.FullName, 1); } ParseForNameDuplicates(child); } } public static int GetChildIndex(this ITest test) { var index = test.Properties["childIndex"]; return (int)index[0]; } public static bool HasChildIndex(this ITest test) { var index = test.Properties["childIndex"]; return index.Count > 0; } static string GetAncestorPath(ITest test) { var path = ""; var testParent = test.Parent; while (testParent != null && testParent.Parent != null && !string.IsNullOrEmpty(testParent.Name)) { path = testParent.Name + "/" + path; testParent = testParent.Parent; } return path; } public static string GetUniqueName(this ITest test) { var id = GetAncestorPath(test) + GetFullName(test); if (test.HasChildIndex()) { var index = test.GetChildIndex(); if (index >= 0) id += index; } if (test.IsSuite) { id += "[suite]"; } return id; } public static string GetFullName(ITest test) { if (test.TypeInfo == null && (test.Parent == null || test.Parent.TypeInfo == null)) { return "[" + test.FullName + "]"; } var assemblyId = test.TypeInfo == null ? test.Parent.TypeInfo.Assembly.GetName().Name : test.TypeInfo.Assembly.GetName().Name; return string.Format("[{0}][{1}]", assemblyId, test.FullName); } public static string GetSkipReason(this ITest test) { if (test.Properties.ContainsKey(PropertyNames.SkipReason)) return (string)test.Properties.Get(PropertyNames.SkipReason); return null; } public static string GetParentId(this ITest test) { if (test.Parent != null) return test.Parent.Id; return null; } public static string GetParentUniqueName(this ITest test) { if (test.Parent != null) return GetUniqueName(test.Parent); return null; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/TestExtensions.cs.meta ================================================ fileFormatVersion: 2 guid: 8bc74398aa3944646ade4ee78cd57484 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/TestResultExtensions.cs ================================================ using System; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestRunner.NUnitExtensions { internal static class TestResultExtensions { public static void RecordPrefixedException(this TestResult testResult, string prefix, Exception ex, ResultState resultState = null) { if (ex is NUnitException) { ex = ex.InnerException; } if (resultState == null) { resultState = testResult.ResultState == ResultState.Cancelled ? ResultState.Cancelled : ResultState.Error; } var exceptionMessage = ExceptionHelper.BuildMessage(ex); string stackTrace = "--" + prefix + NUnit.Env.NewLine + ExceptionHelper.BuildStackTrace(ex); if (testResult.StackTrace != null) { stackTrace = testResult.StackTrace + NUnit.Env.NewLine + stackTrace; } if (testResult.Test.IsSuite) { resultState = resultState.WithSite(FailureSite.TearDown); } if (ex is ResultStateException) { exceptionMessage = ex.Message; resultState = ((ResultStateException)ex).ResultState; stackTrace = StackFilter.Filter(ex.StackTrace); } string message = (string.IsNullOrEmpty(prefix) ? "" : (prefix + " : ")) + exceptionMessage; if (testResult.Message != null) { message = testResult.Message + NUnit.Env.NewLine + message; } testResult.SetResult(resultState, message, stackTrace); } public static void RecordPrefixedError(this TestResult testResult, string prefix, string error, ResultState resultState = null) { if (resultState == null) { resultState = testResult.ResultState == ResultState.Cancelled ? ResultState.Cancelled : ResultState.Error; } if (testResult.Test.IsSuite) { resultState = resultState.WithSite(FailureSite.TearDown); } string message = (string.IsNullOrEmpty(prefix) ? "" : (prefix + " : ")) + error; if (testResult.Message != null) { message = testResult.Message + NUnit.Env.NewLine + message; } testResult.SetResult(resultState, message); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/TestResultExtensions.cs.meta ================================================ fileFormatVersion: 2 guid: 65fb6da362a78334ab360a125cfafdaf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/UnityTestAssemblyBuilder.cs ================================================ using System.Collections.Generic; using System.IO; using System.Reflection; using NUnit; using NUnit.Framework.Api; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestTools.NUnitExtensions { internal class UnityTestAssemblyBuilder : DefaultTestAssemblyBuilder { private readonly string m_ProductName; public UnityTestAssemblyBuilder() { m_ProductName = Application.productName; } public ITest Build(Assembly[] assemblies, IDictionary options) { var test = BuildAsync(assemblies, options); while (test.MoveNext()) { } return test.Current; } public IEnumerator BuildAsync(Assembly[] assemblies, IDictionary options) { var productName = string.Join("_", m_ProductName.Split(Path.GetInvalidFileNameChars())); var suite = new TestSuite(productName); foreach (var assembly in assemblies) { var assemblySuite = Build(assembly, options) as TestSuite; if (assemblySuite != null && assemblySuite.HasChildren) { suite.Add(assemblySuite); } yield return null; } yield return suite; } public static Dictionary GetNUnitTestBuilderSettings(TestPlatform testPlatform) { var emptySettings = new Dictionary(); emptySettings.Add(FrameworkPackageSettings.TestParameters, "platform=" + testPlatform); return emptySettings; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions/UnityTestAssemblyBuilder.cs.meta ================================================ fileFormatVersion: 2 guid: 98ba0396e4b4ee8498a8f097affcfddf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/NUnitExtensions.meta ================================================ fileFormatVersion: 2 guid: 3e8d6af343b383544ba5743d119f4062 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/PlayModeRunnerCallback.cs ================================================ using NUnit.Framework; using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools.TestRunner.Callbacks { [AddComponentMenu("")] internal class PlayModeRunnerCallback : MonoBehaviour, ITestRunnerListener { private TestResultRenderer m_ResultRenderer; public void RunFinished(ITestResult testResults) { Application.logMessageReceivedThreaded -= LogRecieved; if (Camera.main == null) { gameObject.AddComponent(); } m_ResultRenderer = new TestResultRenderer(testResults); m_ResultRenderer.ShowResults(); } public void TestFinished(ITestResult result) { } public void OnGUI() { if (m_ResultRenderer != null) m_ResultRenderer.Draw(); } public void RunStarted(ITest testsToRun) { Application.logMessageReceivedThreaded += LogRecieved; } public void TestStarted(ITest test) { } private void LogRecieved(string message, string stacktrace, LogType type) { if (TestContext.Out != null) TestContext.Out.WriteLine(message); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/PlayModeRunnerCallback.cs.meta ================================================ fileFormatVersion: 2 guid: 3cf5cb9e1ef590c48b1f919f2a7bd895 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/RemoteTestResultSender.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework.Interfaces; using UnityEngine.Networking.PlayerConnection; using UnityEngine.TestRunner.TestLaunchers; namespace UnityEngine.TestTools.TestRunner.Callbacks { [AddComponentMenu("")] internal class RemoteTestResultSender : MonoBehaviour, ITestRunnerListener { private class QueueData { public Guid id { get; set; } public byte[] data { get; set; } } private readonly Queue m_SendQueue = new Queue(); private readonly object m_LockQueue = new object(); private readonly IRemoteTestResultDataFactory m_TestResultDataFactory = new RemoteTestResultDataFactory(); public void Start() { PlayerConnection.instance.Register(PlayerConnectionMessageIds.runFinishedMessageId, EditorProccessedTheResult); StartCoroutine(SendDataRoutine()); } private void EditorProccessedTheResult(MessageEventArgs arg0) { if (arg0.data != null) { return; } //Some platforms don't quit, so we need to disconnect to make sure they will not connect to another editor instance automatically. PlayerConnection.instance.DisconnectAll(); //XBOX has an error when quitting if (Application.platform == RuntimePlatform.XboxOne) { return; } Application.Quit(); } private byte[] SerializeObject(object objectToSerialize) { return Encoding.UTF8.GetBytes(JsonUtility.ToJson(objectToSerialize)); } public void RunStarted(ITest testsToRun) { var data = SerializeObject(m_TestResultDataFactory.CreateFromTest(testsToRun)); lock (m_LockQueue) { m_SendQueue.Enqueue(new QueueData { id = PlayerConnectionMessageIds.runStartedMessageId, data = data }); } } public void RunFinished(ITestResult testResults) { var data = SerializeObject(m_TestResultDataFactory.CreateFromTestResult(testResults)); lock (m_LockQueue) { m_SendQueue.Enqueue(new QueueData { id = PlayerConnectionMessageIds.runFinishedMessageId, data = data, }); } } public void TestStarted(ITest test) { var data = SerializeObject(m_TestResultDataFactory.CreateFromTest(test)); lock (m_LockQueue) { m_SendQueue.Enqueue(new QueueData { id = PlayerConnectionMessageIds.testStartedMessageId, data = data }); } } public void TestFinished(ITestResult result) { var testRunnerResultForApi = m_TestResultDataFactory.CreateFromTestResult(result); var resultData = SerializeObject(testRunnerResultForApi); lock (m_LockQueue) { m_SendQueue.Enqueue(new QueueData { id = PlayerConnectionMessageIds.testFinishedMessageId, data = resultData, }); } } public IEnumerator SendDataRoutine() { while (!PlayerConnection.instance.isConnected) { yield return new WaitForSeconds(1); } while (true) { lock (m_LockQueue) { if (PlayerConnection.instance.isConnected && m_SendQueue.Count > 0) { var queueData = m_SendQueue.Dequeue(); PlayerConnection.instance.Send(queueData.id, queueData.data); yield return null; } //This is needed so we dont stall the player totally if (!m_SendQueue.Any()) { yield return new WaitForSeconds(0.02f); } } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/RemoteTestResultSender.cs.meta ================================================ fileFormatVersion: 2 guid: 20793418366caf14293b29c55df5e9ec MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/TestResultRenderer.cs ================================================ using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestTools.TestRunner.Callbacks { internal class TestResultRenderer { private static class Styles { public static readonly GUIStyle SucceedLabelStyle; public static readonly GUIStyle FailedLabelStyle; public static readonly GUIStyle FailedMessagesStyle; static Styles() { SucceedLabelStyle = new GUIStyle("label"); SucceedLabelStyle.normal.textColor = Color.green; SucceedLabelStyle.fontSize = 48; FailedLabelStyle = new GUIStyle("label"); FailedLabelStyle.normal.textColor = Color.red; FailedLabelStyle.fontSize = 32; FailedMessagesStyle = new GUIStyle("label"); FailedMessagesStyle.wordWrap = false; FailedMessagesStyle.richText = true; } } private readonly List m_FailedTestCollection; private bool m_ShowResults; private Vector2 m_ScrollPosition; public TestResultRenderer(ITestResult testResults) { m_FailedTestCollection = new List(); GetFailedTests(testResults); } private void GetFailedTests(ITestResult testResults) { if (testResults is TestCaseResult) { if (testResults.ResultState.Status == TestStatus.Failed) m_FailedTestCollection.Add(testResults); } else if (testResults.HasChildren) { foreach (var testResultsChild in testResults.Children) { GetFailedTests(testResultsChild); } } } private const int k_MaxStringLength = 15000; public void ShowResults() { m_ShowResults = true; Cursor.visible = true; } public void Draw() { if (!m_ShowResults) return; if (m_FailedTestCollection.Count == 0) { GUILayout.Label("All test succeeded", Styles.SucceedLabelStyle, GUILayout.Width(600)); } else { int count = m_FailedTestCollection.Count; GUILayout.Label(count + " tests failed!", Styles.FailedLabelStyle); m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition, GUILayout.ExpandWidth(true)); var text = ""; text += "Code-based tests\n"; text += string.Join("\n", m_FailedTestCollection .Select(result => result.Name + " " + result.ResultState + "\n" + result.Message) .ToArray()); if (text.Length > k_MaxStringLength) text = text.Substring(0, k_MaxStringLength); GUILayout.TextArea(text, Styles.FailedMessagesStyle); GUILayout.EndScrollView(); } if (GUILayout.Button("Close")) Application.Quit(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/TestResultRenderer.cs.meta ================================================ fileFormatVersion: 2 guid: 5ebb87899ca30b743bb4274bc00c02b4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/TestResultRendererCallback.cs ================================================ using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools.TestRunner.Callbacks { internal class TestResultRendererCallback : MonoBehaviour, ITestRunnerListener { private TestResultRenderer m_ResultRenderer; public void RunStarted(ITest testsToRun) { } public void RunFinished(ITestResult testResults) { if (Camera.main == null) { gameObject.AddComponent(); } m_ResultRenderer = new TestResultRenderer(testResults); m_ResultRenderer.ShowResults(); } public void OnGUI() { if (m_ResultRenderer != null) m_ResultRenderer.Draw(); } public void TestStarted(ITest test) { } public void TestFinished(ITestResult result) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks/TestResultRendererCallback.cs.meta ================================================ fileFormatVersion: 2 guid: dfc336f10b83bd74eaded16a658275c7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Callbacks.meta ================================================ fileFormatVersion: 2 guid: 61e236e8570a95e4eb754fb291e102e0 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/ITestRunnerListener.cs ================================================ using System; using NUnit.Framework.Interfaces; using UnityEngine.Events; namespace UnityEngine.TestTools.TestRunner { internal interface ITestRunnerListener { void RunStarted(ITest testsToRun); void RunFinished(ITestResult testResults); void TestStarted(ITest test); void TestFinished(ITestResult result); } [Serializable] internal class TestFinishedEvent : UnityEvent {} [Serializable] internal class TestStartedEvent : UnityEvent {} [Serializable] internal class RunFinishedEvent : UnityEvent {} [Serializable] internal class RunStartedEvent : UnityEvent {} } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/ITestRunnerListener.cs.meta ================================================ fileFormatVersion: 2 guid: d1b534518943030499685344fd1d476d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Messages/IEditModeTestYieldInstruction.cs ================================================ using System.Collections; namespace UnityEngine.TestTools { public interface IEditModeTestYieldInstruction { bool ExpectDomainReload { get; } bool ExpectedPlaymodeState { get; } IEnumerator Perform(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Messages/IEditModeTestYieldInstruction.cs.meta ================================================ fileFormatVersion: 2 guid: 898bc38486fc899428fbe5bd6adfe473 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/Messages.meta ================================================ fileFormatVersion: 2 guid: 256a0ca37fa972840bce7fca446e75e7 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/PlaymodeTestsController.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine.SceneManagement; using UnityEngine.TestRunner.NUnitExtensions; using UnityEngine.TestRunner.NUnitExtensions.Runner; using UnityEngine.TestTools.NUnitExtensions; using UnityEngine.TestTools.Utils; namespace UnityEngine.TestTools.TestRunner { [Serializable] [AddComponentMenu("")] internal class PlaymodeTestsController : MonoBehaviour { private IEnumerator m_TestSteps; [SerializeField] private List m_AssembliesWithTests; public List AssembliesWithTests { get { return m_AssembliesWithTests; } set { m_AssembliesWithTests = value; } } [SerializeField] internal TestStartedEvent testStartedEvent = new TestStartedEvent(); [SerializeField] internal TestFinishedEvent testFinishedEvent = new TestFinishedEvent(); [SerializeField] internal RunStartedEvent runStartedEvent = new RunStartedEvent(); [SerializeField] internal RunFinishedEvent runFinishedEvent = new RunFinishedEvent(); internal const string kPlaymodeTestControllerName = "Code-based tests runner"; [SerializeField] public PlaymodeTestsControllerSettings settings = new PlaymodeTestsControllerSettings(); internal UnityTestAssemblyRunner m_Runner; public IEnumerator Start() { //Skip 2 frame because Unity. yield return null; yield return null; StartCoroutine(Run()); } internal static bool IsControllerOnScene() { return GameObject.Find(kPlaymodeTestControllerName) != null; } internal static PlaymodeTestsController GetController() { return GameObject.Find(kPlaymodeTestControllerName).GetComponent(); } public IEnumerator TestRunnerCorotine() { while (m_TestSteps.MoveNext()) { yield return m_TestSteps.Current; } if (m_Runner.IsTestComplete) { runFinishedEvent.Invoke(m_Runner.Result); Cleanup(); yield return null; } } public IEnumerator Run() { CoroutineTestWorkItem.monoBehaviourCoroutineRunner = this; gameObject.hideFlags |= HideFlags.DontSave; if (settings.sceneBased) { SceneManager.LoadScene(1, LoadSceneMode.Additive); yield return null; } var testListUtil = new PlayerTestAssemblyProvider(new AssemblyLoadProxy(), m_AssembliesWithTests); m_Runner = new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(), new PlaymodeWorkItemFactory()); var loadedTests = m_Runner.Load(testListUtil.GetUserAssemblies().Select(a => a.Assembly).ToArray(), UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(TestPlatform.PlayMode)); loadedTests.ParseForNameDuplicates(); runStartedEvent.Invoke(m_Runner.LoadedTest); var testListenerWrapper = new TestListenerWrapper(testStartedEvent, testFinishedEvent); m_TestSteps = m_Runner.Run(testListenerWrapper, settings.filter.BuildNUnitFilter()).GetEnumerator(); yield return TestRunnerCorotine(); } public void Cleanup() { if (m_Runner != null) { m_Runner.StopRun(); m_Runner = null; } if (Application.isEditor) { Destroy(gameObject); } } public static void TryCleanup() { var controller = GetController(); if (controller != null) { controller.Cleanup(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/PlaymodeTestsController.cs.meta ================================================ fileFormatVersion: 2 guid: 102e512f651ee834f951a2516c1ea3b8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/PlaymodeTestsControllerSettings.cs ================================================ using System; using UnityEngine.SceneManagement; using UnityEngine.TestTools.TestRunner.GUI; namespace UnityEngine.TestTools.TestRunner { [Serializable] internal class PlaymodeTestsControllerSettings { [SerializeField] public TestRunnerFilter filter; public bool sceneBased; public string originalScene; public string bootstrapScene; public static PlaymodeTestsControllerSettings CreateRunnerSettings(TestRunnerFilter filter) { var settings = new PlaymodeTestsControllerSettings { filter = filter, sceneBased = false, originalScene = SceneManager.GetActiveScene().path, bootstrapScene = null }; return settings; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/PlaymodeTestsControllerSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 2799eb4c84e72e54092a292cf626936b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/IRemoteTestResultDataFactory.cs ================================================ using System; using NUnit.Framework.Interfaces; namespace UnityEngine.TestRunner.TestLaunchers { internal interface IRemoteTestResultDataFactory { RemoteTestResultDataWithTestData CreateFromTestResult(ITestResult result); RemoteTestResultDataWithTestData CreateFromTest(ITest test); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/IRemoteTestResultDataFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 874c0713cdc44f549b0161750b48d2c2 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/PlayerConnectionMessageIds.cs ================================================ using System; namespace UnityEngine.TestRunner.TestLaunchers { internal static class PlayerConnectionMessageIds { public static Guid runStartedMessageId { get { return new Guid("6a7f53dd-4672-461d-a7b5-9467e9393fd3"); } } public static Guid runFinishedMessageId { get { return new Guid("ffb622fc-34ad-4901-8d7b-47fb04b0bdd4"); } } public static Guid testStartedMessageId { get { return new Guid("b54d241e-d88d-4dba-8c8f-ee415d11c030"); } } public static Guid testFinishedMessageId { get { return new Guid("72f7b7f4-6829-4cd1-afde-78872b9d5adc"); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/PlayerConnectionMessageIds.cs.meta ================================================ fileFormatVersion: 2 guid: 41d60936b62cc6d4ca7fe628b22b0e40 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestData.cs ================================================ using System; using System.Linq; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using UnityEngine.TestRunner.NUnitExtensions; namespace UnityEngine.TestRunner.TestLaunchers { [Serializable] internal class RemoteTestData { public string id; public string name; public string fullName; public int testCaseCount; public int ChildIndex; public bool hasChildren; public bool isSuite; public string[] childrenIds; public int testCaseTimeout; public string[] Categories; public bool IsTestAssembly; public RunState RunState; public string Description; public string SkipReason; public string ParentId; public string UniqueName; public string ParentUniqueName; internal RemoteTestData(ITest test) { id = test.Id; name = test.Name; fullName = test.FullName; testCaseCount = test.TestCaseCount; ChildIndex = -1; if (test.Properties["childIndex"].Count > 0) { ChildIndex = (int)test.Properties["childIndex"][0]; } hasChildren = test.HasChildren; isSuite = test.IsSuite; childrenIds = test.Tests.Select(t => t.Id).ToArray(); Categories = test.GetAllCategoriesFromTest().ToArray(); IsTestAssembly = test is TestAssembly; RunState = (RunState)Enum.Parse(typeof(RunState), test.RunState.ToString()); Description = (string)test.Properties.Get(PropertyNames.Description); SkipReason = test.GetSkipReason(); ParentId = test.GetParentId(); UniqueName = test.GetUniqueName(); ParentUniqueName = test.GetParentUniqueName(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestData.cs.meta ================================================ fileFormatVersion: 2 guid: b135ec222fdcd11468014c90d11d6821 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestResultData.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; namespace UnityEngine.TestRunner.TestLaunchers { [Serializable] internal class RemoteTestResultData { public string testId; public string name; public string fullName; public string resultState; public TestStatus testStatus; public double duration; public DateTime startTime; public DateTime endTime; public string message; public string stackTrace; public int assertCount; public int failCount; public int passCount; public int skipCount; public int inconclusiveCount; public bool hasChildren; public string output; public string xml; public string[] childrenIds; internal RemoteTestResultData(ITestResult result) { testId = result.Test.Id; name = result.Name; fullName = result.FullName; resultState = result.ResultState.ToString(); testStatus = result.ResultState.Status; duration = result.Duration; startTime = result.StartTime; endTime = result.EndTime; message = result.Message; stackTrace = result.StackTrace; assertCount = result.AssertCount; failCount = result.FailCount; passCount = result.PassCount; skipCount = result.SkipCount; inconclusiveCount = result.InconclusiveCount; hasChildren = result.HasChildren; output = result.Output; xml = result.ToXml(true).OuterXml; childrenIds = result.Children.Select(child => child.Test.Id).ToArray(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestResultData.cs.meta ================================================ fileFormatVersion: 2 guid: 03e4d63665d06f04c8a6cf68133c1592 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestResultDataFactory.cs ================================================ using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestRunner.TestLaunchers { internal class RemoteTestResultDataFactory : IRemoteTestResultDataFactory { public RemoteTestResultDataWithTestData CreateFromTestResult(ITestResult result) { var tests = CreateTestDataList(result.Test); tests.First().testCaseTimeout = UnityTestExecutionContext.CurrentContext.TestCaseTimeout; return new RemoteTestResultDataWithTestData() { results = CreateTestResultDataList(result), tests = tests }; } public RemoteTestResultDataWithTestData CreateFromTest(ITest test) { var tests = CreateTestDataList(test); if (UnityTestExecutionContext.CurrentContext != null) { tests.First().testCaseTimeout = UnityTestExecutionContext.CurrentContext.TestCaseTimeout; } return new RemoteTestResultDataWithTestData() { tests = tests }; } private RemoteTestData[] CreateTestDataList(ITest test) { var list = new List(); list.Add(new RemoteTestData(test)); list.AddRange(test.Tests.SelectMany(CreateTestDataList)); return list.ToArray(); } private static RemoteTestResultData[] CreateTestResultDataList(ITestResult result) { var list = new List(); list.Add(new RemoteTestResultData(result)); list.AddRange(result.Children.SelectMany(CreateTestResultDataList)); return list.ToArray(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestResultDataFactory.cs.meta ================================================ fileFormatVersion: 2 guid: 826b6becaef90fb458eedebe4c2f3664 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestResultDataWithTestData.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestRunner.TestLaunchers { [Serializable] internal class RemoteTestResultDataWithTestData { public RemoteTestResultData[] results; public RemoteTestData[] tests; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers/RemoteTestResultDataWithTestData.cs.meta ================================================ fileFormatVersion: 2 guid: 475e3699f219c854f8581a9838135002 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/RemoteHelpers.meta ================================================ fileFormatVersion: 2 guid: 91c20d2c22b8b3a4cb6c816bd225591a folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestEnumeratorWrapper.cs ================================================ using System; using System.Collections; using System.Reflection; using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; namespace UnityEngine.TestTools.TestRunner { internal class TestEnumeratorWrapper { private readonly TestMethod m_TestMethod; public TestEnumeratorWrapper(TestMethod testMethod) { m_TestMethod = testMethod; } public IEnumerator GetEnumerator(ITestExecutionContext context) { if (m_TestMethod.Method.ReturnType.Type == typeof(IEnumerator)) { return HandleEnumerableTest(context); } var message = string.Format("Return type {0} of {1} in {2} is not supported.", m_TestMethod.Method.ReturnType, m_TestMethod.Method.Name, m_TestMethod.Method.TypeInfo.FullName); if (m_TestMethod.Method.ReturnType.Type == typeof(IEnumerable)) { message += "\nDid you mean IEnumerator?"; } throw new InvalidSignatureException(message); } private IEnumerator HandleEnumerableTest(ITestExecutionContext context) { try { return m_TestMethod.Method.MethodInfo.Invoke(context.TestObject, m_TestMethod.parms != null ? m_TestMethod.parms.OriginalArguments : null) as IEnumerator; } catch (TargetInvocationException e) { if (e.InnerException is IgnoreException) { context.CurrentResult.SetResult(ResultState.Ignored, e.InnerException.Message); return null; } throw; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestEnumeratorWrapper.cs.meta ================================================ fileFormatVersion: 2 guid: 9ad0b0c865b01af4ca1b414689e71259 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestListenerWrapper.cs ================================================ using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools.TestRunner { internal class TestListenerWrapper : ITestListener { private readonly TestFinishedEvent m_TestFinishedEvent; private readonly TestStartedEvent m_TestStartedEvent; public TestListenerWrapper(TestStartedEvent testStartedEvent, TestFinishedEvent testFinishedEvent) { m_TestStartedEvent = testStartedEvent; m_TestFinishedEvent = testFinishedEvent; } public void TestStarted(ITest test) { m_TestStartedEvent.Invoke(test); } public void TestFinished(ITestResult result) { m_TestFinishedEvent.Invoke(result); } public void TestOutput(TestOutput output) { } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestListenerWrapper.cs.meta ================================================ fileFormatVersion: 2 guid: 73deb9b8722aa284eab27c4dc90956c6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestPlatform.cs ================================================ using System; namespace UnityEngine.TestTools { [Flags] [Serializable] public enum TestPlatform : byte { All = 0xFF, EditMode = 1 << 1, PlayMode = 1 << 2 } internal static class TestPlatformEnumExtensions { public static bool IsFlagIncluded(this TestPlatform flags, TestPlatform flag) { return (flags & flag) == flag; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestPlatform.cs.meta ================================================ fileFormatVersion: 2 guid: 743879b4db4bc1a4b829aae4386f4acf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestRunnerFilter.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.IO; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Filters; using UnityEngine.TestRunner.NUnitExtensions.Filters; namespace UnityEngine.TestTools.TestRunner.GUI { [Serializable] internal class TestRunnerFilter { #pragma warning disable 649 public string[] assemblyNames; public string[] groupNames; public string[] categoryNames; public static TestRunnerFilter empty = new TestRunnerFilter(); public string[] testNames; public int testRepetitions = 1; public static string AssemblyNameFromPath(string path) { string output = Path.GetFileName(path); if (output != null && output.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) return output.Substring(0, output.Length - 4); return output; } private bool CategoryMatches(IEnumerable categories) { if (categoryNames == null || categoryNames.Length == 0) return true; foreach (string category in categories) { if (categoryNames.Contains(category)) return true; } return false; } private bool IDMatchesAssembly(string id) { if (AreOptionalFiltersEmpty()) return true; if (assemblyNames == null) return false; int openingBracket = id.IndexOf('['); int closingBracket = id.IndexOf(']'); if (openingBracket >= 0 && openingBracket < id.Length && closingBracket > openingBracket && openingBracket < id.Length) { //Some assemblies are absolute and explicitly part of the test ID e.g. //"[/path/to/assembly-name.dll][rest of ID ...]" //While some are minimal assembly names e.g. //"[assembly-name][rest of ID ...]" //Strip them down to just the assembly name string assemblyNameFromID = AssemblyNameFromPath(id.Substring(openingBracket + 1, closingBracket - openingBracket - 1)); foreach (string assemblyName in assemblyNames) { if (assemblyName.Equals(assemblyNameFromID, StringComparison.OrdinalIgnoreCase)) return true; } } return false; } private bool NameMatches(string name) { if (AreOptionalFiltersEmpty()) return true; if (groupNames == null) return false; foreach (var nameFromFilter in groupNames) { //Strict regex match for test group name on its own if (Regex.IsMatch(name, nameFromFilter)) return true; //Match test names that end with parametrized test values and full nunit generated test names that have . separators var regex = nameFromFilter.TrimEnd('$') + @"[\.|\(.*\)]"; if (Regex.IsMatch(name, regex)) return true; } return false; } private bool AreOptionalFiltersEmpty() { if (assemblyNames != null && assemblyNames.Length != 0) return false; if (groupNames != null && groupNames.Length != 0) return false; if (testNames != null && testNames.Length != 0) return false; return true; } private bool NameMatchesExactly(string name) { if (AreOptionalFiltersEmpty()) return true; if (testNames == null) return false; foreach (var exactName in testNames) { if (name == exactName) return true; } return false; } private static void ClearAncestors(IEnumerable newResultList, string parentID) { if (string.IsNullOrEmpty(parentID)) return; foreach (var result in newResultList) { if (result.Id == parentID) { result.Clear(); ClearAncestors(newResultList, result.ParentId); break; } } } public void ClearResults(List newResultList) { foreach (var result in newResultList) { if (!result.IsSuite && CategoryMatches(result.Categories)) { if (IDMatchesAssembly(result.Id) || NameMatches(result.FullName) || NameMatchesExactly(result.FullName)) { result.Clear(); ClearAncestors(newResultList, result.ParentId); } } } } public ITestFilter BuildNUnitFilter() { var filters = new List(); if (testNames != null && testNames.Length != 0) { var nameFilter = new OrFilter(testNames.Select(n => new FullNameFilter(n)).ToArray()); filters.Add(nameFilter); } if (groupNames != null && groupNames.Length != 0) { var exactNamesFilter = new OrFilter(groupNames.Select(n => { var f = new FullNameFilter(n); f.IsRegex = true; return f; }).ToArray()); filters.Add(exactNamesFilter); } if (assemblyNames != null && assemblyNames.Length != 0) { var assemblyFilter = new OrFilter(assemblyNames.Select(c => new AssemblyNameFilter(c)).ToArray()); filters.Add(assemblyFilter); } if (categoryNames != null && categoryNames.Length != 0) { var categoryFilter = new OrFilter(categoryNames.Select(c => new CategoryFilterExtended(c) {IsRegex = true}).ToArray()); filters.Add(categoryFilter); } return filters.Count == 0 ? TestFilter.Empty : new AndFilter(filters.ToArray()); } internal interface IClearableResult { string Id { get; } string FullName { get; } string ParentId { get; } bool IsSuite { get; } List Categories { get; } void Clear(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner/TestRunnerFilter.cs.meta ================================================ fileFormatVersion: 2 guid: a025ba7ee40d0104db8d08b1d9eabb0d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/TestRunner.meta ================================================ fileFormatVersion: 2 guid: 1ddb9e1c877ea80479d1eab4ddaa5d0d folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/UnityEngine.TestRunner.asmdef ================================================ { "name": "UnityEngine.TestRunner", "references": [], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, "overrideReferences": true, "precompiledReferences": [ "nunit.framework.dll" ], "autoReferenced": false, "defineConstraints": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/UnityEngine.TestRunner.asmdef.meta ================================================ fileFormatVersion: 2 guid: 27619889b8ba8c24980f49ee34dbb44a AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/AssemblyLoadProxy.cs ================================================ using System.Reflection; namespace UnityEngine.TestTools.Utils { internal class AssemblyLoadProxy : IAssemblyLoadProxy { public IAssemblyWrapper Load(string assemblyString) { return new AssemblyWrapper(Assembly.Load(assemblyString)); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/AssemblyLoadProxy.cs.meta ================================================ fileFormatVersion: 2 guid: fb593906b7b6d824087dcaebf6c082e0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/AssemblyWrapper.cs ================================================ using System; using System.Reflection; namespace UnityEngine.TestTools.Utils { internal class AssemblyWrapper : IAssemblyWrapper { public AssemblyWrapper(Assembly assembly) { Assembly = assembly; } public Assembly Assembly { get; } public virtual string Location { get { //Some platforms dont support this throw new NotImplementedException(); } } public virtual AssemblyName[] GetReferencedAssemblies() { //Some platforms dont support this throw new NotImplementedException(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/AssemblyWrapper.cs.meta ================================================ fileFormatVersion: 2 guid: 2e3b9bbf2c1a3cd4f88883ca32882ec6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/IAssemblyLoadProxy.cs ================================================ namespace UnityEngine.TestTools.Utils { internal interface IAssemblyLoadProxy { IAssemblyWrapper Load(string assemblyString); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/IAssemblyLoadProxy.cs.meta ================================================ fileFormatVersion: 2 guid: 12dfd4bdbb5c8e6419432fbc54ef25d9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/IAssemblyWrapper.cs ================================================ using System.Reflection; namespace UnityEngine.TestTools.Utils { internal interface IAssemblyWrapper { Assembly Assembly { get; } string Location { get; } AssemblyName[] GetReferencedAssemblies(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/IAssemblyWrapper.cs.meta ================================================ fileFormatVersion: 2 guid: 1c5afe945b715e149a70113a4be7b32a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/IScriptingRuntimeProxy.cs ================================================ namespace UnityEngine.TestTools.Utils { internal interface IScriptingRuntimeProxy { string[] GetAllUserAssemblies(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/IScriptingRuntimeProxy.cs.meta ================================================ fileFormatVersion: 2 guid: fe4aef60e4ace544c8430da8ef8acba2 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/ITestAssemblyProvider.cs ================================================ using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools.Utils { internal interface ITestAssemblyProvider { ITest GetTestsWithNUnit(); IAssemblyWrapper[] GetUserAssemblies(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/ITestAssemblyProvider.cs.meta ================================================ fileFormatVersion: 2 guid: c5acba6181d845c4e92146009bd4480f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/PlayerTestAssemblyProvider.cs ================================================ using System.Collections.Generic; using System.IO; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine.TestTools.NUnitExtensions; namespace UnityEngine.TestTools.Utils { internal class PlayerTestAssemblyProvider { private IAssemblyLoadProxy m_AssemblyLoadProxy; private readonly List m_AssembliesToLoad; //Cached until domain reload private static List m_LoadedAssemblies; internal PlayerTestAssemblyProvider(IAssemblyLoadProxy assemblyLoadProxy, List assembliesToLoad) { m_AssemblyLoadProxy = assemblyLoadProxy; m_AssembliesToLoad = assembliesToLoad; LoadAssemblies(); } public ITest GetTestsWithNUnit() { return BuildTests(TestPlatform.PlayMode, m_LoadedAssemblies.ToArray()); } public List GetUserAssemblies() { return m_LoadedAssemblies; } protected static ITest BuildTests(TestPlatform testPlatform, IAssemblyWrapper[] assemblies) { var settings = UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(testPlatform); var builder = new UnityTestAssemblyBuilder(); return builder.Build(assemblies.Select(a => a.Assembly).ToArray(), settings); } private void LoadAssemblies() { if (m_LoadedAssemblies != null) { return; } m_LoadedAssemblies = new List(); foreach (var userAssembly in m_AssembliesToLoad) { IAssemblyWrapper a; try { a = m_AssemblyLoadProxy.Load(userAssembly); } catch (FileNotFoundException) { continue; } if (a != null) m_LoadedAssemblies.Add(a); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/PlayerTestAssemblyProvider.cs.meta ================================================ fileFormatVersion: 2 guid: 43a3aec217baa9644a7cf34b5f93fed9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/ScriptingRuntimeProxy.cs ================================================ namespace UnityEngine.TestTools.Utils { internal class ScriptingRuntimeProxy : IScriptingRuntimeProxy { public string[] GetAllUserAssemblies() { return ScriptingRuntime.GetAllUserAssemblies(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider/ScriptingRuntimeProxy.cs.meta ================================================ fileFormatVersion: 2 guid: f3a361a6ad1aff14ba8f48976e94ad76 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AssemblyProvider.meta ================================================ fileFormatVersion: 2 guid: 51557afa652635743b264a309f0a5c60 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AttributeHelper.cs ================================================ using System; using System.IO; using System.Linq; namespace UnityEngine.TestTools { internal static class AttributeHelper { internal static Type GetTargetClassFromName(string targetClassName, Type attributeInterface) { Type targetClass = null; foreach (var assemblyName in ScriptingRuntime.GetAllUserAssemblies()) { // we need to pass the assembly name without the .dll extension, so removing that first var name = Path.GetFileNameWithoutExtension(assemblyName); targetClass = Type.GetType(targetClassName + "," + name); if (targetClass != null) break; } if (targetClass == null) { Debug.LogWarningFormat("Class type not found: " + targetClassName); return null; } ValidateTargetClass(targetClass, attributeInterface); return targetClass; } private static void ValidateTargetClass(Type targetClass, Type attributeInterface) { var constructorInfos = targetClass.GetConstructors(); if (constructorInfos.All(constructor => constructor.GetParameters().Length != 0)) { Debug.LogWarningFormat("{0} does not implement default constructor", targetClass.Name); } if (!attributeInterface.IsAssignableFrom(targetClass)) { Debug.LogWarningFormat("{0} does not implement {1}", targetClass.Name, attributeInterface.Name); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/AttributeHelper.cs.meta ================================================ fileFormatVersion: 2 guid: ae8ce3ffe04ac2c42945fd27e0291fc3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/ColorEqualityComparer.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class ColorEqualityComparer : IEqualityComparer { private const float k_DefaultError = 0.01f; private readonly float AllowedError; private static readonly ColorEqualityComparer m_Instance = new ColorEqualityComparer(); public static ColorEqualityComparer Instance { get { return m_Instance; } } private ColorEqualityComparer() : this(k_DefaultError) { } public ColorEqualityComparer(float error) { this.AllowedError = error; } public bool Equals(Color expected, Color actual) { return Utils.AreFloatsEqualAbsoluteError(expected.r, actual.r, AllowedError) && Utils.AreFloatsEqualAbsoluteError(expected.g, actual.g, AllowedError) && Utils.AreFloatsEqualAbsoluteError(expected.b, actual.b, AllowedError) && Utils.AreFloatsEqualAbsoluteError(expected.a, actual.a, AllowedError); } public int GetHashCode(Color color) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/ColorEqualityComparer.cs.meta ================================================ fileFormatVersion: 2 guid: d6105bc8cf5ce544487daca4cbc62583 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/CoroutineRunner.cs ================================================ using System; using System.Collections; using NUnit.Framework.Internal; using UnityEngine.TestRunner.NUnitExtensions.Runner; namespace UnityEngine.TestTools.Utils { internal class CoroutineRunner { private bool m_Running; private bool m_TestFailed; private bool m_Timeout; private readonly MonoBehaviour m_Controller; private readonly UnityTestExecutionContext m_Context; private Coroutine m_TimeOutCoroutine; private IEnumerator m_TestCoroutine; internal const int k_DefaultTimeout = 1000 * 180; public CoroutineRunner(MonoBehaviour playmodeTestsController, UnityTestExecutionContext context) { m_Controller = playmodeTestsController; m_Context = context; } public IEnumerator HandleEnumerableTest(IEnumerator testEnumerator) { if (m_Context.TestCaseTimeout == 0) { m_Context.TestCaseTimeout = k_DefaultTimeout; } do { if (!m_Running) { m_Running = true; m_TestCoroutine = ExMethod(testEnumerator, m_Context.TestCaseTimeout); m_Controller.StartCoroutine(m_TestCoroutine); } if (m_TestFailed) { StopAllRunningCoroutines(); yield break; } if (m_Context.ExecutionStatus == TestExecutionStatus.StopRequested || m_Context.ExecutionStatus == TestExecutionStatus.AbortRequested) { StopAllRunningCoroutines(); yield break; } yield return null; } while (m_Running); } private void StopAllRunningCoroutines() { if (m_TimeOutCoroutine != null) { m_Controller.StopCoroutine(m_TimeOutCoroutine); } if (m_TestCoroutine != null) { m_Controller.StopCoroutine(m_TestCoroutine); } } private IEnumerator ExMethod(IEnumerator e, int timeout) { m_TimeOutCoroutine = m_Controller.StartCoroutine(StartTimer(e, timeout, () => { m_TestFailed = true; m_Timeout = true; m_Running = false; })); yield return m_Controller.StartCoroutine(e); m_Controller.StopCoroutine(m_TimeOutCoroutine); m_Running = false; } private IEnumerator StartTimer(IEnumerator coroutineToBeKilled, int timeout, Action onTimeout) { yield return new WaitForSecondsRealtime(timeout / 1000f); if (coroutineToBeKilled != null) m_Controller.StopCoroutine(coroutineToBeKilled); if (onTimeout != null) onTimeout(); } public bool HasFailedWithTimeout() { return m_Timeout; } public int GetDefaultTimeout() { return k_DefaultTimeout; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/CoroutineRunner.cs.meta ================================================ fileFormatVersion: 2 guid: 24a158219395ebf44a60547b97784ddc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/FloatEqualityComparer.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class FloatEqualityComparer : IEqualityComparer { private const float k_DefaultError = 0.0001f; private readonly float AllowedError; private static readonly FloatEqualityComparer m_Instance = new FloatEqualityComparer(); public static FloatEqualityComparer Instance { get { return m_Instance; } } private FloatEqualityComparer() : this(k_DefaultError) {} public FloatEqualityComparer(float allowedError) { this.AllowedError = allowedError; } public bool Equals(float expected, float actual) { return Utils.AreFloatsEqual(expected, actual, AllowedError); } public int GetHashCode(float value) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/FloatEqualityComparer.cs.meta ================================================ fileFormatVersion: 2 guid: af5042802f06c804c8abddd544b77a4a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/IOuterUnityTestAction.cs ================================================ using System.Collections; using NUnit.Framework.Interfaces; namespace UnityEngine.TestTools { /// /// When implemented by an attribute, this interface implemented to provide actions to execute before setup and after teardown of tests. /// public interface IOuterUnityTestAction { /// Executed before each test is run /// The test that is going to be run. IEnumerator BeforeTest(ITest test); /// Executed after each test is run /// The test that has just been run. IEnumerator AfterTest(ITest test); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/IOuterUnityTestAction.cs.meta ================================================ fileFormatVersion: 2 guid: b9c2a6302985d3846b7b9f6fd9e2da9a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/IPostBuildCleanup.cs ================================================ namespace UnityEngine.TestTools { public interface IPostBuildCleanup { void Cleanup(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/IPostBuildCleanup.cs.meta ================================================ fileFormatVersion: 2 guid: ff67c526455160f4690a44f74dee4cbe MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/IPrebuildSceneSetup.cs ================================================ namespace UnityEngine.TestTools { public interface IPrebuildSetup { void Setup(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/IPrebuildSceneSetup.cs.meta ================================================ fileFormatVersion: 2 guid: acc16f0c684508f44813662a300c574b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/MonoBehaviourTest/IMonoBehaviourTest.cs ================================================ namespace UnityEngine.TestTools { public interface IMonoBehaviourTest { bool IsTestFinished {get; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/MonoBehaviourTest/IMonoBehaviourTest.cs.meta ================================================ fileFormatVersion: 2 guid: a002d3737b873954395b7cf862873ab8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/MonoBehaviourTest/MonoBehaviourTest.cs ================================================ namespace UnityEngine.TestTools { public class MonoBehaviourTest : CustomYieldInstruction where T : MonoBehaviour, IMonoBehaviourTest { public T component { get; } public GameObject gameObject { get { return component.gameObject; } } public MonoBehaviourTest(bool dontDestroyOnLoad = true) { var go = new GameObject("MonoBehaviourTest: " + typeof(T).FullName); component = go.AddComponent(); if (dontDestroyOnLoad) { Object.DontDestroyOnLoad(go); } } public override bool keepWaiting { get { return !component.IsTestFinished; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/MonoBehaviourTest/MonoBehaviourTest.cs.meta ================================================ fileFormatVersion: 2 guid: 164c9b1458eaab743a4b45c37a4d720d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/MonoBehaviourTest.meta ================================================ fileFormatVersion: 2 guid: ce8da628f68c7594b8b9a597fa52db7b folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/PostBuildCleanupAttribute.cs ================================================ using System; namespace UnityEngine.TestTools { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class PostBuildCleanupAttribute : Attribute { public PostBuildCleanupAttribute(Type targetClass) { TargetClass = targetClass; } public PostBuildCleanupAttribute(string targetClassName) { TargetClass = AttributeHelper.GetTargetClassFromName(targetClassName, typeof(IPostBuildCleanup)); } internal Type TargetClass { get; private set; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/PostBuildCleanupAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: 621fd19bcb071b64aa1d68f0271aa780 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/PrebuildSceneSetupAttribute.cs ================================================ using System; namespace UnityEngine.TestTools { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class PrebuildSetupAttribute : Attribute { public PrebuildSetupAttribute(Type targetClass) { TargetClass = targetClass; } public PrebuildSetupAttribute(string targetClassName) { TargetClass = AttributeHelper.GetTargetClassFromName(targetClassName, typeof(IPrebuildSetup)); } internal Type TargetClass { get; private set; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/PrebuildSceneSetupAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: d1b7ce919aa8864409412e809073cf96 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/QuaternionEqualityComparer.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class QuaternionEqualityComparer : IEqualityComparer { private const float k_DefaultError = 0.00001f; private readonly float AllowedError; private static readonly QuaternionEqualityComparer m_Instance = new QuaternionEqualityComparer(); public static QuaternionEqualityComparer Instance { get { return m_Instance; } } private QuaternionEqualityComparer() : this(k_DefaultError) {} public QuaternionEqualityComparer(float allowedError) { AllowedError = allowedError; } public bool Equals(Quaternion expected, Quaternion actual) { return Mathf.Abs(Quaternion.Dot(expected, actual)) > (1.0f - AllowedError); } public int GetHashCode(Quaternion quaternion) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/QuaternionEqualityComparer.cs.meta ================================================ fileFormatVersion: 2 guid: 3b28913f21577de429da928d6d05219f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/StacktraceFilter.cs ================================================ using System.Linq; using System.Text; namespace UnityEngine.TestTools.Utils { internal static class StackTraceFilter { private static readonly string[] s_FilteredLogMessages = { @"UnityEngine.DebugLogHandler:Internal_Log", @"UnityEngine.DebugLogHandler:Log", @"UnityEngine.Logger:Log", @"UnityEngine.Debug" }; private static readonly string[] s_LastMessages = { @"System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)", @"UnityEditor.TestTools.TestRunner.EditModeRunner:InvokeDelegator" }; public static string Filter(string inputStackTrace) { int idx; foreach (var lastMessage in s_LastMessages) { idx = inputStackTrace.IndexOf(lastMessage); if (idx != -1) inputStackTrace = inputStackTrace.Substring(0, idx); } var inputStackTraceLines = inputStackTrace.Split('\n'); var result = new StringBuilder(); foreach (var line in inputStackTraceLines) { if (s_FilteredLogMessages.Any(s => line.StartsWith(s))) continue; result.AppendLine(line); } return result.ToString(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/StacktraceFilter.cs.meta ================================================ fileFormatVersion: 2 guid: fc748d99f1f0d484a811a566fc7915ec MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Utils.cs ================================================ using System; namespace UnityEngine.TestTools.Utils { public static class Utils { public static bool AreFloatsEqual(float expected, float actual, float epsilon) { // special case for infinity if (expected == Mathf.Infinity || actual == Mathf.Infinity || expected == Mathf.NegativeInfinity || actual == Mathf.NegativeInfinity) return expected == actual; // we cover both relative and absolute tolerance with this check // which is better than just relative in case of small (in abs value) args // please note that "usually" approximation is used [i.e. abs(x)+abs(y)+1] // but we speak about test code so we dont care that much about performance // but we do care about checks being more precise return Math.Abs(actual - expected) <= epsilon * Mathf.Max(Mathf.Max(Mathf.Abs(actual), Mathf.Abs(expected)), 1.0f); } public static bool AreFloatsEqualAbsoluteError(float expected, float actual, float allowedAbsoluteError) { return Math.Abs(actual - expected) <= allowedAbsoluteError; } /// /// Analogous to GameObject.CreatePrimitive, but creates a primitive mesh renderer with fast shader instead of a default builtin shader. /// Optimized for testing performance. /// /// A GameObject with primitive mesh renderer and collider. public static GameObject CreatePrimitive(PrimitiveType type) { var prim = GameObject.CreatePrimitive(type); var renderer = prim.GetComponent(); if (renderer) renderer.sharedMaterial = new Material(Shader.Find("VertexLit")); return prim; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Utils.cs.meta ================================================ fileFormatVersion: 2 guid: 9502550ba4785e3499d6c9251fa2114b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector2ComparerWithEqualsOperator.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class Vector2ComparerWithEqualsOperator : IEqualityComparer { private static readonly Vector2ComparerWithEqualsOperator m_Instance = new Vector2ComparerWithEqualsOperator(); public static Vector2ComparerWithEqualsOperator Instance { get { return m_Instance; } } private Vector2ComparerWithEqualsOperator() {} public bool Equals(Vector2 expected, Vector2 actual) { return expected == actual; } public int GetHashCode(Vector2 vec2) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector2ComparerWithEqualsOperator.cs.meta ================================================ fileFormatVersion: 2 guid: 65701ebe8bada6b4785e9c7afe7f5bee MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector2EqualityComparer.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class Vector2EqualityComparer : IEqualityComparer { private const float k_DefaultError = 0.0001f; private readonly float AllowedError; private static readonly Vector2EqualityComparer m_Instance = new Vector2EqualityComparer(); public static Vector2EqualityComparer Instance { get { return m_Instance; } } private Vector2EqualityComparer() : this(k_DefaultError) { } public Vector2EqualityComparer(float error) { this.AllowedError = error; } public bool Equals(Vector2 expected, Vector2 actual) { return Utils.AreFloatsEqual(expected.x, actual.x, AllowedError) && Utils.AreFloatsEqual(expected.y, actual.y, AllowedError); } public int GetHashCode(Vector2 vec2) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector2EqualityComparer.cs.meta ================================================ fileFormatVersion: 2 guid: 58ad09607a0d62d458a78d7174665566 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector3ComparerWithEqualsOperator.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class Vector3ComparerWithEqualsOperator : IEqualityComparer { private static readonly Vector3ComparerWithEqualsOperator m_Instance = new Vector3ComparerWithEqualsOperator(); public static Vector3ComparerWithEqualsOperator Instance { get { return m_Instance; } } private Vector3ComparerWithEqualsOperator() {} public bool Equals(Vector3 expected, Vector3 actual) { return expected == actual; } public int GetHashCode(Vector3 vec3) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector3ComparerWithEqualsOperator.cs.meta ================================================ fileFormatVersion: 2 guid: 5b994928117e3db418da69c821da7e19 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector3EqualityComparer.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class Vector3EqualityComparer : IEqualityComparer { private const float k_DefaultError = 0.0001f; private readonly float AllowedError; private static readonly Vector3EqualityComparer m_Instance = new Vector3EqualityComparer(); public static Vector3EqualityComparer Instance { get { return m_Instance; } } private Vector3EqualityComparer() : this(k_DefaultError) {} public Vector3EqualityComparer(float allowedError) { this.AllowedError = allowedError; } public bool Equals(Vector3 expected, Vector3 actual) { return Utils.AreFloatsEqual(expected.x, actual.x, AllowedError) && Utils.AreFloatsEqual(expected.y, actual.y, AllowedError) && Utils.AreFloatsEqual(expected.z, actual.z, AllowedError); } public int GetHashCode(Vector3 vec3) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector3EqualityComparer.cs.meta ================================================ fileFormatVersion: 2 guid: 4bd2bc28ff24d5c488844851cb785db0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector4ComparerWithEqualsOperator.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class Vector4ComparerWithEqualsOperator : IEqualityComparer { private static readonly Vector4ComparerWithEqualsOperator m_Instance = new Vector4ComparerWithEqualsOperator(); public static Vector4ComparerWithEqualsOperator Instance { get { return m_Instance; } } private Vector4ComparerWithEqualsOperator() {} public bool Equals(Vector4 expected, Vector4 actual) { return expected == actual; } public int GetHashCode(Vector4 vec4) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector4ComparerWithEqualsOperator.cs.meta ================================================ fileFormatVersion: 2 guid: 44100f5f60f351348b9719b46d46cebe MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector4EqualityComparer.cs ================================================ using System.Collections.Generic; namespace UnityEngine.TestTools.Utils { public class Vector4EqualityComparer : IEqualityComparer { private const float k_DefaultError = 0.0001f; private readonly float AllowedError; private static readonly Vector4EqualityComparer m_Instance = new Vector4EqualityComparer(); public static Vector4EqualityComparer Instance { get { return m_Instance; } } private Vector4EqualityComparer() : this(k_DefaultError) {} public Vector4EqualityComparer(float allowedError) { this.AllowedError = allowedError; } public bool Equals(Vector4 expected, Vector4 actual) { return Utils.AreFloatsEqual(expected.x, actual.x, AllowedError) && Utils.AreFloatsEqual(expected.y, actual.y, AllowedError) && Utils.AreFloatsEqual(expected.z, actual.z, AllowedError) && Utils.AreFloatsEqual(expected.w, actual.w, AllowedError); } public int GetHashCode(Vector4 vec4) { return 0; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils/Vector4EqualityComparer.cs.meta ================================================ fileFormatVersion: 2 guid: 32da81683c22faf458026716a2b821aa MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner/Utils.meta ================================================ fileFormatVersion: 2 guid: bb32bccaf32a6db448d1c0cc99c78688 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/UnityEngine.TestRunner.meta ================================================ fileFormatVersion: 2 guid: 950890083f4907541a6ed06d70959e49 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/package.json ================================================ { "name": "com.unity.test-framework", "displayName": "Test Framework", "version": "1.0.13", "unity": "2019.2", "unityRelease": "0a10", "description": "Test framework for running Edit mode and Play mode test in Unity.", "keywords": [ "Test", "TestFramework" ], "category": "Unity Test Framework", "repository": { "type": "git", "url": "git@gitlab.cds.internal.unity3d.com/upm-packages/core/com.unity.test-framework.git", "revision": "8d09534f1c9f96b37fa38167a8697e5965ab58b8" }, "dependencies": { "com.unity.ext.nunit": "1.0.0" }, "relatedPackages": { "com.unity.test-framework.tests": "1.0.13" } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.test-framework@1.0.13/package.json.meta ================================================ fileFormatVersion: 2 guid: d6a2e6e4803de7b43baacdc355fc144d TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/.gitlab-ci.yml ================================================ image: node:6.10.0 stages: - push_to_packman_staging push_to_packman_staging: stage: push_to_packman_staging only: - tags script: - curl -u $USER_NAME:$API_KEY https://staging-packages.unity.com/auth > .npmrc - npm publish ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/CHANGELOG.md ================================================ # Changelog These are the release notes for the TextMesh Pro UPM package which was first introduced with Unity 2018.1. Please see the following link for the Release Notes for prior versions of TextMesh Pro. http://digitalnativestudios.com/forum/index.php?topic=1363.0 ## [2.0.1] - 2019-05-08 ### Changes - See Release 1.4.1 - Requires .Net 4.x Scripting Runtime. ## [2.0.0] - 2019-03-01 ### Changes - Same release as 1.4.0 ## [1.4.1] - 2019-05-08 ### Changes - Improved handling of automatic Font Asset upgrade to version 1.1.0 which is required to support the new Dynamic SDF system. See Case #1144858 - Made release compatible with .Net 3.5 Scripting Runtime. - Added support for Stereo rendering to the TMP SDF Overlay shaders. - Fixed Caret positioning issue when using IME. Case #1146626 ## [1.4.0] - 2019-03-07 ### Changes - Same release as 1.4.0-preview.3a. ## [1.4.0-preview.3a] - 2019-02-28 ### Changes - Improved performance of the Project Files GUID Remapping Tool. - Fixed an issue with the TMP_FontAsset.TryAddCharacters() functions which was resulting in an error when added characters exceeded the capacity of the atlas texture. - Updated TMP_FontAsset.TryAddCharacters functions to add new overloads returning list of characters that could not be added. - Added function in OnEnable of FontAsset Editor's to clean up Fallback list to remove any null / empty entries. - Added support for Stereo rendering to the TMP Distance Field and Mobile Distance Field shaders. ## [1.4.0-preview.2a] - 2019-02-14 ### Changes - Fixed an issue with SDF Scale handling where the text object would not render correctly after the object scale had been set to zero. - Fixed an issue with the TMP_UpdateManager where text objects were not getting unregistered correctly. - Any changes to Font Asset Creation Settings' padding, atlas width and / or atlas height will now result in all Material Presets for the given font asset to also be updated. - Added new section in the TMP Settings related to the new Dynamic Font System. - Added new property in the Dynamic Font System section to determine if OpenType Font Features will be retrieved from source font files at runtime as new characters are added to font assets. Glyph Adjustment Data (Kerning) is the only feature currently supported. - Fix an issue where font assets created at runtime were not getting their asset version number set to "1.1.0". - Improved parsing of the text file used in the Font Asset Creator and "Characters from File" option to handle UTF16 "\u" and UTF32 "\U" escape character sequences. - Fixed a Null Reference Error (NRE) that could occur when using the <font> tag with an invalid font name followed by the <sprite> tag. - The Glyph Adjustment Table presentation and internal data structure has been changed to facilitate the future addition of OpenType font features. See https://forum.unity.com/threads/version-1-4-0-preview-with-dynamic-sdf-for-unity-2018-3-now-available.622420/#post-4206595 for more details. - Fixed an issue with the <rotate> tag incorrectly affecting character spacing. ## [1.4.0-preview.1] - 2019-01-30 ### Changes - Renamed TMPro_FontUtilities to TMP_FontAssetCommon to more accurately reflect the content of this file. - Accessing the TextMesh Pro Settings via the new Edit - Settings menu when TMP Essential Resources have not yet been imported in the project will no longer open a new window to provide the options to import these resources. - Fixed an issue where using int.MaxValue, int.MinValue, float.MaxValue and float.MinValue in conjunction with SetText() would display incorrect numerical values. Case #1078521. - Added public setter to the TMP Settings' missingGlyphCharacter to allow changing which character will be used for missing characters via scripting. - Fixed a potential Null Reference Exception related to loading the Default Style Sheet. - Added compiler conditional to TMP_UpdateManager.cs to address changes to SRP. - Improved the <margin> tag to make it possible to define both left and right margin values. Example: <margin left=10% right=10px>. - Added new menu option to allow the quick creation of a UI Button using TMP. New menu option is located in Create - UI - Button (TextMeshPro). - Renamed TMP related create menu options. - Fixed TMP object creation handling when using Prefab isolation mode. Case #1077392 - Fixed another issue related to Prefabs where some serialized properties of the text object would incorrectly show up in the Overrides prefab options. Case #1093101 - Fixed issue where changing the Sorting Layer or Sorting Order of a object would not dirty the scene. Case #1069776 - Fixed a text alignment issue when setting text alignment on disabled text objects. Case #1047771 - Fixed an issue where text object bounds were not set correctly on newly created text objects or in some cases when setting the text to null or string.empty. Case #1093388 - Fixed an issue in the IntToString() function that could result in Index Out Of Bounds error. Case #1102007 - Changed the TMP_InputField IsValidChar function to protected virtual. - The "Allow Rich Text Editing" property of the TMP_InputField is now set to false by default. - Added new option to the Sprite Asset context menu to make it easier to update sprite glyphs edited via the Unity Sprite Editor. - Added new Sharpness slider in the Debug section of the SDF Material inspector. - Fixed an error that would occur when using the context menu Reset on text component. Case #1044726 - Fixed issue where CharacterInfo.index would be incorrect as a result of using Surrogate Pairs in the text. Case #1037828 - The TMP_EditorPanel and TMP_UiEditorPanel now have their "UseForChildren" flag set to true to enable user / custom inspectors to inherit from them. - Fixed an issue where rich text tags using pixel (px) or font units (em) were not correctly accounting for orthographic camera mode. This change only affects the normal TMP text component. - Fixed an inspector issue related to changes to the margin in the TMP Extra Settings panel. Case #1114253 - Added new property to Glyph Adjustment Pairs which determines if Character Spacing Adjustments should affect the given pair. - Updated the Glyph Adjustment Table where ID now represents the unicode (hex) value for the character instead of its decimal value. - Added new SetValueWithoutNotify() function to TMP_DropDown and SetTextWithoutNotify() function to TMP_InputField allowing these to be set without triggering OnValueChanged event. - Geometry buffer deallocation which normally takes place when current allocations exceed those of the new text by more than 256 characters will no longer occur if the new text is set to null or string.empty. - Fixed a minor issue where the underline SDF scale would be incorrect when the underline text sequence contained normal size characters and ended with a subscript or superscript character. - Fixed an error that would occur when using the Reset Context menu on a Material using the SDF Surface or Mobile SDF Surface Shaders. Case #1122279 - Resolved a Null Reference Error that would appear when cycling through the text overflow modes. Case #1121624 ## [1.3.0] - 2018-08-09 ### Changes - Revamped UI to conform to Unity Human Interface Guidelines. - Updated the title text on the Font Asset Creator window tab to "Font Asset Creator". - Using TMP_Text.SetCharArray() with an empty char[] array will now clear the text. - Made a small improvement to the TMP Input Field when using nested 2d RectMasks. - Renamed symbol defines used by TMP to append TMP_ in front of the define to avoid potential conflicts with user defines. - Improved the Project Files GUID Remapping tool to allow specifying a target folder to scan. - Added the ability to cancel the scanning process used by the Project Files GUID Remapping tool. - Moved TMP Settings to universal settings window in 2018.3 and above. - Changing style sheet in the TMP Settings will now be reflected automatically on existing text objects in the editor. - Added new function TMP_StyleSheet.UpdateStyleSheet() to update the internal reference to which style sheet text objects should be using in conjunction with the style tag. ## [1.2.4] - 2018-06-10 ### Changes - Fixed a minor issue when using Justified and Flush alignment in conjunction with \u00A0. - The Font Asset creationSettings field is no longer an Editor only serialized field. ## [1.2.3] - 2018-05-29 ### Changes - Added new bitmap shader with support for Custom Font Atlas texture. This shader also includes a new property "Padding" to provide control over the geometry padding to closely fit a modified / custom font atlas texture. - Fixed an issue with ForceMeshUpdate(bool ignoreActiveState) not being handled correctly. - Cleaned up memory allocations from repeated use of the Font Asset Creator. - Sprites are now scaled based on the current font instead of the primary font asset assigned to the text object. - It is now possible to recall the most recent settings used when creating a font asset in the Font Asset Creator. - Newly created font assets now contain the settings used when they were last created. This will make the process of updating / regenerating font assets much easier. - New context menu "Update Font Asset" was added to the Font Asset inspector which will open the Font Asset Creator with the most recently used settings for that font asset. - New Context Menu "Create Font Asset" was added to the Font inspector panel which will open the Font Asset Creator with this source font file already selected. - Fixed 3 compiler warnings that would appear when using .Net 4.x. - Modified the TMP Settings to place the Missing Glyph options in their own section. - Renamed a symbol used for internal debugging to avoid potential conflicts with other user project defines. - TMP Sprite Importer "Create Sprite Asset" and "Save Sprite Asset" options are disabled unless a Sprite Data Source, Import Format and Sprite Texture Atlas are provided. - Improved the performance of the Project Files GUID Remapping tool. - Users will now be prompted to import the TMP Essential Resources when using the Font Asset Creator if such resources have not already been imported. ## [1.2.2] - 2018-03-28 ### Changes - Calling SetAllDirty() on a TMP text component will now force a regeneration of the text object including re-parsing of the text. - Fixed potential Null Reference Exception that could occur when assigning a new fallback font asset. - Removed public from test classes. - Fixed an issue where using nested links (which doesn't make sense conceptually) would result in an error. Should accidental use of nested links occurs, the last / most nested ends up being used. - Fixed a potential text alignment issue where an hyphen at the end of a line followed by a new line containing a single word too long to fit the text container would result in miss alignment of the hyphen. - Updated package license. - Non-Breaking Space character (0xA0) will now be excluded from word spacing adjustments when using Justified or Flush text alignment. - Improved handling of Underline, Strikethrough and Mark tag with regards to vertex color and Color tag alpha. - Improved TMP_FontAsset.HasCharacter(char character, bool searchFallbacks) to include a recursive search of fallbacks as well as TMP Settings fallback list and default font asset. - The <gradient> tag will now also apply to sprites provided the sprite tint attribute is set to a value of 1. Ex. <sprite="Sprite Asset" index=0 tint=1>. - Updated Font Asset Creator Plugin to allow for cancellation of the font asset generation process. - Added callback to support the Scriptable Render Pipeline (SRP) with the normal TextMeshPro component. - Improved handling of some non-breaking space characters which should not be ignored at the end of a line. - Sprite Asset fallbacks will now be searched when using the <sprite> tag and referencing a sprite by Unicode or by Name. - Updated EmojiOne samples from https://www.emojione.com/ and added attribution. - Removed the 32bit versions of the TMP Plugins used by the Font Asset Creator since the Unity Editor is now only available as 64bit. - The isTextTruncated property is now serialized. - Added new event handler to the TMP_TextEventHandler.cs script included in Example 12a to allow tracking of interactions with Sprites. ## [1.2.1] - 2018-02-14 ### Changes - Package is now backwards compatible with Unity 2018.1. - Renamed Assembly Definitions (.asmdef) to new UPM package conventions. - Added DisplayName for TMP UPM package. - Revised Editor and Playmode tests to ignore / skip over the tests if the required resources are not present in the project. - Revised implementation of Font Asset Creator progress bar to use Unity's EditorGUI.ProgressBar instead of custom texture. - Fixed an issue where using the material tag in conjunction with fallback font assets was not handled correctly. - Fixed an issue where changing the fontStyle property in conjunction with using alternative typefaces / font weights would not correctly trigger a regeneration of the text object. ## [1.2.0] - 2018-01-23 ### Changes - Package version # increased to 1.2.0 which is the first release for Unity 2018.2. ## [1.1.0] - 2018-01-23 ### Changes - Package version # increased to 1.1.0 which is the first release for Unity 2018.1. ## [1.0.27] - 2018-01-16 ### Changes - Fixed an issue where setting the TMP_InputField.text property to null would result in an error. - Fixed issue with Raycast Target state not getting serialized properly when saving / reloading a scene. - Changed reference to PrefabUtility.GetPrefabParent() to PrefabUtility.GetCorrespondingObjectFromSource() to reflect public API change in 2018.2 - Option to import package essential resources will only be presented to users when accessing a TMP component or the TMP Settings file via the project menu. ## [1.0.26] - 2018-01-10 ### Added - Removed Tizen player references in the TMP_InputField as the Tizen player is no longer supported as of Unity 2018.1. ## [1.0.25] - 2018-01-05 ### Added - Fixed a minor issue with PreferredValues calculation in conjunction with using text auto-sizing. - Improved Kerning handling where it is now possible to define positional adjustments for the first and second glyph in the pair. - Renamed Kerning Info Table to Glyph Adjustment Table to better reflect the added functionality of this table. - Added Search toolbar to the Glyph Adjustment Table. - Fixed incorrect detection / handling of Asset Serialization mode in the Project Conversion Utility. - Removed SelectionBase attribute from TMP components. - Revised TMP Shaders to support the new UNITY_UI_CLIP_RECT shader keyword which can provide a performance improvement of up to 30% on some devices. - Added TMP_PRESENT define as per the request of several third party asset publishers. ## [1.0.23] - 2017-11-14 ### Added - New menu option added to Import Examples and additional content like Font Assets, Materials Presets, etc for TextMesh Pro. This new menu option is located in "Window -> TextMeshPro -> Import Examples and Extra Content". - New menu option added to Convert existing project files and assets created with either the Source Code or DLL only version of TextMesh Pro. Please be sure to backup your project before using this option. The new menu option is located in "Window -> TextMeshPro -> Project Files GUID Remapping Tool". - Added Assembly Definitions for the TMP Runtime and Editor scripts. - Added support for the UI DirtyLayoutCallback, DirtyVerticesCallback and DirtyMaterialCallback. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/CHANGELOG.md.meta ================================================ fileFormatVersion: 2 guid: 22464cf7ab0243a6bf9c79851183b002 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Documentation~/TextMeshPro.md ================================================ # **_TextMesh Pro User Guide_** #### **Overview** This User Guide was designed to provide first time users of TextMesh Pro with a basic overview of the features and functionality of the tool. #### **Installation** The TextMesh Pro UPM package is already included with the Unity Editor and as such does not require installation. TextMesh Pro "TMP" does however require adding resources to your project which are essential for using TextMesh Pro. To import the "*TMP Essential Resources*", please use the "*Window -> TextMeshPro -> Import TMP Essential Resources*" menu option. These resources will be added at the root of your project in the "*TextMesh Pro*" folder. The TextMesh Pro package also includes additional resources and examples that will make discovering and learning about TextMesh Pro's powerful features easier. It is strongly recommended that first time users import these additional resources. To import the "*TMP Examples & Extras*", please use the "*Window -> TextMeshPro -> Import TMP Examples & Extras*" menu option. These resources will also be added in the same "*TextMesh Pro*" folder inside your project. #### **Quick Start** There are two TextMesh Pro components available. The first TMP text component is of type <TextMeshPro> and designed to work with the MeshRenderer. This component is an ideal replacement for the legacy TextMesh component. To add a new <TextMeshPro> text object, go to: *GameObject->3D Object->TextMeshPro Text*. The second TMP text component is of type <TextMeshProUGUI> and designed to work with the CanvasRenderer and Canvas system. This component is an ideal replacement for the UI.Text component. To add a new <TextMeshProUGUI> text object, go to: *GameObject->UI->TextMeshPro Text*. You may also wish to watch this [Getting Started](https://youtu.be/olnxlo-Wri4) short video which covers this topic. We strongly recommend that you also watch the [Font Asset Creation](https://youtu.be/qzJNIGCFFtY) video as well as the [Working with Material Presets](https://youtu.be/d2MARbDNeaA) as these two topics is also key to working and getting the most out of TextMesh Pro. As mentionned in the Installation section of this guide, it is recommended that you import the "*TMP Examples & Extras*" and take the time to explore each of the examples as they provide a great overview of the functionality of the tool and the many text layout and [rich text tags](http://digitalnativestudios.com/textmeshpro/docs/rich-text/) available in TextMesh Pro. #### **Support & API Documentation** Should you have questions or require assistance, please visit the [Unity UI & TextMesh Pro](https://forum.unity.com/forums/unity-ui-textmesh-pro.60/) section of the Unity forum as well as the [TextMesh Pro User Forum](http://digitalnativestudios.com/forum/index.php) where you will find additional information, [Video Tutorials](http://digitalnativestudios.com/forum/index.php?board=4.0) and [FAQ](http://digitalnativestudios.com/forum/index.php?topic=890.0). In the event you are unable to find the information you seek, always feel free to post on the [Unity UI & TextMesh Pro](https://forum.unity.com/forums/unity-ui-textmesh-pro.60/) section user forum. [Online Documentation](http://digitalnativestudios.com/textmeshpro/docs/) is also available on TextMesh Pro including Rich Text tags, Shaders, Scripting API and more. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Documentation~/TextMeshPro.md.meta ================================================ fileFormatVersion: 2 guid: ca77d26d10b9455ca5a4b22c93be2a31 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Gizmos/TMP - Dropdown Icon.psd.meta ================================================ fileFormatVersion: 2 guid: a7ec9e7ad8b847b7ae4510af83c5d868 TextureImporter: fileIDToRecycleName: {} externalObjects: {} serializedVersion: 7 mipmaps: mipMapMode: 0 enableMipMap: 0 sRGBTexture: 1 linearTexture: 1 fadeOut: 0 borderMipMap: 0 mipMapsPreserveCoverage: 0 alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: -2 maxTextureSize: 128 textureSettings: serializedVersion: 2 filterMode: -1 aniso: 1 mipBias: -100 wrapU: 1 wrapV: 1 wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 textureType: 2 textureShape: 1 singleChannelComponent: 0 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 platformSettings: - serializedVersion: 2 buildTarget: DefaultTexturePlatform maxTextureSize: 128 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: Standalone maxTextureSize: 128 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: iPhone maxTextureSize: 128 resizeAlgorithm: 0 textureFormat: 2 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: Android maxTextureSize: 128 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: Windows Store Apps maxTextureSize: 128 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: WebGL maxTextureSize: 128 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] physicsShape: [] bones: [] spriteID: vertices: [] indices: edges: [] weights: [] spritePackingTag: pSDRemoveMatte: 1 pSDShowRemoveMatteOption: 1 userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Gizmos/TMP - Font Asset Icon.psd.meta ================================================ fileFormatVersion: 2 guid: ee148e281f3c41c5b4ff5f8a5afe5a6c timeCreated: 1463559213 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 7 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 128 textureSettings: filterMode: -1 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Gizmos/TMP - Input Field Icon.psd.meta ================================================ fileFormatVersion: 2 guid: 3ee40aa79cd242a5b53b0b0ca4f13f0f timeCreated: 1457860876 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 128 textureSettings: filterMode: -1 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Gizmos/TMP - Sprite Asset Icon.psd.meta ================================================ fileFormatVersion: 2 guid: ec7c645d93308c04d8840982af12101e timeCreated: 1463559213 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 7 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 128 textureSettings: filterMode: -1 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Gizmos/TMP - Text Component Icon.psd.meta ================================================ fileFormatVersion: 2 guid: 2fd6421f253b4ef1a19526541f9ffc0c TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 128 textureSettings: filterMode: -1 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Gizmos.meta ================================================ fileFormatVersion: 2 guid: e93ec7eb6de342aabd156833e253f838 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Shaders/TMP_Properties.cginc ================================================ // UI Editable properties uniform sampler2D _FaceTex; // Alpha : Signed Distance uniform float _FaceUVSpeedX; uniform float _FaceUVSpeedY; uniform fixed4 _FaceColor; // RGBA : Color + Opacity uniform float _FaceDilate; // v[ 0, 1] uniform float _OutlineSoftness; // v[ 0, 1] uniform sampler2D _OutlineTex; // RGBA : Color + Opacity uniform float _OutlineUVSpeedX; uniform float _OutlineUVSpeedY; uniform fixed4 _OutlineColor; // RGBA : Color + Opacity uniform float _OutlineWidth; // v[ 0, 1] uniform float _Bevel; // v[ 0, 1] uniform float _BevelOffset; // v[-1, 1] uniform float _BevelWidth; // v[-1, 1] uniform float _BevelClamp; // v[ 0, 1] uniform float _BevelRoundness; // v[ 0, 1] uniform sampler2D _BumpMap; // Normal map uniform float _BumpOutline; // v[ 0, 1] uniform float _BumpFace; // v[ 0, 1] uniform samplerCUBE _Cube; // Cube / sphere map uniform fixed4 _ReflectFaceColor; // RGB intensity uniform fixed4 _ReflectOutlineColor; //uniform float _EnvTiltX; // v[-1, 1] //uniform float _EnvTiltY; // v[-1, 1] uniform float3 _EnvMatrixRotation; uniform float4x4 _EnvMatrix; uniform fixed4 _SpecularColor; // RGB intensity uniform float _LightAngle; // v[ 0,Tau] uniform float _SpecularPower; // v[ 0, 1] uniform float _Reflectivity; // v[ 5, 15] uniform float _Diffuse; // v[ 0, 1] uniform float _Ambient; // v[ 0, 1] uniform fixed4 _UnderlayColor; // RGBA : Color + Opacity uniform float _UnderlayOffsetX; // v[-1, 1] uniform float _UnderlayOffsetY; // v[-1, 1] uniform float _UnderlayDilate; // v[-1, 1] uniform float _UnderlaySoftness; // v[ 0, 1] uniform fixed4 _GlowColor; // RGBA : Color + Intesity uniform float _GlowOffset; // v[-1, 1] uniform float _GlowOuter; // v[ 0, 1] uniform float _GlowInner; // v[ 0, 1] uniform float _GlowPower; // v[ 1, 1/(1+4*4)] // API Editable properties uniform float _ShaderFlags; uniform float _WeightNormal; uniform float _WeightBold; uniform float _ScaleRatioA; uniform float _ScaleRatioB; uniform float _ScaleRatioC; uniform float _VertexOffsetX; uniform float _VertexOffsetY; //uniform float _UseClipRect; uniform float _MaskID; uniform sampler2D _MaskTex; uniform float4 _MaskCoord; uniform float4 _ClipRect; // bottom left(x,y) : top right(z,w) //uniform float _MaskWipeControl; //uniform float _MaskEdgeSoftness; //uniform fixed4 _MaskEdgeColor; //uniform bool _MaskInverse; uniform float _MaskSoftnessX; uniform float _MaskSoftnessY; // Font Atlas properties uniform sampler2D _MainTex; uniform float _TextureWidth; uniform float _TextureHeight; uniform float _GradientScale; uniform float _ScaleX; uniform float _ScaleY; uniform float _PerspectiveFilter; uniform float _Sharpness; ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Shaders/TMP_Properties.cginc.meta ================================================ fileFormatVersion: 2 guid: 3c6c403084eacec478a1129ce20061ea ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Shaders/TMP_SDF Internal SSD.shader ================================================ // Simplified SDF shader: // - No Shading Option (bevel / bump / env map) // - No Glow Option // - Softness is applied on both side of the outline Shader "Hidden/TextMeshPro/Internal/Distance Field SSD" { Properties { _FaceColor ("Face Color", Color) = (1,1,1,1) _FaceDilate ("Face Dilate", Range(-1,1)) = 0 _OutlineSoftness ("Outline Softness", Range(0,1)) = 0.02 _WeightNormal ("Weight Normal", float) = 0 _WeightBold ("Weight Bold", float) = .5 _MainTex ("Font Atlas", 2D) = "white" {} _TextureWidth ("Texture Width", float) = 512 _TextureHeight ("Texture Height", float) = 512 _GradientScale ("Gradient Scale", float) = 5 _ScaleX ("Scale X", float) = 1 _ScaleY ("Scale Y", float) = 1 _Sharpness ("Sharpness", Range(-1,1)) = 0 _VertexOffsetX ("Vertex OffsetX", float) = 0 _VertexOffsetY ("Vertex OffsetY", float) = 0 _ColorMask ("Color Mask", Float) = 15 } SubShader { Tags { "ForceSupported" = "True" } Lighting Off Blend One OneMinusSrcAlpha Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex VertShader #pragma fragment PixShader #include "UnityCG.cginc" #include "TMP_Properties.cginc" sampler2D _GUIClipTexture; uniform float4x4 unity_GUIClipTextureMatrix; struct vertex_t { float4 vertex : POSITION; float3 normal : NORMAL; fixed4 color : COLOR; float2 texcoord0 : TEXCOORD0; float2 texcoord1 : TEXCOORD1; }; struct pixel_t { float4 vertex : SV_POSITION; fixed4 faceColor : COLOR; float2 texcoord0 : TEXCOORD0; float2 clipUV : TEXCOORD1; }; pixel_t VertShader(vertex_t input) { // Does not handle simulated bold correctly. float4 vert = input.vertex; vert.x += _VertexOffsetX; vert.y += _VertexOffsetY; float4 vPosition = UnityObjectToClipPos(vert); float opacity = input.color.a; fixed4 faceColor = fixed4(input.color.rgb, opacity) * _FaceColor; faceColor.rgb *= faceColor.a; // Generate UV for the Clip Texture float3 eyePos = UnityObjectToViewPos(input.vertex); float2 clipUV = mul(unity_GUIClipTextureMatrix, float4(eyePos.xy, 0, 1.0)); // Structure for pixel shader pixel_t output = { vPosition, faceColor, float2(input.texcoord0.x, input.texcoord0.y), clipUV, }; return output; } half transition(half2 range, half distance) { return smoothstep(range.x, range.y, distance); } // PIXEL SHADER fixed4 PixShader(pixel_t input) : SV_Target { half distanceSample = tex2D(_MainTex, input.texcoord0).a; half smoothing = fwidth(distanceSample) * (1 - _Sharpness) + _OutlineSoftness; half contour = 0.5 - _FaceDilate * 0.5; half2 edgeRange = half2(contour - smoothing, contour + smoothing); half4 c = input.faceColor; half edgeTransition = transition(edgeRange, distanceSample); c *= edgeTransition; c *= tex2D(_GUIClipTexture, input.clipUV).a; return c; } ENDCG } } CustomEditor "TMPro.EditorUtilities.TMP_SDFShaderGUI" } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Shaders/TMP_SDF Internal SSD.shader.meta ================================================ fileFormatVersion: 2 guid: ce4ec0f498d1b1a4f90fe94e115b6f9a ShaderImporter: externalObjects: {} defaultTextures: [] nonModifiableTextures: [] userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Shaders.meta ================================================ fileFormatVersion: 2 guid: 2da27f5fe80a3a549ac7331d9f52f5f0 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/SectionHeader_Dark.psd.meta ================================================ fileFormatVersion: 2 guid: fb5730e24283d0c489e5c7d0bee023d9 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/SectionHeader_Light.psd.meta ================================================ fileFormatVersion: 2 guid: e3b0f810fdea84e40ab4ba20f256f7e8 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignBaseLine.psd.meta ================================================ fileFormatVersion: 2 guid: 8bc445bb79654bf496c92d0407840a92 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignBaseLine_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 18775b51e3bd42299fd30bd036ea982f TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignBottom.psd.meta ================================================ fileFormatVersion: 2 guid: ca51b19024094d1b87f3e07edb0a75fb TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignBottom_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 585b70cb75dd43efbfead809c30a1731 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignCapLine.psd.meta ================================================ fileFormatVersion: 2 guid: 0d9a36012a224080966c7b55896aa0f9 timeCreated: 1467964791 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 7 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: serializedVersion: 2 sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignCapLine_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 49679f302ac6408697f6b9314a38985c timeCreated: 1467964413 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 7 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: serializedVersion: 2 sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignCenter.psd.meta ================================================ fileFormatVersion: 2 guid: 81ed8c76d2bc4a4c95d092c98af4e58f TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignCenterGeo.psd.meta ================================================ fileFormatVersion: 2 guid: c76700ea0062413d9f69409b4e9e151b timeCreated: 1484171296 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignCenterGeo_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 35ff0937876540d3bd4b6a941df62a92 timeCreated: 1484171296 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignCenter_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 6ace62d30f494c948b71d5594afce11d TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignFlush.psd.meta ================================================ fileFormatVersion: 2 guid: 691475c57a824010be0c6f474caeb7e1 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignFlush_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 64b9fad609434c489c32b1cdf2004a1c TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignJustified.psd.meta ================================================ fileFormatVersion: 2 guid: 92027f7f8cfc4feaa477da0dc38d3d46 timeCreated: 1472535271 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 7 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 spriteTessellationDetail: -1 textureType: 2 buildTargetSettings: [] spriteSheet: serializedVersion: 2 sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignJustified_Light.psd.meta ================================================ fileFormatVersion: 2 guid: fa6bd40a216346b783a4cce741d277a5 timeCreated: 1472535778 licenseType: Pro TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 7 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 spriteTessellationDetail: -1 textureType: 2 buildTargetSettings: [] spriteSheet: serializedVersion: 2 sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignLeft.psd.meta ================================================ fileFormatVersion: 2 guid: 9288066c33474b94b6ee5465f4df1cc0 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignLeft_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 12736c98af174f91827a26b66d2b01b9 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignMidLine.psd.meta ================================================ fileFormatVersion: 2 guid: c2f7f6a88b4c4f20a53deb72f3d9144c timeCreated: 1426240649 licenseType: Store TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: serializedVersion: 2 sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignMiddle.psd.meta ================================================ fileFormatVersion: 2 guid: 41b96614b2e6494ba995ddcd252d11ae TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignMiddle_Light.psd.meta ================================================ fileFormatVersion: 2 guid: 066619c9c9c84f89acb1b48c11a7efe2 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignMidline_Light.psd.meta ================================================ fileFormatVersion: 2 guid: bb42b2d967d6427983c901a4ffc8ecd9 timeCreated: 1426240650 licenseType: Store TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 allowsAlphaSplitting: 0 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: serializedVersion: 2 sprites: [] outline: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignRight.psd.meta ================================================ fileFormatVersion: 2 guid: 342a0f8aca7f4f0691338912faec0494 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignRight_Light.psd.meta ================================================ fileFormatVersion: 2 guid: e05ace3bd15740cda0bad60d89092a5b TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignTop.psd.meta ================================================ fileFormatVersion: 2 guid: 48d034c499ee4697af9dd6e327110249 TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures/btn_AlignTop_Light.psd.meta ================================================ fileFormatVersion: 2 guid: ed041e68439749a69d0efa0e3d896c2e TextureImporter: fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 0 linearTexture: 1 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: filterMode: 0 aniso: 1 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 0 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 2 buildTargetSettings: [] spriteSheet: sprites: [] spritePackingTag: userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources/Textures.meta ================================================ fileFormatVersion: 2 guid: f8e6a2d47aba4c6c9b3c5a72d9f48da5 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Editor Resources.meta ================================================ fileFormatVersion: 2 guid: d1a0a27327b54c3bac52a08929c33f81 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/LICENSE.md ================================================ TextMesh Pro copyright © 2014-2019 Unity Technologies ApS Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions. ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/LICENSE.md.meta ================================================ fileFormatVersion: 2 guid: 0d2d0f36e67d4518a07df76235e91f9a TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Package Resources/TMP Essential Resources.unitypackage.meta ================================================ fileFormatVersion: 2 guid: ce4ff17ca867d2b48b5c8a4181611901 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Package Resources/TMP Examples & Extras.unitypackage.meta ================================================ fileFormatVersion: 2 guid: bc00e25696e4132499f56528d3fed2e3 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Package Resources.meta ================================================ fileFormatVersion: 2 guid: 5ec95f4d5b2d1f14e9ff8682562553f9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/PackageConversionData.json ================================================ { "assetRecords": [ { "referencedResource": "Blue to Purple - Vertical.asset", "target": "guid: 1e643bbd7e13d46418da3774e72bef60", "replacement": "guid: 479a66fa4b094512a62b0a8e553ad95a" }, { "referencedResource": "Dark to Light Green - Vertical.asset", "target": "guid: 90c9133b254e2184b8084dea4f392337", "replacement": "guid: 4c86a3366cd840348ebe8dc438570ee4" }, { "referencedResource": "Light to Dark Green - Vertical.asset", "target": "guid: 33c745f0979f3984182a138bcc6e57ec", "replacement": "guid: 5cf8ae092ca54931b443bec5148f3c59" }, { "referencedResource": "Yellow to Orange - Vertical.asset", "target": "guid: e002cb2a36d9e4a439a062867fa24e1e", "replacement": "guid: 69a525efa7e6472eab268f6ea605f06e" }, { "referencedResource": "Crate - Surface Shader Scene.mat", "target": "guid: e177c46c2a091564d88df2c2ca9dcf97", "replacement": "guid: e6b9b44320f4448d9d5e0ee634259966" }, { "referencedResource": "Ground - Logo Scene.mat", "target": "guid: 504ae362e57fc464b847f1e9fd0e4035", "replacement": "guid: c719e38f25a9480abd2480ab621a2949" }, { "referencedResource": "Ground - Surface Shader Scene.mat", "target": "guid: 9ed9aa864ec2d7f4dad266b9534c6d85", "replacement": "guid: aadd5a709a48466c887296bb5b1b8110" }, { "referencedResource": "Small Crate_diffuse.mat", "target": "guid: 92f161029a6d3c54a92d9d283352a135", "replacement": "guid: 22262639920f43d6be32430e4e58350d" }, { "referencedResource": "Text Popup.prefab", "target": "guid: c879e892866c8db4f8930b25672233ac", "replacement": "guid: b06f0e6c1dfa4356ac918da1bb32c603" }, { "referencedResource": "TextMeshPro - Prefab 1.prefab", "target": "guid: a6a60659abb4d9d4b934feebd3dcc952", "replacement": "guid: a6e39ced0ea046bcb636c3f0b2e2a745" }, { "referencedResource": "TextMeshPro - Prefab 2.prefab", "target": "guid: 1b190e3e0ab4c8e4881656b9160c59c2", "replacement": "guid: fdad9d952ae84cafb74c63f2e694d042" }, { "referencedResource": "Anton SDF.asset", "target": "guid: f76ef802b8b940c46a31f9027f2b0158", "replacement": "guid: 8a89fa14b10d46a99122fd4f73fca9a2" }, { "referencedResource": "Anton SDF - Drop Shadow.mat", "target": "guid: 250a1a103b3b4914c9707e6a423446d6", "replacement": "guid: 749b9069dc4742c5bfa5c74644049926" }, { "referencedResource": "Anton SDF - Outline.mat", "target": "guid: e077dc203e948b740859c1c0ca8b9691", "replacement": "guid: a00013af81304728b2be1f4309ee2433" }, { "referencedResource": "Bangers SDF.asset", "target": "guid: 808aa8f1ab804104aa7d0c337a6c1481", "replacement": "guid: 125cb55b44b24c4393181402bc6200e6" }, { "referencedResource": "Bangers SDF - Drop Shadow.mat", "target": "guid: c26f698d4eee19e4a8b8f42cd299bab5", "replacement": "guid: f2dcf029949142e28b974630369c8b4e" }, { "referencedResource": "Bangers SDF - Outline.mat", "target": "guid: db7f2cfbf23d6d54ca4e74a9abd55326", "replacement": "guid: f629c6e43dba4bf38cb74d8860150664" }, { "referencedResource": "Bangers SDF Glow.mat", "target": "guid: 7dd7006c58d8a3148a73aa211d8c13d0", "replacement": "guid: d75b8f41e959450c84ac6e967084d3e1" }, { "referencedResource": "Bangers SDF Logo.mat", "target": "guid: 4fb51aa7001a2244395ddf6a15d37389", "replacement": "guid: f4e195ac1e204eff960149d1cb34e18c" }, { "referencedResource": "Electronic Highway Sign SDF.asset", "target": "guid: 163292f6f226d954593d45b079f8aae0", "replacement": "guid: dc36b3fdc14f47ebb36fd484a67e268a" }, { "referencedResource": "LiberationSans SDF - Drop Shadow.mat", "target": "guid: 33db60c37b63f08448ded4b385e74e38", "replacement": "guid: e73a58f6e2794ae7b1b7e50b7fb811b0" }, { "referencedResource": "LiberationSans SDF - Metalic Green.mat", "target": "guid: 4f9843c79516ed1468b9b5a4f32e67e3", "replacement": "guid: 8b29aaa3eec7468097ff07adfcf29ac9" }, { "referencedResource": "LiberationSans SDF - Outline.mat", "target": "guid: 83a1b0fe6c3dbac44b66f09c82e1d509", "replacement": "guid: 79459efec17a4d00a321bdcc27bbc385" }, { "referencedResource": "LiberationSans SDF - Overlay.mat", "target": "guid: 55eb086ae18c76e4bb6cc7106d0dd6e2", "replacement": "guid: 9ad269c99dcf42b7aedefd83dd5a7b9d" }, { "referencedResource": "LiberationSans SDF - Soft Mask.mat", "target": "guid: 74e06d99c1657fc4abd33f20685ea9ff", "replacement": "guid: 42df1c7856584b6b8db9a509b6b10074" }, { "referencedResource": "Oswald Bold SDF.asset", "target": "guid: 09641b029dfa78843902b548a9de7553", "replacement": "guid: 0161d805a3764c089bef00bfe00793f5" }, { "referencedResource": "Roboto-Bold SDF.asset", "target": "guid: d62a573c923f5cb47b8ff65261033b90", "replacement": "guid: 5302535af1044152a457ed104f1f4b91" }, { "referencedResource": "Roboto-Bold SDF - Drop Shadow.mat", "target": "guid: 102e7c5c5e3b1f3468518cb166967d77", "replacement": "guid: b246c4190f4e46ec9352fe15a7b09ce0" }, { "referencedResource": "Roboto-Bold SDF - Surface.mat", "target": "guid: e2da38ead8f8238449c54a1ef49e080f", "replacement": "guid: e6b276ec991f467aa14ef1f3cc665993" }, { "referencedResource": "DropCap Numbers.asset", "target": "guid: c4fd2a959a50b584b92dedfefec1ffda", "replacement": "guid: 14aa93acbb234d16aaef0e8b46814db6" }, { "referencedResource": "Benchmark01.cs", "target": "guid: c5fb1b5c24460f745be29cc0eb06a58c", "replacement": "guid: f970ea55f9f84bf79b05dab180b8c125" }, { "referencedResource": "Benchmark01_UGUI.cs", "target": "guid: 5e6abf300e36c0a4eb43969c3f2172f8", "replacement": "guid: 8ef7be1c625941f7ba8ed7cc71718c0d" }, { "referencedResource": "Benchmark02.cs", "target": "guid: 3467f4170568a484d8b57e2051a27363", "replacement": "guid: e8538afcddc14efbb5d9e94b7ae50197" }, { "referencedResource": "Benchmark03.cs", "target": "guid: e6e9d20624a23da4c8b2b6fb7608bb9a", "replacement": "guid: a73109742c8d47ac822895a473300c29" }, { "referencedResource": "Benchmark04.cs", "target": "guid: 481dd67bdedc3104ea2156ed49f3acd5", "replacement": "guid: dc20866c0d5e413ab7559440e15333ae" }, { "referencedResource": "CameraController.cs", "target": "guid: a9f0e07aefca0cc459134ff9df622278", "replacement": "guid: 2d687537154440a3913a9a3c7977978c" }, { "referencedResource": "ChatController.cs", "target": "guid: eba5a4db2591a5844aea5f6f3ad8548e", "replacement": "guid: 53d91f98a2664f5cb9af11de72ac54ec" }, { "referencedResource": "EnvMapAnimator.cs", "target": "guid: 7e69f3f28c520ce4d9ab9964b2895b1a", "replacement": "guid: a4b6f99e8bc54541bbd149b014ff441c" }, { "referencedResource": "ObjectSpin.cs", "target": "guid: 5e7872ff51989434dabf7807265ada3c", "replacement": "guid: 4f19c7f94c794c5097d8bd11e39c750d" }, { "referencedResource": "ShaderPropAnimator.cs", "target": "guid: c56cf968fb6a5b6488e709242718845d", "replacement": "guid: 2787a46a4dc848c1b4b7b9307b614bfd" }, { "referencedResource": "SimpleScript.cs", "target": "guid: c64808ff5137c9044a583750e5b0468a", "replacement": "guid: 9eff140b25d64601aabc6ba32245d099" }, { "referencedResource": "SkewTextExample.cs", "target": "guid: 48d40dfeb33b717488f55ddbf676643a", "replacement": "guid: d412675cfb3441efa3bf8dcd9b7624dc" }, { "referencedResource": "TeleType.cs", "target": "guid: 9094c5c777af3f14489e8947748e86e6", "replacement": "guid: e32c266ee6204b21a427753cb0694c81" }, { "referencedResource": "TextConsoleSimulator.cs", "target": "guid: 45757dcc8f119454dac6365e8fd15e8b", "replacement": "guid: 43bcd35a1c0c40ccb6d472893fe2093f" }, { "referencedResource": "TextMeshProFloatingText.cs", "target": "guid: dd0e4b969aa70504382a89d2f208ae6c", "replacement": "guid: a4d4c76e63944cba8c7d00f56334b98c" }, { "referencedResource": "TextMeshSpawner.cs", "target": "guid: 385939aed18e82d41894437798c30ed8", "replacement": "guid: 76c11bbcfddf44e0ba17d6c2751c8d84" }, { "referencedResource": "TMP_ExampleScript_01.cs", "target": "guid: 36bafabb5572c6347923b971425ab3be", "replacement": "guid: 6f2c5b59b6874405865e2616e4ec276a" }, { "referencedResource": "TMP_FrameRateCounter.cs", "target": "guid: c0357609254b68d4881cab18f04dd4dc", "replacement": "guid: 686ec78b56aa445795335fbadafcfaa4" }, { "referencedResource": "TMP_TextEventCheck.cs", "target": "guid: ba181bda76b7f6047ba2188e94bf0894", "replacement": "guid: d736ce056cf444ca96e424f4d9c42b76" }, { "referencedResource": "TMP_TextEventHandler.cs", "target": "guid: 48a2fdbd95acd794caf78a85a0b6926a", "replacement": "guid: 1312ae25639a4bae8e25ae223209cc50" }, { "referencedResource": "TMP_TextInfoDebugTool.cs", "target": "guid: 5eeee4467ee5b6a4884a1ec94812d93e", "replacement": "guid: 21256c5b62f346f18640dad779911e20" }, { "referencedResource": "TMP_TextSelector_A.cs", "target": "guid: 68baf2864c88f4a43a50f16709de8717", "replacement": "guid: 103e0a6a1d404693b9fb1a5173e0e979" }, { "referencedResource": "TMP_TextSelector_B.cs", "target": "guid: f499ff45b9a3d0840a0df48d01b2877b", "replacement": "guid: a05dcd8be7ec4ccbb35c26219884aa37" }, { "referencedResource": "TMP_UiFrameRateCounter.cs", "target": "guid: dc33b7a34d20d5e4e8d54b6867ce81e3", "replacement": "guid: 24b0dc2d1d494adbbec1f4db26b4cf83" }, { "referencedResource": "TMPro_InstructionOverlay.cs", "target": "guid: 53b866620ba77504eaf52cab7dbd95c9", "replacement": "guid: c3c1afeda5e545e0b19add5373896d2e" }, { "referencedResource": "VertexColorCycler.cs", "target": "guid: c8d54cdd5913d4e4bb7b655d7d16835b", "replacement": "guid: 91b8ba3d52e041fab2d0e0f169855539" }, { "referencedResource": "VertexJitter.cs", "target": "guid: e4769cb37968ea948a763a9a89f9e583", "replacement": "guid: 2ed57967c52645d390a89dcf8f61ba73" }, { "referencedResource": "VertexShakeA.cs", "target": "guid: eaa12d191e718c945ac55da73fa469db", "replacement": "guid: f7cfa58e417a46ea8889989684c2522e" }, { "referencedResource": "VertexShakeB.cs", "target": "guid: 32c83a5d3ba42b84aa26386eac47566b", "replacement": "guid: e4e0d9ccee5f4950be8979268c9014e0" }, { "referencedResource": "VertexZoom.cs", "target": "guid: 5305493000edc7d4ea4302757dc19a99", "replacement": "guid: 52ec835d14bd486f900952b77698b7eb" }, { "referencedResource": "WarpTextExample.cs", "target": "guid: f3eef864a10f51045a7530e2afe7c179", "replacement": "guid: 790744c462254b7ba8038e6ed28b3db2" }, { "referencedResource": "DropCap Numbers.psd", "target": "guid: 28b41fef228d6814f90e541deaf9f262", "replacement": "guid: fd09957580ac4326916010f1f260975b" }, { "referencedResource": "Brushed Metal 3.jpg", "target": "guid: c30270e41dccf9441ab56d94261bdcfa", "replacement": "guid: f88677df267a41d6be1e7a6133e7d227" }, { "referencedResource": "Engraved Wall.jpg", "target": "guid: 93d6f74f2ef358e41989d4152b195f88", "replacement": "guid: e0f91e6569da4934a48d85bf8d3063f0" }, { "referencedResource": "Engraved Wall Normal.jpg", "target": "guid: 1edd0950293e8664094053a041548c23", "replacement": "guid: 20f91c93e7fb490f9496609c52ef3904" }, { "referencedResource": "Floor Cement.jpg", "target": "guid: ac5a0a5373b36e049bb7f98f88dbc244", "replacement": "guid: 283f897e4925411ebbaa758b4cb13fc2" }, { "referencedResource": "Floor Tiles 1 - diffuse.jpg", "target": "guid: 7bbfb8818476e4641ba3e75f5225eb69", "replacement": "guid: 85ac55597b97403c82fc6601a93cf241" }, { "referencedResource": "Floor Tiles 1 - normal.jpg", "target": "guid: e00d5a9a0944134448432ccacf221b95", "replacement": "guid: c45cd05946364f32aba704f0853a975b" }, { "referencedResource": "Fruit Jelly (B&W).jpg", "target": "guid: 74d8c208a0193e14ca6916bea88a2c52", "replacement": "guid: 1cdc5b506b1a4a33a53c30669ced1f51" }, { "referencedResource": "Gradient Diagonal (Color).jpg", "target": "guid: 2421a4955e71725448211e6bfbc7d7fb", "replacement": "guid: 2ce5c55e85304b819a1826ecbc839aa5" }, { "referencedResource": "Gradient Horizontal (Color).jpg", "target": "guid: 0bbb43aff4f7811419ffceb1b16cf3d6", "replacement": "guid: 6eb184de103d4b3f812b38561065192f" }, { "referencedResource": "Gradient Vertical (Color).jpg", "target": "guid: 3359915af07779e4e9a966df9eed764f", "replacement": "guid: 03d0538de6e24c0f819bfc9ce084dfa9" }, { "referencedResource": "Mask Zig-n-Zag.psd", "target": "guid: 04eb87e72b3c1c648ba47a869ee00505", "replacement": "guid: bb8dfcd263ad4eb383a33d74a720be6f" }, { "referencedResource": "Sand Normal Map.jpg", "target": "guid: 89e1b1c005d29cf4598ea861deb35a80", "replacement": "guid: 8b8c8a10edf94ddc8cc4cc4fcd5696a9" }, { "referencedResource": "Small Crate_diffuse.jpg", "target": "guid: 64734c9bc6df32149a0c9cb0b18693e1", "replacement": "guid: 602cb87b6a29443b8636370ea0751574" }, { "referencedResource": "Small Crate_normal.jpg", "target": "guid: 81b50d9cb6f3104448ec54c00a80101a", "replacement": "guid: 8878a782f4334ecbbcf683b3ac780966" }, { "referencedResource": "Stainless 03.png", "target": "guid: 40d7f27f614cc1043a1f7e19074f461c", "replacement": "guid: 83cb272f9ee046f6ab6636ca38af8db4" }, { "referencedResource": "Text Overflow - Linked Text Image 1.png", "target": "guid: 1fd8c568b1fcdbe43be65c1619cf3293", "replacement": "guid: 4ccf43d26c4748c792174516f4a8fcef" }, { "referencedResource": "Text Overflow - Linked Text UI Screenshot.png", "target": "guid: 7983d2ec0427c114a916ae3c4769dc10", "replacement": "guid: c76d18757a194d618355f05f815cb0a1" }, { "referencedResource": "Wipe Pattern - Circle.psd", "target": "guid: 6f5e9497d22a7a84193ec825e2eb41ac", "replacement": "guid: 10c49fcd9c64421db7c0133e61e55f97" }, { "referencedResource": "Wipe Pattern - Diagonal.psd", "target": "guid: 8ee4d366b96418044aa9f94b3e2de645", "replacement": "guid: ed5290d8df18488780e2996b9b882f01" }, { "referencedResource": "Wipe Pattern - Radial Double.psd", "target": "guid: 3e0e22da7c9570b498205179ef58ef38", "replacement": "guid: 7631f4eff8f74ed38eb3eb9db17134e1" }, { "referencedResource": "Wipe Pattern - Radial Quad.psd", "target": "guid: 05ffd580f33f74644a6025ec196860af", "replacement": "guid: 2b5e9ae96c5644d8bae932f8b4ca68a2" }, { "referencedResource": "LiberationSans SDF.asset", "target": "guid: 715b80e429c437e40867928a4e1fc975", "replacement": "guid: 8f586378b4e144a9851e7b34d9b748ee" }, { "referencedResource": "LineBreaking Following Characters.txt", "target": "guid: 312ba5b9e90627940866e19549a788cf", "replacement": "guid: fade42e8bc714b018fac513c043d323b" }, { "referencedResource": "LineBreaking Leading Characters.txt", "target": "guid: 8d713940fcbede142ae4a33ea0062b33", "replacement": "guid: d82c1b31c7e74239bff1220585707d2b" }, { "referencedResource": "TMP_Bitmap.shader", "target": "guid: edfcf888cd11d9245b91d2883049a57e", "replacement": "guid: 128e987d567d4e2c824d754223b3f3b0" }, { "referencedResource": "TMP_Bitmap-Mobile.shader", "target": "guid: d1cf17907700cb647aa3ea423ba38f2e", "replacement": "guid: 1e3b057af24249748ff873be7fafee47" }, { "referencedResource": "TMP_SDF.shader", "target": "guid: dca26082f9cb439469295791d9f76fe5", "replacement": "guid: 68e6db2ebdc24f95958faec2be5558d6" }, { "referencedResource": "TMP_SDF Overlay.shader", "target": "guid: 4a7755d6b5b67874f89c85f56f95fe97", "replacement": "guid: dd89cf5b9246416f84610a006f916af7" }, { "referencedResource": "TMP_SDF-Mobile.shader", "target": "guid: cafd18099dfc0114896e0a8b277b81b6", "replacement": "guid: fe393ace9b354375a9cb14cdbbc28be4" }, { "referencedResource": "TMP_SDF-Mobile Masking.shader", "target": "guid: afc255f7c2be52e41973a3d10a2e632d", "replacement": "guid: bc1ede39bf3643ee8e493720e4259791" }, { "referencedResource": "TMP_SDF-Mobile Overlay.shader", "target": "guid: 9ecb3fe313cb5f7478141eba4a2d54ed", "replacement": "guid: a02a7d8c237544f1962732b55a9aebf1" }, { "referencedResource": "TMP_SDF-Surface.shader", "target": "guid: 8e6b9842dbb1a5a4887378afab854e63", "replacement": "guid: f7ada0af4f174f0694ca6a487b8f543d" }, { "referencedResource": "TMP_SDF-Surface-Mobile.shader", "target": "guid: 3c2ea7753c1425145a74d106ec1cd852", "replacement": "guid: 85187c2149c549c5b33f0cdb02836b17" }, { "referencedResource": "TMP_Sprite.shader", "target": "guid: 3a1c68c8292caf046bd21158886c5e40", "replacement": "guid: cf81c85f95fe47e1a27f6ae460cf182c" }, { "referencedResource": "Default Sprite Asset.asset", "target": "guid: 273ca6c80b4b5d746b5e548f532bffd8", "replacement": "guid: fbef3c704dce48f08a44612d6c856c8d" }, { "referencedResource": "EmojiOne.asset", "target": "guid: 9a952e2781ef26940ae089f1053ef4ef", "replacement": "guid: c41005c129ba4d66911b75229fd70b45" }, { "referencedResource": "TMP Default Style Sheet.asset", "target": "guid: 54d1085f9a2fdea4587fcfc7dddcd4bc", "replacement": "guid: f952c082cb03451daed3ee968ac6c63e" }, { "referencedResource": "TMP Settings.asset", "target": "guid: 69ed5bac41eebaa4c97e9d2a4168c54f", "replacement": "guid: 3f5b5dff67a942289a9defa416b206f3" }, { "referencedResource": "TextContainer.cs", "target": "guid: 3b34fc186f40e8043b977d4fa70db8c5", "replacement": "guid: 32d40088a6124c578ad6b428df586e2e" }, { "referencedResource": "TextContainer.cs", "target": "fileID: 311004786, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 32d40088a6124c578ad6b428df586e2e" }, { "referencedResource": "TextMeshPro.cs", "target": "guid: 1a1578b9753d2604f98d608cb4239e2f", "replacement": "guid: 9541d86e2fd84c1d9990edf0852d74ab" }, { "referencedResource": "TextMeshPro.cs", "target": "fileID: -806885394, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab" }, { "referencedResource": "TextMeshProUGUI.cs", "target": "guid: 496f2e385b0c62542b5c739ccfafd8da", "replacement": "guid: f4688fdb7df04437aeb418b961361dc5" }, { "referencedResource": "TextMeshProUGUI.cs", "target": "fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5" }, { "referencedResource": "TMP_Asset.cs", "target": "guid: e2c4405608b405a4680436e183e53c45", "replacement": "guid: 3bda1886f58f4e0ab1139400b160c3ee" }, { "referencedResource": "TMP_Asset.cs", "target": "fileID: -659140726, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 3bda1886f58f4e0ab1139400b160c3ee" }, { "referencedResource": "TMP_ColorGradient.cs", "target": "guid: e90e18dd4a044ff4394833216e6bf4d2", "replacement": "guid: 54d21f6ece3b46479f0c328f8c6007e0" }, { "referencedResource": "TMP_ColorGradient.cs", "target": "fileID: 2108210716, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 54d21f6ece3b46479f0c328f8c6007e0" }, { "referencedResource": "TMP_Dropdown.cs", "target": "guid: 44cb1d34ddab9d449a05fc3747876be1", "replacement": "guid: 7b743370ac3e4ec2a1668f5455a8ef8a" }, { "referencedResource": "TMP_Dropdown.cs", "target": "fileID: 1148083418, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 7b743370ac3e4ec2a1668f5455a8ef8a" }, { "referencedResource": "TMP_FontAsset.cs", "target": "guid: 74dfce233ddb29b4294c3e23c1d3650d", "replacement": "guid: 71c1514a6bd24e1e882cebbe1904ce04" }, { "referencedResource": "TMP_FontAsset.cs", "target": "fileID: -667331979, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 71c1514a6bd24e1e882cebbe1904ce04" }, { "referencedResource": "TMP_InputField.cs", "target": "guid: 7b85855a3deaa2e44ac6741a6bbc85f6", "replacement": "guid: 2da0c512f12947e489f739169773d7ca" }, { "referencedResource": "TMP_InputField.cs", "target": "fileID: -1620774994, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca" }, { "referencedResource": "TMP_Settings.cs", "target": "guid: aafc3c7b9e915d64e8ec3d2c88b3a231", "replacement": "guid: 2705215ac5b84b70bacc50632be6e391" }, { "referencedResource": "TMP_Settings.cs", "target": "fileID: -395462249, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 2705215ac5b84b70bacc50632be6e391" }, { "referencedResource": "TMP_SpriteAsset.cs", "target": "guid: 90940d439ca0ef746af0b48419b92d2e", "replacement": "guid: 84a92b25f83d49b9bc132d206b370281" }, { "referencedResource": "TMP_SpriteAsset.cs", "target": "fileID: 2019389346, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 84a92b25f83d49b9bc132d206b370281" }, { "referencedResource": "TMP_StyleSheet.cs", "target": "guid: 13259b4ce497b194eb52a33d8eda0bdc", "replacement": "guid: ab2114bdc8544297b417dfefe9f1e410" }, { "referencedResource": "TMP_StyleSheet.cs", "target": "fileID: -1936749209, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: ab2114bdc8544297b417dfefe9f1e410" }, { "referencedResource": "TMP_SubMesh.cs", "target": "guid: bd950677b2d06c74494b1c1118584fff", "replacement": "guid: 07994bfe8b0e4adb97d706de5dea48d5" }, { "referencedResource": "TMP_SubMesh.cs", "target": "fileID: 1330537494, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 07994bfe8b0e4adb97d706de5dea48d5" }, { "referencedResource": "TMP_SubMeshUI.cs", "target": "guid: a5378e1f14d974d419f811d6b0861f20", "replacement": "guid: 058cba836c1846c3aa1c5fd2e28aea77" }, { "referencedResource": "TMP_SubMeshUI.cs", "target": "fileID: 1908110080, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 058cba836c1846c3aa1c5fd2e28aea77" }, { "referencedResource": "TMP_Text.cs", "target": "guid: 9ec8dc9c3fa2e5d41b939b5888d2f1e8", "replacement": "guid: 5143f58107604835ab1a5efa2d8818fd" }, { "referencedResource": "TMP_Text.cs", "target": "fileID: -1385168320, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 5143f58107604835ab1a5efa2d8818fd" }, { "referencedResource": "Default Sprite Asset.png", "target": "guid: 5b32c2d36abe44540bed74c1f787033b", "replacement": "guid: a0fc465d6cf04254a2938578735e2383" }, { "referencedResource": "EmojiOne.png", "target": "guid: 6ec706981a919c3489f0b061a40054e2", "replacement": "guid: dffef66376be4fa480fb02b19edbe903" } ] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/PackageConversionData.json.meta ================================================ fileFormatVersion: 2 guid: 05f5bfd584002f948982a1498890f9a9 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/PackageConversionData_Assets.json ================================================ { "assetRecords": [ { "referencedResource": "TMP_FontAsset.cs", "target": "guid: 74dfce233ddb29b4294c3e23c1d3650d", "replacement": "guid: 71c1514a6bd24e1e882cebbe1904ce04" }, { "referencedResource": "TMP_FontAsset.cs", "target": "fileID: -667331979, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 71c1514a6bd24e1e882cebbe1904ce04" }, { "referencedResource": "Anton SDF.asset", "target": "guid: f76ef802b8b940c46a31f9027f2b0158", "replacement": "guid: 8a89fa14b10d46a99122fd4f73fca9a2" }, { "referencedResource": "Bangers SDF.asset", "target": "guid: 808aa8f1ab804104aa7d0c337a6c1481", "replacement": "guid: 125cb55b44b24c4393181402bc6200e6" }, { "referencedResource": "Electronic Highway Sign SDF.asset", "target": "guid: 163292f6f226d954593d45b079f8aae0", "replacement": "guid: dc36b3fdc14f47ebb36fd484a67e268a" }, { "referencedResource": "Oswald Bold SDF.asset", "target": "guid: 09641b029dfa78843902b548a9de7553", "replacement": "guid: 0161d805a3764c089bef00bfe00793f5" }, { "referencedResource": "Roboto-Bold SDF.asset", "target": "guid: d62a573c923f5cb47b8ff65261033b90", "replacement": "guid: 5302535af1044152a457ed104f1f4b91" }, { "referencedResource": "LiberationSans SDF.asset", "target": "guid: 715b80e429c437e40867928a4e1fc975", "replacement": "guid: 8f586378b4e144a9851e7b34d9b748ee" }, { "referencedResource": "TMP_Bitmap.shader", "target": "guid: edfcf888cd11d9245b91d2883049a57e", "replacement": "guid: 128e987d567d4e2c824d754223b3f3b0" }, { "referencedResource": "TMP_Bitmap-Mobile.shader", "target": "guid: d1cf17907700cb647aa3ea423ba38f2e", "replacement": "guid: 1e3b057af24249748ff873be7fafee47" }, { "referencedResource": "TMP_SDF.shader", "target": "guid: dca26082f9cb439469295791d9f76fe5", "replacement": "guid: 68e6db2ebdc24f95958faec2be5558d6" }, { "referencedResource": "TMP_SDF Overlay.shader", "target": "guid: 4a7755d6b5b67874f89c85f56f95fe97", "replacement": "guid: dd89cf5b9246416f84610a006f916af7" }, { "referencedResource": "TMP_SDF-Mobile.shader", "target": "guid: cafd18099dfc0114896e0a8b277b81b6", "replacement": "guid: fe393ace9b354375a9cb14cdbbc28be4" }, { "referencedResource": "TMP_SDF-Mobile Masking.shader", "target": "guid: afc255f7c2be52e41973a3d10a2e632d", "replacement": "guid: bc1ede39bf3643ee8e493720e4259791" }, { "referencedResource": "TMP_SDF-Mobile Overlay.shader", "target": "guid: 9ecb3fe313cb5f7478141eba4a2d54ed", "replacement": "guid: a02a7d8c237544f1962732b55a9aebf1" }, { "referencedResource": "TMP_SDF-Surface.shader", "target": "guid: 8e6b9842dbb1a5a4887378afab854e63", "replacement": "guid: f7ada0af4f174f0694ca6a487b8f543d" }, { "referencedResource": "TMP_SDF-Surface-Mobile.shader", "target": "guid: 3c2ea7753c1425145a74d106ec1cd852", "replacement": "guid: 85187c2149c549c5b33f0cdb02836b17" }, { "referencedResource": "TMP_Sprite.shader", "target": "guid: 3a1c68c8292caf046bd21158886c5e40", "replacement": "guid: cf81c85f95fe47e1a27f6ae460cf182c" }, { "referencedResource": "TMP_ColorGradient.cs", "target": "guid: e90e18dd4a044ff4394833216e6bf4d2", "replacement": "guid: 54d21f6ece3b46479f0c328f8c6007e0" }, { "referencedResource": "TMP_ColorGradient.cs", "target": "fileID: 2108210716, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 54d21f6ece3b46479f0c328f8c6007e0" }, { "referencedResource": "TMP_Settings.cs", "target": "guid: aafc3c7b9e915d64e8ec3d2c88b3a231", "replacement": "guid: 2705215ac5b84b70bacc50632be6e391" }, { "referencedResource": "TMP_Settings.cs", "target": "fileID: -395462249, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 2705215ac5b84b70bacc50632be6e391" }, { "referencedResource": "TMP Settings.asset", "target": "guid: 69ed5bac41eebaa4c97e9d2a4168c54f", "replacement": "guid: 3f5b5dff67a942289a9defa416b206f3" }, { "referencedResource": "LineBreaking Following Characters.txt", "target": "guid: 312ba5b9e90627940866e19549a788cf", "replacement": "guid: fade42e8bc714b018fac513c043d323b" }, { "referencedResource": "LineBreaking Leading Characters.txt", "target": "guid: 8d713940fcbede142ae4a33ea0062b33", "replacement": "guid: d82c1b31c7e74239bff1220585707d2b" }, { "referencedResource": "TMP_StyleSheet.cs", "target": "guid: 13259b4ce497b194eb52a33d8eda0bdc", "replacement": "guid: ab2114bdc8544297b417dfefe9f1e410" }, { "referencedResource": "TMP_StyleSheet.cs", "target": "fileID: -1936749209, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: ab2114bdc8544297b417dfefe9f1e410" }, { "referencedResource": "TMP Default Style Sheet.asset", "target": "guid: 54d1085f9a2fdea4587fcfc7dddcd4bc", "replacement": "guid: f952c082cb03451daed3ee968ac6c63e" }, { "referencedResource": "TMP_SpriteAsset.cs", "target": "guid: 90940d439ca0ef746af0b48419b92d2e", "replacement": "guid: 84a92b25f83d49b9bc132d206b370281" }, { "referencedResource": "TMP_SpriteAsset.cs", "target": "fileID: 2019389346, guid: 89f0137620f6af44b9ba852b4190e64e", "replacement": "fileID: 11500000, guid: 84a92b25f83d49b9bc132d206b370281" }, { "referencedResource": "Default Sprite Asset.asset", "target": "guid: 273ca6c80b4b5d746b5e548f532bffd8", "replacement": "guid: fbef3c704dce48f08a44612d6c856c8d" }, { "referencedResource": "Default Sprite Asset.png", "target": "guid: 5b32c2d36abe44540bed74c1f787033b", "replacement": "guid: a0fc465d6cf04254a2938578735e2383" }, { "referencedResource": "EmojiOne.asset", "target": "guid: 9a952e2781ef26940ae089f1053ef4ef", "replacement": "guid: c41005c129ba4d66911b75229fd70b45" }, { "referencedResource": "EmojiOne.png", "target": "guid: 6ec706981a919c3489f0b061a40054e2", "replacement": "guid: dffef66376be4fa480fb02b19edbe903" }, { "referencedResource": "DropCap Numbers.asset", "target": "guid: c4fd2a959a50b584b92dedfefec1ffda", "replacement": "guid: 14aa93acbb234d16aaef0e8b46814db6" }, { "referencedResource": "DropCap Numbers.psd", "target": "guid: 28b41fef228d6814f90e541deaf9f262", "replacement": "guid: fd09957580ac4326916010f1f260975b" } ] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/PackageConversionData_Assets.json.meta ================================================ fileFormatVersion: 2 guid: 0e0afa652c0031c48896a97b424d027b TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/DropdownOptionListDrawer.cs ================================================ using UnityEditorInternal; using UnityEngine; using UnityEngine.UI; using UnityEditor; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_Dropdown.OptionDataList), true)] class DropdownOptionListDrawer : PropertyDrawer { private ReorderableList m_ReorderableList; private void Init(SerializedProperty property) { if (m_ReorderableList != null) return; SerializedProperty array = property.FindPropertyRelative("m_Options"); m_ReorderableList = new ReorderableList(property.serializedObject, array); m_ReorderableList.drawElementCallback = DrawOptionData; m_ReorderableList.drawHeaderCallback = DrawHeader; m_ReorderableList.elementHeight += 16; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { Init(property); m_ReorderableList.DoList(position); } private void DrawHeader(Rect rect) { GUI.Label(rect, "Options"); } private void DrawOptionData(Rect rect, int index, bool isActive, bool isFocused) { SerializedProperty itemData = m_ReorderableList.serializedProperty.GetArrayElementAtIndex(index); SerializedProperty itemText = itemData.FindPropertyRelative("m_Text"); SerializedProperty itemImage = itemData.FindPropertyRelative("m_Image"); RectOffset offset = new RectOffset(0, 0, -1, -3); rect = offset.Add(rect); rect.height = EditorGUIUtility.singleLineHeight; EditorGUI.PropertyField(rect, itemText, GUIContent.none); rect.y += EditorGUIUtility.singleLineHeight; EditorGUI.PropertyField(rect, itemImage, GUIContent.none); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { Init(property); return m_ReorderableList.GetHeight(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/DropdownOptionListDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: 9545c9eb3bf94265810463794fec8334 timeCreated: 1464818008 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/GlyphInfoDrawer.cs ================================================ /* using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_Glyph))] public class GlyphInfoDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_id = property.FindPropertyRelative("id"); SerializedProperty prop_x = property.FindPropertyRelative("x"); SerializedProperty prop_y = property.FindPropertyRelative("y"); SerializedProperty prop_width = property.FindPropertyRelative("width"); SerializedProperty prop_height = property.FindPropertyRelative("height"); SerializedProperty prop_xOffset = property.FindPropertyRelative("xOffset"); SerializedProperty prop_yOffset = property.FindPropertyRelative("yOffset"); SerializedProperty prop_xAdvance = property.FindPropertyRelative("xAdvance"); SerializedProperty prop_scale = property.FindPropertyRelative("scale"); // We get Rect since a valid position may not be provided by the caller. Rect rect = GUILayoutUtility.GetRect(position.width, 48); rect.y -= 15; //GUI.enabled = false; EditorGUIUtility.labelWidth = 40f; EditorGUIUtility.fieldWidth = 45f; bool prevGuiState = GUI.enabled; GUI.enabled = true; EditorGUI.LabelField(new Rect(rect.x + 5f, rect.y, 80f, 18), new GUIContent("Ascii: " + prop_id.intValue + ""), TMP_UIStyleManager.label); EditorGUI.LabelField(new Rect(rect.x + 90f, rect.y, 80f, 18), new GUIContent("Hex: " + prop_id.intValue.ToString("X") + ""), TMP_UIStyleManager.label); EditorGUI.LabelField(new Rect(rect.x + 170f, rect.y, 80, 18), "Char: [ " + (char)prop_id.intValue + " ]", TMP_UIStyleManager.label); GUI.enabled = prevGuiState; EditorGUIUtility.labelWidth = 35f; EditorGUIUtility.fieldWidth = 10f; float width = (rect.width - 5f) / 4; EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 0, rect.y + 22, width - 5f, 18), prop_x, new GUIContent("X:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 1, rect.y + 22, width - 5f, 18), prop_y, new GUIContent("Y:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 2, rect.y + 22, width - 5f, 18), prop_width, new GUIContent("W:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 3, rect.y + 22, width - 5f, 18), prop_height, new GUIContent("H:")); //GUI.enabled = true; EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 0, rect.y + 44, width - 5f, 18), prop_xOffset, new GUIContent("OX:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 1, rect.y + 44, width - 5f, 18), prop_yOffset, new GUIContent("OY:")); //GUI.enabled = true; EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 2, rect.y + 44, width - 5f, 18), prop_xAdvance, new GUIContent("ADV:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 3, rect.y + 44, width - 5f, 18), prop_scale, new GUIContent("SF:")); } } } */ ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/GlyphInfoDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: 900f1a451c764dc3bdcc0de815a15935 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/GlyphMetricsPropertyDrawer.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(GlyphMetrics))] public class GlyphMetricsPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_Width = property.FindPropertyRelative("m_Width"); SerializedProperty prop_Height = property.FindPropertyRelative("m_Height"); SerializedProperty prop_HoriBearingX = property.FindPropertyRelative("m_HorizontalBearingX"); SerializedProperty prop_HoriBearingY = property.FindPropertyRelative("m_HorizontalBearingY"); SerializedProperty prop_HoriAdvance = property.FindPropertyRelative("m_HorizontalAdvance"); // We get Rect since a valid position may not be provided by the caller. Rect rect = new Rect(position.x, position.y, position.width, 49); EditorGUI.LabelField(rect, new GUIContent("Glyph Metrics")); EditorGUIUtility.labelWidth = 30f; EditorGUIUtility.fieldWidth = 10f; //GUI.enabled = false; float width = (rect.width - 75f) / 2; EditorGUI.PropertyField(new Rect(rect.x + width * 0, rect.y + 20, width - 5f, 18), prop_Width, new GUIContent("W:")); EditorGUI.PropertyField(new Rect(rect.x + width * 1, rect.y + 20, width - 5f, 18), prop_Height, new GUIContent("H:")); //GUI.enabled = true; width = (rect.width - 75f) / 3; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(new Rect(rect.x + width * 0, rect.y + 40, width - 5f, 18), prop_HoriBearingX, new GUIContent("BX:")); EditorGUI.PropertyField(new Rect(rect.x + width * 1, rect.y + 40, width - 5f, 18), prop_HoriBearingY, new GUIContent("BY:")); EditorGUI.PropertyField(new Rect(rect.x + width * 2, rect.y + 40, width - 5f, 18), prop_HoriAdvance, new GUIContent("AD:")); if (EditorGUI.EndChangeCheck()) { } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 65f; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/GlyphMetricsPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: e3882522a08b6f5459b4dea6f8791278 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/GlyphRectPropertyDrawer.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(GlyphRect))] public class GlyphRectPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { //EditorGUI.BeginProperty(position, label, property); SerializedProperty prop_X = property.FindPropertyRelative("m_X"); SerializedProperty prop_Y = property.FindPropertyRelative("m_Y"); SerializedProperty prop_Width = property.FindPropertyRelative("m_Width"); SerializedProperty prop_Height = property.FindPropertyRelative("m_Height"); // We get Rect since a valid position may not be provided by the caller. Rect rect = new Rect(position.x, position.y, position.width, 49); EditorGUI.LabelField(rect, new GUIContent("Glyph Rect")); EditorGUIUtility.labelWidth = 30f; EditorGUIUtility.fieldWidth = 10f; //GUI.enabled = false; float width = (rect.width - 75f) / 4; EditorGUI.PropertyField(new Rect(rect.x + width * 0, rect.y + 20, width - 5f, 18), prop_X, new GUIContent("X:")); EditorGUI.PropertyField(new Rect(rect.x + width * 1, rect.y + 20, width - 5f, 18), prop_Y, new GUIContent("Y:")); EditorGUI.PropertyField(new Rect(rect.x + width * 2, rect.y + 20, width - 5f, 18), prop_Width, new GUIContent("W:")); EditorGUI.PropertyField(new Rect(rect.x + width * 3, rect.y + 20, width - 5f, 18), prop_Height, new GUIContent("H:")); //EditorGUI.EndProperty(); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 45f; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/GlyphRectPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: 8bc2b083b068f3546a9509c805e0541c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_BaseEditorPanel.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { public abstract class TMP_BaseEditorPanel : Editor { //Labels and Tooltips static readonly GUIContent k_RtlToggleLabel = new GUIContent("Enable RTL Editor", "Reverses text direction and allows right to left editing."); static readonly GUIContent k_MainSettingsLabel = new GUIContent("Main Settings"); static readonly GUIContent k_FontAssetLabel = new GUIContent("Font Asset", "The Font Asset containing the glyphs that can be rendered for this text."); static readonly GUIContent k_MaterialPresetLabel = new GUIContent("Material Preset", "The material used for rendering. Only materials created from the Font Asset can be used."); static readonly GUIContent k_AutoSizeLabel = new GUIContent("Auto Size", "Auto sizes the text to fit the available space."); static readonly GUIContent k_FontSizeLabel = new GUIContent("Font Size", "The size the text will be rendered at in points."); static readonly GUIContent k_AutoSizeOptionsLabel = new GUIContent("Auto Size Options"); static readonly GUIContent k_MinLabel = new GUIContent("Min", "The minimum font size."); static readonly GUIContent k_MaxLabel = new GUIContent("Max", "The maximum font size."); static readonly GUIContent k_WdLabel = new GUIContent("WD%", "Compresses character width up to this value before reducing font size."); static readonly GUIContent k_LineLabel = new GUIContent("Line", "Negative value only. Compresses line height down to this value before reducing font size."); static readonly GUIContent k_FontStyleLabel = new GUIContent("Font Style", "Styles to apply to the text such as Bold or Italic."); static readonly GUIContent k_BoldLabel = new GUIContent("B", "Bold"); static readonly GUIContent k_ItalicLabel = new GUIContent("I", "Italic"); static readonly GUIContent k_UnderlineLabel = new GUIContent("U", "Underline"); static readonly GUIContent k_StrikethroughLabel = new GUIContent("S", "Strikethrough"); static readonly GUIContent k_LowercaseLabel = new GUIContent("ab", "Lowercase"); static readonly GUIContent k_UppercaseLabel = new GUIContent("AB", "Uppercase"); static readonly GUIContent k_SmallcapsLabel = new GUIContent("SC", "Smallcaps"); static readonly GUIContent k_ColorModeLabel = new GUIContent("Color Mode", "The type of gradient to use."); static readonly GUIContent k_BaseColorLabel = new GUIContent("Vertex Color", "The base color of the text vertices."); static readonly GUIContent k_ColorPresetLabel = new GUIContent("Color Preset", "A Color Preset which override the local color settings."); static readonly GUIContent k_ColorGradientLabel = new GUIContent("Color Gradient", "The gradient color applied over the Vertex Color. Can be locally set or driven by a Gradient Asset."); static readonly GUIContent k_CorenerColorsLabel = new GUIContent("Colors", "The color composition of the gradient."); static readonly GUIContent k_OverrideTagsLabel = new GUIContent("Override Tags", "Whether the color settings override the tag."); static readonly GUIContent k_SpacingOptionsLabel = new GUIContent("Spacing Options", "Spacing adjustments between different elements of the text."); static readonly GUIContent k_CharacterSpacingLabel = new GUIContent("Character"); static readonly GUIContent k_WordSpacingLabel = new GUIContent("Word"); static readonly GUIContent k_LineSpacingLabel = new GUIContent("Line"); static readonly GUIContent k_ParagraphSpacingLabel = new GUIContent("Paragraph"); static readonly GUIContent k_AlignmentLabel = new GUIContent("Alignment", "Horizontal and vertical aligment of the text within its container."); static readonly GUIContent k_WrapMixLabel = new GUIContent("Wrap Mix (W <-> C)", "How much to favor words versus characters when distributing the text."); static readonly GUIContent k_WrappingLabel = new GUIContent("Wrapping", "Wraps text to the next line when reaching the edge of the container."); static readonly GUIContent[] k_WrappingOptions = { new GUIContent("Disabled"), new GUIContent("Enabled") }; static readonly GUIContent k_OverflowLabel = new GUIContent("Overflow", "How to display text which goes past the edge of the container."); static readonly GUIContent k_MarginsLabel = new GUIContent("Margins", "The space between the text and the edge of its container."); static readonly GUIContent k_GeometrySortingLabel = new GUIContent("Geometry Sorting", "The order in which text geometry is sorted. Used to adjust the way overlapping characters are displayed."); static readonly GUIContent k_RichTextLabel = new GUIContent("Rich Text", "Enables the use of rich text tags such as and ."); static readonly GUIContent k_EscapeCharactersLabel = new GUIContent("Parse Escape Characters", "Whether to display strings such as \"\\n\" as is or replace them by the character they represent."); static readonly GUIContent k_VisibleDescenderLabel = new GUIContent("Visible Descender", "Compute descender values from visible characters only. Used to adjust layout behavior when hiding and revealing characters dynamically."); static readonly GUIContent k_SpriteAssetLabel = new GUIContent("Sprite Asset", "The Sprite Asset used when NOT specifically referencing one using ."); static readonly GUIContent k_HorizontalMappingLabel = new GUIContent("Horizontal Mapping", "Horizontal UV mapping when using a shader with a texture face option."); static readonly GUIContent k_VerticalMappingLabel = new GUIContent("Vertical Mapping", "Vertical UV mapping when using a shader with a texture face option."); static readonly GUIContent k_LineOffsetLabel = new GUIContent("Line Offset", "Adds an horizontal offset to each successive line. Used for slanted texturing."); static readonly GUIContent k_KerningLabel = new GUIContent("Kerning", "Enables character specific spacing between pairs of characters."); static readonly GUIContent k_PaddingLabel = new GUIContent("Extra Padding", "Adds some padding between the characters and the edge of the text mesh. Can reduce graphical errors when displaying small text."); static readonly GUIContent k_LeftLabel = new GUIContent("Left"); static readonly GUIContent k_TopLabel = new GUIContent("Top"); static readonly GUIContent k_RightLabel = new GUIContent("Right"); static readonly GUIContent k_BottomLabel = new GUIContent("Bottom"); protected static readonly GUIContent k_ExtraSettingsLabel = new GUIContent("Extra Settings"); protected struct Foldout { // Track Inspector foldout panel states, globally. public static bool extraSettings = false; public static bool materialInspector = true; } protected static int s_EventId; public int selAlignGridA; public int selAlignGridB; protected SerializedProperty m_TextProp; protected SerializedProperty m_IsRightToLeftProp; protected string m_RtlText; protected SerializedProperty m_FontAssetProp; protected SerializedProperty m_FontSharedMaterialProp; protected Material[] m_MaterialPresets; protected GUIContent[] m_MaterialPresetNames; protected int m_MaterialPresetSelectionIndex; protected bool m_IsPresetListDirty; protected SerializedProperty m_FontStyleProp; protected SerializedProperty m_FontColorProp; protected SerializedProperty m_EnableVertexGradientProp; protected SerializedProperty m_FontColorGradientProp; protected SerializedProperty m_FontColorGradientPresetProp; protected SerializedProperty m_OverrideHtmlColorProp; protected SerializedProperty m_FontSizeProp; protected SerializedProperty m_FontSizeBaseProp; protected SerializedProperty m_AutoSizingProp; protected SerializedProperty m_FontSizeMinProp; protected SerializedProperty m_FontSizeMaxProp; protected SerializedProperty m_LineSpacingMaxProp; protected SerializedProperty m_CharWidthMaxAdjProp; protected SerializedProperty m_CharacterSpacingProp; protected SerializedProperty m_WordSpacingProp; protected SerializedProperty m_LineSpacingProp; protected SerializedProperty m_ParagraphSpacingProp; protected SerializedProperty m_TextAlignmentProp; protected SerializedProperty m_HorizontalMappingProp; protected SerializedProperty m_VerticalMappingProp; protected SerializedProperty m_UvLineOffsetProp; protected SerializedProperty m_EnableWordWrappingProp; protected SerializedProperty m_WordWrappingRatiosProp; protected SerializedProperty m_TextOverflowModeProp; protected SerializedProperty m_PageToDisplayProp; protected SerializedProperty m_LinkedTextComponentProp; protected SerializedProperty m_IsLinkedTextComponentProp; protected SerializedProperty m_EnableKerningProp; protected SerializedProperty m_IsRichTextProp; protected SerializedProperty m_HasFontAssetChangedProp; protected SerializedProperty m_EnableExtraPaddingProp; protected SerializedProperty m_CheckPaddingRequiredProp; protected SerializedProperty m_EnableEscapeCharacterParsingProp; protected SerializedProperty m_UseMaxVisibleDescenderProp; protected SerializedProperty m_GeometrySortingOrderProp; protected SerializedProperty m_SpriteAssetProp; protected SerializedProperty m_MarginProp; protected SerializedProperty m_ColorModeProp; protected bool m_HavePropertiesChanged; protected TMP_Text m_TextComponent; protected RectTransform m_RectTransform; protected Material m_TargetMaterial; protected Vector3[] m_RectCorners = new Vector3[4]; protected Vector3[] m_HandlePoints = new Vector3[4]; protected virtual void OnEnable() { m_TextProp = serializedObject.FindProperty("m_text"); m_IsRightToLeftProp = serializedObject.FindProperty("m_isRightToLeft"); m_FontAssetProp = serializedObject.FindProperty("m_fontAsset"); m_FontSharedMaterialProp = serializedObject.FindProperty("m_sharedMaterial"); m_FontStyleProp = serializedObject.FindProperty("m_fontStyle"); m_FontSizeProp = serializedObject.FindProperty("m_fontSize"); m_FontSizeBaseProp = serializedObject.FindProperty("m_fontSizeBase"); m_AutoSizingProp = serializedObject.FindProperty("m_enableAutoSizing"); m_FontSizeMinProp = serializedObject.FindProperty("m_fontSizeMin"); m_FontSizeMaxProp = serializedObject.FindProperty("m_fontSizeMax"); m_LineSpacingMaxProp = serializedObject.FindProperty("m_lineSpacingMax"); m_CharWidthMaxAdjProp = serializedObject.FindProperty("m_charWidthMaxAdj"); // Colors & Gradient m_FontColorProp = serializedObject.FindProperty("m_fontColor"); m_EnableVertexGradientProp = serializedObject.FindProperty("m_enableVertexGradient"); m_FontColorGradientProp = serializedObject.FindProperty("m_fontColorGradient"); m_FontColorGradientPresetProp = serializedObject.FindProperty("m_fontColorGradientPreset"); m_OverrideHtmlColorProp = serializedObject.FindProperty("m_overrideHtmlColors"); m_CharacterSpacingProp = serializedObject.FindProperty("m_characterSpacing"); m_WordSpacingProp = serializedObject.FindProperty("m_wordSpacing"); m_LineSpacingProp = serializedObject.FindProperty("m_lineSpacing"); m_ParagraphSpacingProp = serializedObject.FindProperty("m_paragraphSpacing"); m_TextAlignmentProp = serializedObject.FindProperty("m_textAlignment"); m_HorizontalMappingProp = serializedObject.FindProperty("m_horizontalMapping"); m_VerticalMappingProp = serializedObject.FindProperty("m_verticalMapping"); m_UvLineOffsetProp = serializedObject.FindProperty("m_uvLineOffset"); m_EnableWordWrappingProp = serializedObject.FindProperty("m_enableWordWrapping"); m_WordWrappingRatiosProp = serializedObject.FindProperty("m_wordWrappingRatios"); m_TextOverflowModeProp = serializedObject.FindProperty("m_overflowMode"); m_PageToDisplayProp = serializedObject.FindProperty("m_pageToDisplay"); m_LinkedTextComponentProp = serializedObject.FindProperty("m_linkedTextComponent"); m_IsLinkedTextComponentProp = serializedObject.FindProperty("m_isLinkedTextComponent"); m_EnableKerningProp = serializedObject.FindProperty("m_enableKerning"); m_EnableExtraPaddingProp = serializedObject.FindProperty("m_enableExtraPadding"); m_IsRichTextProp = serializedObject.FindProperty("m_isRichText"); m_CheckPaddingRequiredProp = serializedObject.FindProperty("checkPaddingRequired"); m_EnableEscapeCharacterParsingProp = serializedObject.FindProperty("m_parseCtrlCharacters"); m_UseMaxVisibleDescenderProp = serializedObject.FindProperty("m_useMaxVisibleDescender"); m_GeometrySortingOrderProp = serializedObject.FindProperty("m_geometrySortingOrder"); m_SpriteAssetProp = serializedObject.FindProperty("m_spriteAsset"); m_MarginProp = serializedObject.FindProperty("m_margin"); m_HasFontAssetChangedProp = serializedObject.FindProperty("m_hasFontAssetChanged"); m_ColorModeProp = serializedObject.FindProperty("m_colorMode"); m_TextComponent = (TMP_Text)target; m_RectTransform = m_TextComponent.rectTransform; // Create new Material Editor if one does not exists m_TargetMaterial = m_TextComponent.fontSharedMaterial; // Set material inspector visibility if (m_TargetMaterial != null) UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded(m_TargetMaterial, Foldout.materialInspector); // Find all Material Presets matching the current Font Asset Material m_MaterialPresetNames = GetMaterialPresets(); // Initialize the Event Listener for Undo Events. Undo.undoRedoPerformed += OnUndoRedo; } protected virtual void OnDisable() { // Set material inspector visibility if (m_TargetMaterial != null) Foldout.materialInspector = UnityEditorInternal.InternalEditorUtility.GetIsInspectorExpanded(m_TargetMaterial); if (Undo.undoRedoPerformed != null) Undo.undoRedoPerformed -= OnUndoRedo; } public override void OnInspectorGUI() { // Make sure Multi selection only includes TMP Text objects. if (IsMixSelectionTypes()) return; serializedObject.Update(); DrawTextInput(); DrawMainSettings(); DrawExtraSettings(); EditorGUILayout.Space(); if (m_HavePropertiesChanged) { m_HavePropertiesChanged = false; m_TextComponent.havePropertiesChanged = true; m_TextComponent.ComputeMarginSize(); EditorUtility.SetDirty(target); } serializedObject.ApplyModifiedProperties(); } public void OnSceneGUI() { if (IsMixSelectionTypes()) return; // Margin Frame & Handles m_RectTransform.GetWorldCorners(m_RectCorners); Vector4 marginOffset = m_TextComponent.margin; Vector3 lossyScale = m_RectTransform.lossyScale; m_HandlePoints[0] = m_RectCorners[0] + m_RectTransform.TransformDirection(new Vector3(marginOffset.x * lossyScale.x, marginOffset.w * lossyScale.y, 0)); m_HandlePoints[1] = m_RectCorners[1] + m_RectTransform.TransformDirection(new Vector3(marginOffset.x * lossyScale.x, -marginOffset.y * lossyScale.y, 0)); m_HandlePoints[2] = m_RectCorners[2] + m_RectTransform.TransformDirection(new Vector3(-marginOffset.z * lossyScale.x, -marginOffset.y * lossyScale.y, 0)); m_HandlePoints[3] = m_RectCorners[3] + m_RectTransform.TransformDirection(new Vector3(-marginOffset.z * lossyScale.x, marginOffset.w * lossyScale.y, 0)); Handles.DrawSolidRectangleWithOutline(m_HandlePoints, new Color32(255, 255, 255, 0), new Color32(255, 255, 0, 255)); // Draw & process FreeMoveHandles // LEFT HANDLE Vector3 oldLeft = (m_HandlePoints[0] + m_HandlePoints[1]) * 0.5f; Vector3 newLeft = Handles.FreeMoveHandle(oldLeft, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap); bool hasChanged = false; if (oldLeft != newLeft) { float delta = oldLeft.x - newLeft.x; marginOffset.x += -delta / lossyScale.x; //Debug.Log("Left Margin H0:" + handlePoints[0] + " H1:" + handlePoints[1]); hasChanged = true; } // TOP HANDLE Vector3 oldTop = (m_HandlePoints[1] + m_HandlePoints[2]) * 0.5f; Vector3 newTop = Handles.FreeMoveHandle(oldTop, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap); if (oldTop != newTop) { float delta = oldTop.y - newTop.y; marginOffset.y += delta / lossyScale.y; //Debug.Log("Top Margin H1:" + handlePoints[1] + " H2:" + handlePoints[2]); hasChanged = true; } // RIGHT HANDLE Vector3 oldRight = (m_HandlePoints[2] + m_HandlePoints[3]) * 0.5f; Vector3 newRight = Handles.FreeMoveHandle(oldRight, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap); if (oldRight != newRight) { float delta = oldRight.x - newRight.x; marginOffset.z += delta / lossyScale.x; hasChanged = true; //Debug.Log("Right Margin H2:" + handlePoints[2] + " H3:" + handlePoints[3]); } // BOTTOM HANDLE Vector3 oldBottom = (m_HandlePoints[3] + m_HandlePoints[0]) * 0.5f; Vector3 newBottom = Handles.FreeMoveHandle(oldBottom, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap); if (oldBottom != newBottom) { float delta = oldBottom.y - newBottom.y; marginOffset.w += -delta / lossyScale.y; hasChanged = true; //Debug.Log("Bottom Margin H0:" + handlePoints[0] + " H3:" + handlePoints[3]); } if (hasChanged) { Undo.RecordObjects(new Object[] {m_RectTransform, m_TextComponent }, "Margin Changes"); m_TextComponent.margin = marginOffset; EditorUtility.SetDirty(target); } } protected void DrawTextInput() { EditorGUILayout.Space(); // If the text component is linked, disable the text input box. if (m_IsLinkedTextComponentProp.boolValue) { EditorGUILayout.HelpBox("The Text Input Box is disabled due to this text component being linked to another.", MessageType.Info); } else { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_TextProp); if (EditorGUI.EndChangeCheck() || (m_IsRightToLeftProp.boolValue && string.IsNullOrEmpty(m_RtlText))) { m_TextComponent.m_inputSource = TMP_Text.TextInputSources.Text; m_TextComponent.m_isInputParsingRequired = true; m_HavePropertiesChanged = true; // Handle Left to Right or Right to Left Editor if (m_IsRightToLeftProp.boolValue) { m_RtlText = string.Empty; string sourceText = m_TextProp.stringValue; // Reverse Text displayed in Text Input Box for (int i = 0; i < sourceText.Length; i++) { m_RtlText += sourceText[sourceText.Length - i - 1]; } } } // Toggle showing Rich Tags m_IsRightToLeftProp.boolValue = EditorGUILayout.Toggle(k_RtlToggleLabel, m_IsRightToLeftProp.boolValue); if (m_IsRightToLeftProp.boolValue) { EditorGUI.BeginChangeCheck(); m_RtlText = EditorGUILayout.TextArea(m_RtlText, TMP_UIStyleManager.wrappingTextArea, GUILayout.Height(EditorGUI.GetPropertyHeight(m_TextProp) - EditorGUIUtility.singleLineHeight), GUILayout.ExpandWidth(true)); if (EditorGUI.EndChangeCheck()) { // Convert RTL input string sourceText = string.Empty; // Reverse Text displayed in Text Input Box for (int i = 0; i < m_RtlText.Length; i++) { sourceText += m_RtlText[m_RtlText.Length - i - 1]; } m_TextProp.stringValue = sourceText; } } } } protected void DrawMainSettings() { // MAIN SETTINGS SECTION GUILayout.Label(k_MainSettingsLabel, EditorStyles.boldLabel); EditorGUI.indentLevel += 1; DrawFont(); DrawColor(); DrawSpacing(); DrawAlignment(); DrawWrappingOverflow(); DrawTextureMapping(); EditorGUI.indentLevel -= 1; } void DrawFont() { // Update list of material presets if needed. if (m_IsPresetListDirty) m_MaterialPresetNames = GetMaterialPresets(); // FONT ASSET EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_FontAssetProp, k_FontAssetLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; m_HasFontAssetChangedProp.boolValue = true; m_IsPresetListDirty = true; m_MaterialPresetSelectionIndex = 0; } Rect rect; // MATERIAL PRESET if (m_MaterialPresetNames != null) { EditorGUI.BeginChangeCheck(); rect = EditorGUILayout.GetControlRect(false, 17); float oldHeight = EditorStyles.popup.fixedHeight; EditorStyles.popup.fixedHeight = rect.height; int oldSize = EditorStyles.popup.fontSize; EditorStyles.popup.fontSize = 11; m_MaterialPresetSelectionIndex = EditorGUI.Popup(rect, k_MaterialPresetLabel, m_MaterialPresetSelectionIndex, m_MaterialPresetNames); if (EditorGUI.EndChangeCheck()) { m_FontSharedMaterialProp.objectReferenceValue = m_MaterialPresets[m_MaterialPresetSelectionIndex]; m_HavePropertiesChanged = true; } //Make sure material preset selection index matches the selection if (m_MaterialPresetSelectionIndex < m_MaterialPresetNames.Length && m_TargetMaterial != m_MaterialPresets[m_MaterialPresetSelectionIndex] && !m_HavePropertiesChanged) m_IsPresetListDirty = true; EditorStyles.popup.fixedHeight = oldHeight; EditorStyles.popup.fontSize = oldSize; } // FONT STYLE EditorGUI.BeginChangeCheck(); int v1, v2, v3, v4, v5, v6, v7; if (EditorGUIUtility.wideMode) { rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 2f); EditorGUI.PrefixLabel(rect, k_FontStyleLabel); int styleValue = m_FontStyleProp.intValue; rect.x += EditorGUIUtility.labelWidth; rect.width -= EditorGUIUtility.labelWidth; rect.width = Mathf.Max(25f, rect.width / 7f); v1 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 1) == 1, k_BoldLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 1 : 0; // Bold rect.x += rect.width; v2 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 2) == 2, k_ItalicLabel, TMP_UIStyleManager.alignmentButtonMid) ? 2 : 0; // Italics rect.x += rect.width; v3 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 4) == 4, k_UnderlineLabel, TMP_UIStyleManager.alignmentButtonMid) ? 4 : 0; // Underline rect.x += rect.width; v7 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 64) == 64, k_StrikethroughLabel, TMP_UIStyleManager.alignmentButtonRight) ? 64 : 0; // Strikethrough rect.x += rect.width; int selected = 0; EditorGUI.BeginChangeCheck(); v4 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 8) == 8, k_LowercaseLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 8 : 0; // Lowercase if (EditorGUI.EndChangeCheck() && v4 > 0) { selected = v4; } rect.x += rect.width; EditorGUI.BeginChangeCheck(); v5 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 16) == 16, k_UppercaseLabel, TMP_UIStyleManager.alignmentButtonMid) ? 16 : 0; // Uppercase if (EditorGUI.EndChangeCheck() && v5 > 0) { selected = v5; } rect.x += rect.width; EditorGUI.BeginChangeCheck(); v6 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 32) == 32, k_SmallcapsLabel, TMP_UIStyleManager.alignmentButtonRight) ? 32 : 0; // Smallcaps if (EditorGUI.EndChangeCheck() && v6 > 0) { selected = v6; } if (selected > 0) { v4 = selected == 8 ? 8 : 0; v5 = selected == 16 ? 16 : 0; v6 = selected == 32 ? 32 : 0; } } else { rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 2f); EditorGUI.PrefixLabel(rect, k_FontStyleLabel); int styleValue = m_FontStyleProp.intValue; rect.x += EditorGUIUtility.labelWidth; rect.width -= EditorGUIUtility.labelWidth; rect.width = Mathf.Max(25f, rect.width / 4f); v1 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 1) == 1, k_BoldLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 1 : 0; // Bold rect.x += rect.width; v2 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 2) == 2, k_ItalicLabel, TMP_UIStyleManager.alignmentButtonMid) ? 2 : 0; // Italics rect.x += rect.width; v3 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 4) == 4, k_UnderlineLabel, TMP_UIStyleManager.alignmentButtonMid) ? 4 : 0; // Underline rect.x += rect.width; v7 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 64) == 64, k_StrikethroughLabel, TMP_UIStyleManager.alignmentButtonRight) ? 64 : 0; // Strikethrough rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 2f); rect.x += EditorGUIUtility.labelWidth; rect.width -= EditorGUIUtility.labelWidth; rect.width = Mathf.Max(25f, rect.width / 4f); int selected = 0; EditorGUI.BeginChangeCheck(); v4 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 8) == 8, k_LowercaseLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 8 : 0; // Lowercase if (EditorGUI.EndChangeCheck() && v4 > 0) { selected = v4; } rect.x += rect.width; EditorGUI.BeginChangeCheck(); v5 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 16) == 16, k_UppercaseLabel, TMP_UIStyleManager.alignmentButtonMid) ? 16 : 0; // Uppercase if (EditorGUI.EndChangeCheck() && v5 > 0) { selected = v5; } rect.x += rect.width; EditorGUI.BeginChangeCheck(); v6 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 32) == 32, k_SmallcapsLabel, TMP_UIStyleManager.alignmentButtonRight) ? 32 : 0; // Smallcaps if (EditorGUI.EndChangeCheck() && v6 > 0) { selected = v6; } if (selected > 0) { v4 = selected == 8 ? 8 : 0; v5 = selected == 16 ? 16 : 0; v6 = selected == 32 ? 32 : 0; } } if (EditorGUI.EndChangeCheck()) { m_FontStyleProp.intValue = v1 + v2 + v3 + v4 + v5 + v6 + v7; m_HavePropertiesChanged = true; } // FONT SIZE EditorGUI.BeginChangeCheck(); EditorGUI.BeginDisabledGroup(m_AutoSizingProp.boolValue); EditorGUILayout.PropertyField(m_FontSizeProp, k_FontSizeLabel, GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 50f)); EditorGUI.EndDisabledGroup(); if (EditorGUI.EndChangeCheck()) { m_FontSizeBaseProp.floatValue = m_FontSizeProp.floatValue; m_HavePropertiesChanged = true; } EditorGUI.indentLevel += 1; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_AutoSizingProp, k_AutoSizeLabel); if (EditorGUI.EndChangeCheck()) { if (m_AutoSizingProp.boolValue == false) m_FontSizeProp.floatValue = m_FontSizeBaseProp.floatValue; m_HavePropertiesChanged = true; } // Show auto sizing options if (m_AutoSizingProp.boolValue) { rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); EditorGUI.PrefixLabel(rect, k_AutoSizeOptionsLabel); int previousIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; rect.width = (rect.width - EditorGUIUtility.labelWidth) / 4f; rect.x += EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 24; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(rect, m_FontSizeMinProp, k_MinLabel); if (EditorGUI.EndChangeCheck()) { m_FontSizeMinProp.floatValue = Mathf.Min(m_FontSizeMinProp.floatValue, m_FontSizeMaxProp.floatValue); m_HavePropertiesChanged = true; } rect.x += rect.width; EditorGUIUtility.labelWidth = 27; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(rect, m_FontSizeMaxProp, k_MaxLabel); if (EditorGUI.EndChangeCheck()) { m_FontSizeMaxProp.floatValue = Mathf.Max(m_FontSizeMinProp.floatValue, m_FontSizeMaxProp.floatValue); m_HavePropertiesChanged = true; } rect.x += rect.width; EditorGUI.BeginChangeCheck(); EditorGUIUtility.labelWidth = 36; EditorGUI.PropertyField(rect, m_CharWidthMaxAdjProp, k_WdLabel); rect.x += rect.width; EditorGUIUtility.labelWidth = 28; EditorGUI.PropertyField(rect, m_LineSpacingMaxProp, k_LineLabel); EditorGUIUtility.labelWidth = 0; if (EditorGUI.EndChangeCheck()) { m_CharWidthMaxAdjProp.floatValue = Mathf.Clamp(m_CharWidthMaxAdjProp.floatValue, 0, 50); m_LineSpacingMaxProp.floatValue = Mathf.Min(0, m_LineSpacingMaxProp.floatValue); m_HavePropertiesChanged = true; } EditorGUI.indentLevel = previousIndent; } EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DrawColor() { // FACE VERTEX COLOR EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_FontColorProp, k_BaseColorLabel); EditorGUILayout.PropertyField(m_EnableVertexGradientProp, k_ColorGradientLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; } EditorGUIUtility.fieldWidth = 0; if (m_EnableVertexGradientProp.boolValue) { EditorGUI.indentLevel += 1; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_FontColorGradientPresetProp, k_ColorPresetLabel); SerializedObject obj = null; SerializedProperty colorMode; SerializedProperty topLeft; SerializedProperty topRight; SerializedProperty bottomLeft; SerializedProperty bottomRight; if (m_FontColorGradientPresetProp.objectReferenceValue == null) { colorMode = m_ColorModeProp; topLeft = m_FontColorGradientProp.FindPropertyRelative("topLeft"); topRight = m_FontColorGradientProp.FindPropertyRelative("topRight"); bottomLeft = m_FontColorGradientProp.FindPropertyRelative("bottomLeft"); bottomRight = m_FontColorGradientProp.FindPropertyRelative("bottomRight"); } else { obj = new SerializedObject(m_FontColorGradientPresetProp.objectReferenceValue); colorMode = obj.FindProperty("colorMode"); topLeft = obj.FindProperty("topLeft"); topRight = obj.FindProperty("topRight"); bottomLeft = obj.FindProperty("bottomLeft"); bottomRight = obj.FindProperty("bottomRight"); } EditorGUILayout.PropertyField(colorMode, k_ColorModeLabel); var rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); EditorGUI.PrefixLabel(rect, k_CorenerColorsLabel); rect.x += EditorGUIUtility.labelWidth; rect.width = rect.width - EditorGUIUtility.labelWidth; switch ((ColorMode)colorMode.enumValueIndex) { case ColorMode.Single: TMP_EditorUtility.DrawColorProperty(rect, topLeft); topRight.colorValue = topLeft.colorValue; bottomLeft.colorValue = topLeft.colorValue; bottomRight.colorValue = topLeft.colorValue; break; case ColorMode.HorizontalGradient: rect.width /= 2f; TMP_EditorUtility.DrawColorProperty(rect, topLeft); rect.x += rect.width; TMP_EditorUtility.DrawColorProperty(rect, topRight); bottomLeft.colorValue = topLeft.colorValue; bottomRight.colorValue = topRight.colorValue; break; case ColorMode.VerticalGradient: TMP_EditorUtility.DrawColorProperty(rect, topLeft); rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); rect.x += EditorGUIUtility.labelWidth; TMP_EditorUtility.DrawColorProperty(rect, bottomLeft); topRight.colorValue = topLeft.colorValue; bottomRight.colorValue = bottomLeft.colorValue; break; case ColorMode.FourCornersGradient: rect.width /= 2f; TMP_EditorUtility.DrawColorProperty(rect, topLeft); rect.x += rect.width; TMP_EditorUtility.DrawColorProperty(rect, topRight); rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f; TMP_EditorUtility.DrawColorProperty(rect, bottomLeft); rect.x += rect.width; TMP_EditorUtility.DrawColorProperty(rect, bottomRight); break; } if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; if (obj != null) { obj.ApplyModifiedProperties(); TMPro_EventManager.ON_COLOR_GRAIDENT_PROPERTY_CHANGED(m_FontColorGradientPresetProp.objectReferenceValue as TMP_ColorGradient); } } EditorGUI.indentLevel -= 1; } EditorGUILayout.PropertyField(m_OverrideHtmlColorProp, k_OverrideTagsLabel); EditorGUILayout.Space(); } void DrawSpacing() { // CHARACTER, LINE & PARAGRAPH SPACING EditorGUI.BeginChangeCheck(); Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); EditorGUI.PrefixLabel(rect, k_SpacingOptionsLabel); int oldIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth - 3f) / 2f; EditorGUIUtility.labelWidth = Mathf.Min(rect.width * 0.55f, 80f); EditorGUI.PropertyField(rect, m_CharacterSpacingProp, k_CharacterSpacingLabel); rect.x += rect.width + 3f; EditorGUI.PropertyField(rect, m_WordSpacingProp, k_WordSpacingLabel); rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight); EditorGUIUtility.labelWidth = 0; rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth -3f) / 2f; EditorGUIUtility.labelWidth = Mathf.Min(rect.width * 0.55f, 80f); EditorGUI.PropertyField(rect, m_LineSpacingProp, k_LineSpacingLabel); rect.x += rect.width + 3f; EditorGUI.PropertyField(rect, m_ParagraphSpacingProp, k_ParagraphSpacingLabel); EditorGUIUtility.labelWidth = 0; EditorGUI.indentLevel = oldIndent; if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; } } void DrawAlignment() { // TEXT ALIGNMENT EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_TextAlignmentProp, k_AlignmentLabel); // WRAPPING RATIOS shown if Justified mode is selected. if (((_HorizontalAlignmentOptions)m_TextAlignmentProp.intValue & _HorizontalAlignmentOptions.Justified) == _HorizontalAlignmentOptions.Justified || ((_HorizontalAlignmentOptions)m_TextAlignmentProp.intValue & _HorizontalAlignmentOptions.Flush) == _HorizontalAlignmentOptions.Flush) DrawPropertySlider(k_WrapMixLabel, m_WordWrappingRatiosProp); if (EditorGUI.EndChangeCheck()) m_HavePropertiesChanged = true; EditorGUILayout.Space(); } void DrawWrappingOverflow() { // TEXT WRAPPING EditorGUI.BeginChangeCheck(); int wrapSelection = EditorGUILayout.Popup(k_WrappingLabel, m_EnableWordWrappingProp.boolValue ? 1 : 0, k_WrappingOptions); if (EditorGUI.EndChangeCheck()) { m_EnableWordWrappingProp.boolValue = wrapSelection == 1; m_HavePropertiesChanged = true; m_TextComponent.m_isInputParsingRequired = true; } // TEXT OVERFLOW EditorGUI.BeginChangeCheck(); // Cache Reference to Linked Text Component TMP_Text oldLinkedComponent = m_LinkedTextComponentProp.objectReferenceValue as TMP_Text; if ((TextOverflowModes)m_TextOverflowModeProp.enumValueIndex == TextOverflowModes.Linked) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(m_TextOverflowModeProp, k_OverflowLabel); EditorGUILayout.PropertyField(m_LinkedTextComponentProp, GUIContent.none); EditorGUILayout.EndHorizontal(); if (GUI.changed) { TMP_Text linkedComponent = m_LinkedTextComponentProp.objectReferenceValue as TMP_Text; if (linkedComponent) m_TextComponent.linkedTextComponent = linkedComponent; } } else if ((TextOverflowModes)m_TextOverflowModeProp.enumValueIndex == TextOverflowModes.Page) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(m_TextOverflowModeProp, k_OverflowLabel); EditorGUILayout.PropertyField(m_PageToDisplayProp, GUIContent.none); EditorGUILayout.EndHorizontal(); if (oldLinkedComponent) m_TextComponent.linkedTextComponent = null; } else { EditorGUILayout.PropertyField(m_TextOverflowModeProp, k_OverflowLabel); if (oldLinkedComponent) m_TextComponent.linkedTextComponent = null; } if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; m_TextComponent.m_isInputParsingRequired = true; } EditorGUILayout.Space(); } protected abstract void DrawExtraSettings(); protected void DrawMargins() { EditorGUI.BeginChangeCheck(); DrawMarginProperty(m_MarginProp, k_MarginsLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; } EditorGUILayout.Space(); } protected void DrawGeometrySorting() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_GeometrySortingOrderProp, k_GeometrySortingLabel); if (EditorGUI.EndChangeCheck()) m_HavePropertiesChanged = true; EditorGUILayout.Space(); } protected void DrawRichText() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_IsRichTextProp, k_RichTextLabel); if (EditorGUI.EndChangeCheck()) m_HavePropertiesChanged = true; } protected void DrawParsing() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_EnableEscapeCharacterParsingProp, k_EscapeCharactersLabel); EditorGUILayout.PropertyField(m_UseMaxVisibleDescenderProp, k_VisibleDescenderLabel); EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_SpriteAssetProp, k_SpriteAssetLabel, true); if (EditorGUI.EndChangeCheck()) m_HavePropertiesChanged = true; EditorGUILayout.Space(); } protected void DrawTextureMapping() { // TEXTURE MAPPING OPTIONS EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_HorizontalMappingProp, k_HorizontalMappingLabel); EditorGUILayout.PropertyField(m_VerticalMappingProp, k_VerticalMappingLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; } // UV OPTIONS if (m_HorizontalMappingProp.enumValueIndex > 0) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_UvLineOffsetProp, k_LineOffsetLabel, GUILayout.MinWidth(70f)); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; } } EditorGUILayout.Space(); } protected void DrawKerning() { // KERNING EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_EnableKerningProp, k_KerningLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; } } protected void DrawPadding() { // EXTRA PADDING EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_EnableExtraPaddingProp, k_PaddingLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; m_CheckPaddingRequiredProp.boolValue = true; } } /// /// Method to retrieve the material presets that match the currently selected font asset. /// protected GUIContent[] GetMaterialPresets() { TMP_FontAsset fontAsset = m_FontAssetProp.objectReferenceValue as TMP_FontAsset; if (fontAsset == null) return null; m_MaterialPresets = TMP_EditorUtility.FindMaterialReferences(fontAsset); m_MaterialPresetNames = new GUIContent[m_MaterialPresets.Length]; for (int i = 0; i < m_MaterialPresetNames.Length; i++) { m_MaterialPresetNames[i] = new GUIContent(m_MaterialPresets[i].name); if (m_TargetMaterial.GetInstanceID() == m_MaterialPresets[i].GetInstanceID()) m_MaterialPresetSelectionIndex = i; } m_IsPresetListDirty = false; return m_MaterialPresetNames; } // DRAW MARGIN PROPERTY protected void DrawMarginProperty(SerializedProperty property, GUIContent label) { Rect rect = EditorGUILayout.GetControlRect(false, 2 * 18); EditorGUI.BeginProperty(rect, label, property); Rect pos0 = new Rect(rect.x + 15, rect.y + 2, rect.width - 15, 18); float width = rect.width + 3; pos0.width = EditorGUIUtility.labelWidth; GUI.Label(pos0, label); var vec = property.vector4Value; float widthB = width - EditorGUIUtility.labelWidth; float fieldWidth = widthB / 4; pos0.width = Mathf.Max(fieldWidth - 5, 45f); // Labels pos0.x = EditorGUIUtility.labelWidth + 15; GUI.Label(pos0, k_LeftLabel); pos0.x += fieldWidth; GUI.Label(pos0, k_TopLabel); pos0.x += fieldWidth; GUI.Label(pos0, k_RightLabel); pos0.x += fieldWidth; GUI.Label(pos0, k_BottomLabel); pos0.y += 18; pos0.x = EditorGUIUtility.labelWidth; vec.x = EditorGUI.FloatField(pos0, GUIContent.none, vec.x); pos0.x += fieldWidth; vec.y = EditorGUI.FloatField(pos0, GUIContent.none, vec.y); pos0.x += fieldWidth; vec.z = EditorGUI.FloatField(pos0, GUIContent.none, vec.z); pos0.x += fieldWidth; vec.w = EditorGUI.FloatField(pos0, GUIContent.none, vec.w); property.vector4Value = vec; EditorGUI.EndProperty(); } protected void DrawPropertySlider(GUIContent label, SerializedProperty property) { Rect rect = EditorGUILayout.GetControlRect(false, 17); GUIContent content = label ?? GUIContent.none; EditorGUI.Slider(new Rect(rect.x, rect.y, rect.width, rect.height), property, 0.0f, 1.0f, content); } protected abstract bool IsMixSelectionTypes(); // Special Handling of Undo / Redo Events. protected abstract void OnUndoRedo(); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_BaseEditorPanel.cs.meta ================================================ fileFormatVersion: 2 guid: 91950f78729ab144aa36e94690b28fad MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_BaseShaderGUI.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { /// Base class for TextMesh Pro shader GUIs. public abstract class TMP_BaseShaderGUI : ShaderGUI { /// Representation of a #pragma shader_feature. /// It is assumed that the first feature option is for no keyword (underscores). protected class ShaderFeature { public string undoLabel; public GUIContent label; /// The keyword labels, for display. Include the no-keyword as the first option. public GUIContent[] keywordLabels; /// The shader keywords. Exclude the no-keyword option. public string[] keywords; int m_State; public bool Active { get { return m_State >= 0; } } public int State { get { return m_State; } } public void ReadState(Material material) { for (int i = 0; i < keywords.Length; i++) { if (material.IsKeywordEnabled(keywords[i])) { m_State = i; return; } } m_State = -1; } public void SetActive(bool active, Material material) { m_State = active ? 0 : -1; SetStateKeywords(material); } public void DoPopup(MaterialEditor editor, Material material) { EditorGUI.BeginChangeCheck(); int selection = EditorGUILayout.Popup(label, m_State + 1, keywordLabels); if (EditorGUI.EndChangeCheck()) { m_State = selection - 1; editor.RegisterPropertyChangeUndo(undoLabel); SetStateKeywords(material); } } void SetStateKeywords(Material material) { for (int i = 0; i < keywords.Length; i++) { if (i == m_State) { material.EnableKeyword(keywords[i]); } else { material.DisableKeyword(keywords[i]); } } } } static GUIContent s_TempLabel = new GUIContent(); protected static bool s_DebugExtended; static int s_UndoRedoCount, s_LastSeenUndoRedoCount; static float[][] s_TempFloats = { null, new float[1], new float[2], new float[3], new float[4] }; protected static GUIContent[] s_XywhVectorLabels = { new GUIContent("X"), new GUIContent("Y"), new GUIContent("W", "Width"), new GUIContent("H", "Height") }; protected static GUIContent[] s_LbrtVectorLabels = { new GUIContent("L", "Left"), new GUIContent("B", "Bottom"), new GUIContent("R", "Right"), new GUIContent("T", "Top") }; static TMP_BaseShaderGUI() { // Keep track of how many undo/redo events happened. Undo.undoRedoPerformed += () => s_UndoRedoCount += 1; } bool m_IsNewGUI = true; float m_DragAndDropMinY; protected MaterialEditor m_Editor; protected Material m_Material; protected MaterialProperty[] m_Properties; void PrepareGUI() { m_IsNewGUI = false; ShaderUtilities.GetShaderPropertyIDs(); // New GUI just got constructed. This happens in response to a selection, // but also after undo/redo events. if (s_LastSeenUndoRedoCount != s_UndoRedoCount) { // There's been at least one undo/redo since the last time this GUI got constructed. // Maybe the undo/redo was for this material? Assume that is was. TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material as Material); } s_LastSeenUndoRedoCount = s_UndoRedoCount; } public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { m_Editor = materialEditor; m_Material = materialEditor.target as Material; this.m_Properties = properties; if (m_IsNewGUI) { PrepareGUI(); } DoDragAndDropBegin(); EditorGUI.BeginChangeCheck(); DoGUI(); if (EditorGUI.EndChangeCheck()) { TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material); } DoDragAndDropEnd(); } /// Override this method to create the specific shader GUI. protected abstract void DoGUI(); static string[] s_PanelStateLabel = new string[] { "\t- Click to collapse -", "\t- Click to expand -" }; protected bool BeginPanel(string panel, bool expanded) { EditorGUILayout.BeginVertical(EditorStyles.helpBox); Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18)); r.x += 20; r.width += 6; bool enabled = GUI.enabled; GUI.enabled = true; expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle); r.width -= 30; EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel); GUI.enabled = enabled; EditorGUI.indentLevel += 1; EditorGUI.BeginDisabledGroup(false); return expanded; } protected bool BeginPanel(string panel, ShaderFeature feature, bool expanded, bool readState = true) { if (readState) { feature.ReadState(m_Material); } EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.BeginHorizontal(); Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 20, GUILayout.Width(20f))); bool active = EditorGUI.Toggle(r, feature.Active); if (EditorGUI.EndChangeCheck()) { m_Editor.RegisterPropertyChangeUndo(feature.undoLabel); feature.SetActive(active, m_Material); } r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18)); r.width += 6; bool enabled = GUI.enabled; GUI.enabled = true; expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle); r.width -= 10; EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel); GUI.enabled = enabled; GUILayout.EndHorizontal(); EditorGUI.indentLevel += 1; EditorGUI.BeginDisabledGroup(!active); return expanded; } public void EndPanel() { EditorGUI.EndDisabledGroup(); EditorGUI.indentLevel -= 1; EditorGUILayout.EndVertical(); } MaterialProperty BeginProperty(string name) { MaterialProperty property = FindProperty(name, m_Properties); EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = property.hasMixedValue; m_Editor.BeginAnimatedCheck(Rect.zero, property); return property; } bool EndProperty() { m_Editor.EndAnimatedCheck(); EditorGUI.showMixedValue = false; return EditorGUI.EndChangeCheck(); } protected void DoPopup(string name, string label, GUIContent[] options) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; int index = EditorGUILayout.Popup(s_TempLabel, (int)property.floatValue, options); if (EndProperty()) { property.floatValue = index; } } protected void DoCubeMap(string name, string label) { DoTexture(name, label, typeof(Cubemap)); } protected void DoTexture2D(string name, string label, bool withTilingOffset = false, string[] speedNames = null) { DoTexture(name, label, typeof(Texture2D), withTilingOffset, speedNames); } void DoTexture(string name, string label, System.Type type, bool withTilingOffset = false, string[] speedNames = null) { MaterialProperty property = BeginProperty(name); Rect rect = EditorGUILayout.GetControlRect(true, 60f); float totalWidth = rect.width; rect.width = EditorGUIUtility.labelWidth + 60f; s_TempLabel.text = label; Object tex = EditorGUI.ObjectField(rect, s_TempLabel, property.textureValue, type, false); if (EndProperty()) { property.textureValue = tex as Texture; } rect.x += rect.width + 4f; rect.width = totalWidth - rect.width - 4f; rect.height = EditorGUIUtility.singleLineHeight; if (withTilingOffset) { DoTilingOffset(rect, property); rect.y += (rect.height + 2f) * 2f; } if (speedNames != null) { DoUVSpeed(rect, speedNames); } } void DoTilingOffset(Rect rect, MaterialProperty property) { float labelWidth = EditorGUIUtility.labelWidth; int indentLevel = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.20f); Vector4 vector = property.textureScaleAndOffset; bool changed = false; float[] values = s_TempFloats[2]; s_TempLabel.text = "Tiling"; Rect vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel); values[0] = vector.x; values[1] = vector.y; EditorGUI.BeginChangeCheck(); EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values); if (EndProperty()) { vector.x = values[0]; vector.y = values[1]; changed = true; } rect.y += rect.height + 2f; s_TempLabel.text = "Offset"; vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel); values[0] = vector.z; values[1] = vector.w; EditorGUI.BeginChangeCheck(); EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values); if (EndProperty()) { vector.z = values[0]; vector.w = values[1]; changed = true; } if (changed) { property.textureScaleAndOffset = vector; } EditorGUIUtility.labelWidth = labelWidth; EditorGUI.indentLevel = indentLevel; } protected void DoUVSpeed(Rect rect, string[] names) { float labelWidth = EditorGUIUtility.labelWidth; int indentLevel = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.20f); s_TempLabel.text = "Speed"; rect = EditorGUI.PrefixLabel(rect, s_TempLabel); EditorGUIUtility.labelWidth = 13f; rect.width = rect.width * 0.5f - 1f; DoFloat(rect, names[0], "X"); rect.x += rect.width + 2f; DoFloat(rect, names[1], "Y"); EditorGUIUtility.labelWidth = labelWidth; EditorGUI.indentLevel = indentLevel; } protected void DoToggle(string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; bool value = EditorGUILayout.Toggle(s_TempLabel, property.floatValue == 1f); if (EndProperty()) { property.floatValue = value ? 1f : 0f; } } protected void DoFloat(string name, string label) { MaterialProperty property = BeginProperty(name); Rect rect = EditorGUILayout.GetControlRect(); rect.width = EditorGUIUtility.labelWidth + 55f; s_TempLabel.text = label; float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue); if (EndProperty()) { property.floatValue = value; } } protected void DoColor(string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue); if (EndProperty()) { property.colorValue = value; } } void DoFloat(Rect rect, string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue); if (EndProperty()) { property.floatValue = value; } } protected void DoSlider(string name, string label) { MaterialProperty property = BeginProperty(name); Vector2 range = property.rangeLimits; s_TempLabel.text = label; float value = EditorGUI.Slider( EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y ); if (EndProperty()) { property.floatValue = value; } } protected void DoVector3(string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue); if (EndProperty()) { property.vectorValue = value; } } protected void DoVector(string name, string label, GUIContent[] subLabels) { MaterialProperty property = BeginProperty(name); Rect rect = EditorGUILayout.GetControlRect(); s_TempLabel.text = label; rect = EditorGUI.PrefixLabel(rect, s_TempLabel); Vector4 vector = property.vectorValue; float[] values = s_TempFloats[subLabels.Length]; for (int i = 0; i < subLabels.Length; i++) { values[i] = vector[i]; } EditorGUI.MultiFloatField(rect, subLabels, values); if (EndProperty()) { for (int i = 0; i < subLabels.Length; i++) { vector[i] = values[i]; } property.vectorValue = vector; } } void DoDragAndDropBegin() { m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y; } void DoDragAndDropEnd() { Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); Event evt = Event.current; if (evt.type == EventType.DragUpdated) { DragAndDrop.visualMode = DragAndDropVisualMode.Generic; evt.Use(); } else if ( evt.type == EventType.DragPerform && Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition) ) { DragAndDrop.AcceptDrag(); evt.Use(); Material droppedMaterial = DragAndDrop.objectReferences[0] as Material; if (droppedMaterial && droppedMaterial != m_Material) { PerformDrop(droppedMaterial); } } } void PerformDrop(Material droppedMaterial) { Texture droppedTex = droppedMaterial.GetTexture(ShaderUtilities.ID_MainTex); if (!droppedTex) { return; } Texture currentTex = m_Material.GetTexture(ShaderUtilities.ID_MainTex); TMP_FontAsset requiredFontAsset = null; if (droppedTex != currentTex) { requiredFontAsset = TMP_EditorUtility.FindMatchingFontAsset(droppedMaterial); if (!requiredFontAsset) { return; } } foreach (GameObject o in Selection.gameObjects) { if (requiredFontAsset) { TMP_Text textComponent = o.GetComponent(); if (textComponent) { Undo.RecordObject(textComponent, "Font Asset Change"); textComponent.font = requiredFontAsset; } } TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(o, m_Material, droppedMaterial); EditorUtility.SetDirty(o); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_BaseShaderGUI.cs.meta ================================================ fileFormatVersion: 2 guid: 438efd46088d408d8a53f707fa68d976 timeCreated: 1469844810 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_BitmapShaderGUI.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { public class TMP_BitmapShaderGUI : TMP_BaseShaderGUI { static bool s_Face = true; protected override void DoGUI() { s_Face = BeginPanel("Face", s_Face); if (s_Face) { DoFacePanel(); } EndPanel(); s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended); if (s_DebugExtended) { DoDebugPanel(); } EndPanel(); } void DoFacePanel() { EditorGUI.indentLevel += 1; if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex)) { DoColor("_FaceColor", "Color"); DoTexture2D("_FaceTex", "Texture", true); } else { DoColor("_Color", "Color"); DoSlider("_DiffusePower", "Diffuse Power"); } EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoDebugPanel() { EditorGUI.indentLevel += 1; DoTexture2D("_MainTex", "Font Atlas"); if (m_Material.HasProperty(ShaderUtilities.ID_VertexOffsetX)) { if (m_Material.HasProperty(ShaderUtilities.ID_Padding)) { EditorGUILayout.Space(); DoFloat("_Padding", "Padding"); } EditorGUILayout.Space(); DoFloat("_VertexOffsetX", "Offset X"); DoFloat("_VertexOffsetY", "Offset Y"); } if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX)) { EditorGUILayout.Space(); DoFloat("_MaskSoftnessX", "Softness X"); DoFloat("_MaskSoftnessY", "Softness Y"); DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels); } if (m_Material.HasProperty(ShaderUtilities.ID_StencilID)) { EditorGUILayout.Space(); DoFloat("_Stencil", "Stencil ID"); DoFloat("_StencilComp", "Stencil Comp"); } EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_BitmapShaderGUI.cs.meta ================================================ fileFormatVersion: 2 guid: 806de5a9211448c8b65c8435ebb48dd4 timeCreated: 1469998850 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_CharacterPropertyDrawer.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_Character))] public class TMP_CharacterPropertyDrawer : PropertyDrawer { //[SerializeField] //static Material s_InternalSDFMaterial; //[SerializeField] //static Material s_InternalBitmapMaterial; int m_GlyphSelectedForEditing = -1; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_Unicode = property.FindPropertyRelative("m_Unicode"); SerializedProperty prop_GlyphIndex = property.FindPropertyRelative("m_GlyphIndex"); SerializedProperty prop_Scale = property.FindPropertyRelative("m_Scale"); GUIStyle style = new GUIStyle(EditorStyles.label); style.richText = true; EditorGUIUtility.labelWidth = 40f; EditorGUIUtility.fieldWidth = 50; Rect rect = new Rect(position.x + 50, position.y, position.width, 49); // Display non-editable fields if (GUI.enabled == false) { int unicode = prop_Unicode.intValue; EditorGUI.LabelField(new Rect(rect.x, rect.y, 120f, 18), new GUIContent("Unicode: 0x" + unicode.ToString("X") + ""), style); EditorGUI.LabelField(new Rect(rect.x + 115, rect.y, 120f, 18), unicode <= 0xFFFF ? new GUIContent("UTF16: \\u" + unicode.ToString("X4") + "") : new GUIContent("UTF32: \\U" + unicode.ToString("X8") + ""), style); EditorGUI.LabelField(new Rect(rect.x, rect.y + 18, 120, 18), new GUIContent("Glyph ID: " + prop_GlyphIndex.intValue + ""), style); EditorGUI.LabelField(new Rect(rect.x, rect.y + 36, 80, 18), new GUIContent("Scale: " + prop_Scale.floatValue + ""), style); // Draw Glyph (if exists) DrawGlyph(position, property); } else // Display editable fields { EditorGUIUtility.labelWidth = 55f; GUI.SetNextControlName("Unicode Input"); EditorGUI.BeginChangeCheck(); string unicode = EditorGUI.TextField(new Rect(rect.x, rect.y, 120, 18), "Unicode:", prop_Unicode.intValue.ToString("X")); if (GUI.GetNameOfFocusedControl() == "Unicode Input") { //Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F')) { Event.current.character = '\0'; } } if (EditorGUI.EndChangeCheck()) { // Update Unicode value prop_Unicode.intValue = TMP_TextUtilities.StringHexToInt(unicode); } // Cache current glyph index in case it needs to be restored if the new glyph index is invalid. int currentGlyphIndex = prop_GlyphIndex.intValue; EditorGUIUtility.labelWidth = 59f; EditorGUI.BeginChangeCheck(); EditorGUI.DelayedIntField(new Rect(rect.x, rect.y + 18, 100, 18), prop_GlyphIndex, new GUIContent("Glyph ID:")); if (EditorGUI.EndChangeCheck()) { // Get a reference to the font asset TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset; // Make sure new glyph index is valid. int elementIndex = fontAsset.glyphTable.FindIndex(item => item.index == prop_GlyphIndex.intValue); if (elementIndex == -1) prop_GlyphIndex.intValue = currentGlyphIndex; else fontAsset.m_IsFontAssetLookupTablesDirty = true; } int glyphIndex = prop_GlyphIndex.intValue; // Reset glyph selection if new character has been selected. if (GUI.enabled && m_GlyphSelectedForEditing != glyphIndex) m_GlyphSelectedForEditing = -1; // Display button to edit the glyph data. if (GUI.Button(new Rect(rect.x + 120, rect.y + 18, 75, 18), new GUIContent("Edit Glyph"))) { if (m_GlyphSelectedForEditing == -1) m_GlyphSelectedForEditing = glyphIndex; else m_GlyphSelectedForEditing = -1; // Button clicks should not result in potential change. GUI.changed = false; } // Show the glyph property drawer if selected if (glyphIndex == m_GlyphSelectedForEditing && GUI.enabled) { // Get a reference to the font asset TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset; if (fontAsset != null) { // Get the index of the glyph in the font asset glyph table. int elementIndex = fontAsset.glyphTable.FindIndex(item => item.index == glyphIndex); if (elementIndex != -1) { SerializedProperty prop_GlyphTable = property.serializedObject.FindProperty("m_GlyphTable"); SerializedProperty prop_Glyph = prop_GlyphTable.GetArrayElementAtIndex(elementIndex); SerializedProperty prop_GlyphMetrics = prop_Glyph.FindPropertyRelative("m_Metrics"); SerializedProperty prop_GlyphRect = prop_Glyph.FindPropertyRelative("m_GlyphRect"); Rect newRect = EditorGUILayout.GetControlRect(false, 115); EditorGUI.DrawRect(new Rect(newRect.x + 52, newRect.y - 20, newRect.width - 52, newRect.height - 5), new Color(0.1f, 0.1f, 0.1f, 0.45f)); EditorGUI.DrawRect(new Rect(newRect.x + 53, newRect.y - 19, newRect.width - 54, newRect.height - 7), new Color(0.3f, 0.3f, 0.3f, 0.8f)); // Display GlyphRect newRect.x += 55; newRect.y -= 18; newRect.width += 5; EditorGUI.PropertyField(newRect, prop_GlyphRect); // Display GlyphMetrics newRect.y += 45; EditorGUI.PropertyField(newRect, prop_GlyphMetrics); rect.y += 120; } } } EditorGUIUtility.labelWidth = 39f; EditorGUI.PropertyField(new Rect(rect.x, rect.y + 36, 80, 18), prop_Scale, new GUIContent("Scale:")); // Draw Glyph (if exists) DrawGlyph(position, property); } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 58; } void DrawGlyph(Rect position, SerializedProperty property) { // Get a reference to the atlas texture TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset; if (fontAsset == null) return; // Get a reference to the Glyph Table SerializedProperty prop_GlyphTable = property.serializedObject.FindProperty("m_GlyphTable"); int glyphIndex = property.FindPropertyRelative("m_GlyphIndex").intValue; int elementIndex = fontAsset.glyphTable.FindIndex(item => item.index == glyphIndex); // Return if we can't find the glyph if (elementIndex == -1) return; SerializedProperty prop_Glyph = prop_GlyphTable.GetArrayElementAtIndex(elementIndex); // Get reference to atlas texture. int atlasIndex = prop_Glyph.FindPropertyRelative("m_AtlasIndex").intValue; Texture2D atlasTexture = fontAsset.atlasTextures.Length > atlasIndex ? fontAsset.atlasTextures[atlasIndex] : null; if (atlasTexture == null) return; Material mat; if (((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP) { mat = TMP_FontAssetEditor.internalBitmapMaterial; if (mat == null) return; mat.mainTexture = atlasTexture; mat.SetColor("_Color", Color.white); } else { mat = TMP_FontAssetEditor.internalSDFMaterial; if (mat == null) return; mat.mainTexture = atlasTexture; mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1); } // Draw glyph Rect glyphDrawPosition = new Rect(position.x, position.y, 48, 58); SerializedProperty prop_GlyphRect = prop_Glyph.FindPropertyRelative("m_GlyphRect"); int glyphOriginX = prop_GlyphRect.FindPropertyRelative("m_X").intValue; int glyphOriginY = prop_GlyphRect.FindPropertyRelative("m_Y").intValue; int glyphWidth = prop_GlyphRect.FindPropertyRelative("m_Width").intValue; int glyphHeight = prop_GlyphRect.FindPropertyRelative("m_Height").intValue; float normalizedHeight = fontAsset.faceInfo.ascentLine - fontAsset.faceInfo.descentLine; float scale = glyphDrawPosition.width / normalizedHeight; // Compute the normalized texture coordinates Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height); if (Event.current.type == EventType.Repaint) { glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2; glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2; glyphDrawPosition.width = glyphWidth * scale; glyphDrawPosition.height = glyphHeight * scale; // Could switch to using the default material of the font asset which would require passing scale to the shader. Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_CharacterPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: 01ada73c4792aba4c937ff5d92cce866 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ColorGradientAssetMenu.cs ================================================ using UnityEditor; using UnityEngine; using System.IO; using System.Collections; namespace TMPro.EditorUtilities { public static class TMP_ColorGradientAssetMenu { [MenuItem("Assets/Create/TextMeshPro/Color Gradient", false, 115)] public static void CreateColorGradient(MenuCommand context) { string filePath; if (Selection.assetGUIDs.Length == 0) filePath = "Assets/New TMP Color Gradient.asset"; else filePath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]); if (Directory.Exists(filePath)) { filePath += "/New TMP Color Gradient.asset"; } else { filePath = Path.GetDirectoryName(filePath) + "/New TMP Color Gradient.asset"; } filePath = AssetDatabase.GenerateUniqueAssetPath(filePath); // Create new Color Gradient Asset. TMP_ColorGradient colorGradient = ScriptableObject.CreateInstance(); // Create Asset AssetDatabase.CreateAsset(colorGradient, filePath); //EditorUtility.SetDirty(colorGradient); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(colorGradient)); EditorUtility.FocusProjectWindow(); Selection.activeObject = colorGradient; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ColorGradientAssetMenu.cs.meta ================================================ fileFormatVersion: 2 guid: d9647b571c5e44729b71d756b3d55317 timeCreated: 1468187791 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ColorGradientEditor.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TMP_ColorGradient))] public class TMP_ColorGradientEditor : Editor { SerializedProperty m_ColorMode; SerializedProperty m_TopLeftColor; SerializedProperty m_TopRightColor; SerializedProperty m_BottomLeftColor; SerializedProperty m_BottomRightColor; void OnEnable() { m_ColorMode = serializedObject.FindProperty("colorMode"); m_TopLeftColor = serializedObject.FindProperty("topLeft"); m_TopRightColor = serializedObject.FindProperty("topRight"); m_BottomLeftColor = serializedObject.FindProperty("bottomLeft"); m_BottomRightColor = serializedObject.FindProperty("bottomRight"); } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_ColorMode, new GUIContent("Color Mode")); if (EditorGUI.EndChangeCheck()) { switch ((ColorMode)m_ColorMode.enumValueIndex) { case ColorMode.Single: m_TopRightColor.colorValue = m_TopLeftColor.colorValue; m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue; m_BottomRightColor.colorValue = m_TopLeftColor.colorValue; break; case ColorMode.HorizontalGradient: m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue; m_BottomRightColor.colorValue = m_TopRightColor.colorValue; break; case ColorMode.VerticalGradient: m_TopRightColor.colorValue = m_TopLeftColor.colorValue; m_BottomRightColor.colorValue = m_BottomLeftColor.colorValue; break; } } Rect rect; switch ((ColorMode)m_ColorMode.enumValueIndex) { case ColorMode.Single: EditorGUI.BeginChangeCheck(); rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); EditorGUI.PrefixLabel(rect, new GUIContent("Colors")); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / (EditorGUIUtility.wideMode ? 1f : 2f); TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor); if (EditorGUI.EndChangeCheck()) { m_TopRightColor.colorValue = m_TopLeftColor.colorValue; m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue; m_BottomRightColor.colorValue = m_TopLeftColor.colorValue; } break; case ColorMode.HorizontalGradient: rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); EditorGUI.PrefixLabel(rect, new GUIContent("Colors")); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f; EditorGUI.BeginChangeCheck(); TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor); if (EditorGUI.EndChangeCheck()) { m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue; } rect.x += rect.width; EditorGUI.BeginChangeCheck(); TMP_EditorUtility.DrawColorProperty(rect, m_TopRightColor); if (EditorGUI.EndChangeCheck()) { m_BottomRightColor.colorValue = m_TopRightColor.colorValue; } break; case ColorMode.VerticalGradient: rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); EditorGUI.PrefixLabel(rect, new GUIContent("Colors")); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / (EditorGUIUtility.wideMode ? 1f : 2f); rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2); EditorGUI.BeginChangeCheck(); TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor); if (EditorGUI.EndChangeCheck()) { m_TopRightColor.colorValue = m_TopLeftColor.colorValue; } rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / (EditorGUIUtility.wideMode ? 1f : 2f); rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2); EditorGUI.BeginChangeCheck(); TMP_EditorUtility.DrawColorProperty(rect, m_BottomLeftColor); if (EditorGUI.EndChangeCheck()) { m_BottomRightColor.colorValue = m_BottomLeftColor.colorValue; } break; case ColorMode.FourCornersGradient: rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); EditorGUI.PrefixLabel(rect, new GUIContent("Colors")); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f; rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2); TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor); rect.x += rect.width; TMP_EditorUtility.DrawColorProperty(rect, m_TopRightColor); rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f; rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2); TMP_EditorUtility.DrawColorProperty(rect, m_BottomLeftColor); rect.x += rect.width; TMP_EditorUtility.DrawColorProperty(rect, m_BottomRightColor); break; } if (serializedObject.ApplyModifiedProperties()) TMPro_EventManager.ON_COLOR_GRAIDENT_PROPERTY_CHANGED(target as TMP_ColorGradient); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ColorGradientEditor.cs.meta ================================================ fileFormatVersion: 2 guid: fcc60c1d6bb544d9b712b652f418ff3a timeCreated: 1468400050 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_DropdownEditor.cs ================================================ using UnityEngine; using UnityEditor; using UnityEditor.UI; using UnityEngine.UI; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TMP_Dropdown), true)] [CanEditMultipleObjects] public class DropdownEditor : SelectableEditor { SerializedProperty m_Template; SerializedProperty m_CaptionText; SerializedProperty m_CaptionImage; SerializedProperty m_ItemText; SerializedProperty m_ItemImage; SerializedProperty m_OnSelectionChanged; SerializedProperty m_Value; SerializedProperty m_Options; protected override void OnEnable() { base.OnEnable(); m_Template = serializedObject.FindProperty("m_Template"); m_CaptionText = serializedObject.FindProperty("m_CaptionText"); m_CaptionImage = serializedObject.FindProperty("m_CaptionImage"); m_ItemText = serializedObject.FindProperty("m_ItemText"); m_ItemImage = serializedObject.FindProperty("m_ItemImage"); m_OnSelectionChanged = serializedObject.FindProperty("m_OnValueChanged"); m_Value = serializedObject.FindProperty("m_Value"); m_Options = serializedObject.FindProperty("m_Options"); } public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUILayout.Space(); serializedObject.Update(); EditorGUILayout.PropertyField(m_Template); EditorGUILayout.PropertyField(m_CaptionText); EditorGUILayout.PropertyField(m_CaptionImage); EditorGUILayout.PropertyField(m_ItemText); EditorGUILayout.PropertyField(m_ItemImage); EditorGUILayout.PropertyField(m_Value); EditorGUILayout.PropertyField(m_Options); EditorGUILayout.PropertyField(m_OnSelectionChanged); serializedObject.ApplyModifiedProperties(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_DropdownEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 6dbcf248c987476181a37f01a1814975 timeCreated: 1446377461 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_EditorCoroutine.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace TMPro.EditorUtilities { /// /// Simple implementation of coroutine working in the Unity Editor. /// public class TMP_EditorCoroutine { //private static Dictionary s_ActiveCoroutines; readonly IEnumerator coroutine; /// /// Constructor /// /// TMP_EditorCoroutine(IEnumerator routine) { this.coroutine = routine; } /// /// Starts a new EditorCoroutine. /// /// Coroutine /// new EditorCoroutine public static TMP_EditorCoroutine StartCoroutine(IEnumerator routine) { TMP_EditorCoroutine coroutine = new TMP_EditorCoroutine(routine); coroutine.Start(); // Add coroutine to tracking list //if (s_ActiveCoroutines == null) // s_ActiveCoroutines = new Dictionary(); // Add new instance of editor coroutine to dictionary. //s_ActiveCoroutines.Add(coroutine.GetHashCode(), coroutine); return coroutine; } /// /// Clear delegate list /// //public static void StopAllEditorCoroutines() //{ // EditorApplication.update = null; //} /// /// Register callback for editor updates /// void Start() { EditorApplication.update += EditorUpdate; } /// /// Unregister callback for editor updates. /// public void Stop() { if (EditorApplication.update != null) EditorApplication.update -= EditorUpdate; //s_ActiveCoroutines.Remove(this.GetHashCode()); } /// /// Delegate function called on editor updates. /// void EditorUpdate() { // Stop editor coroutine if it does not continue. if (coroutine.MoveNext() == false) Stop(); // Process the different types of EditorCoroutines. if (coroutine.Current != null) { } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_EditorCoroutine.cs.meta ================================================ fileFormatVersion: 2 guid: 27a0335dab59ec542aadd6636a5b4ebd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_EditorPanel.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TextMeshPro), true), CanEditMultipleObjects] public class TMP_EditorPanel : TMP_BaseEditorPanel { static readonly GUIContent k_SortingLayerLabel = new GUIContent("Sorting Layer", "Name of the Renderer's sorting layer."); static readonly GUIContent k_OrderInLayerLabel = new GUIContent("Order in Layer", "Renderer's order within a sorting layer."); static readonly GUIContent k_OrthographicLabel = new GUIContent("Orthographic Mode", "Should be enabled when using an orthographic camera. Instructs the shader to not perform any perspective correction."); static readonly GUIContent k_VolumetricLabel = new GUIContent("Volumetric Setup", "Use cubes rather than quads to render the text. Allows for volumetric rendering when combined with a compatible shader."); SerializedProperty m_IsVolumetricTextProp; SerializedProperty m_IsOrthographicProp; Renderer m_Renderer; protected override void OnEnable() { base.OnEnable(); m_IsOrthographicProp = serializedObject.FindProperty("m_isOrthographic"); m_IsVolumetricTextProp = serializedObject.FindProperty("m_isVolumetricText"); m_Renderer = m_TextComponent.GetComponent(); } protected override void DrawExtraSettings() { Foldout.extraSettings = EditorGUILayout.Foldout(Foldout.extraSettings, k_ExtraSettingsLabel, true, TMP_UIStyleManager.boldFoldout); if (Foldout.extraSettings) { EditorGUI.indentLevel += 1; DrawMargins(); DrawSortingLayer(); DrawGeometrySorting(); DrawOrthographicMode(); DrawRichText(); DrawParsing(); DrawVolumetricSetup(); DrawKerning(); DrawPadding(); EditorGUI.indentLevel -= 1; } } protected void DrawSortingLayer() { Undo.RecordObject(m_Renderer, "Sorting Layer Change"); EditorGUI.BeginChangeCheck(); // SORTING LAYERS var sortingLayerNames = SortingLayerHelper.sortingLayerNames; var textComponent = (TextMeshPro)m_TextComponent; // Look up the layer name using the current layer ID string oldName = SortingLayerHelper.GetSortingLayerNameFromID(textComponent.sortingLayerID); // Use the name to look up our array index into the names list int oldLayerIndex = System.Array.IndexOf(sortingLayerNames, oldName); // Show the pop-up for the names EditorGUIUtility.fieldWidth = 0f; int newLayerIndex = EditorGUILayout.Popup(k_SortingLayerLabel, oldLayerIndex, sortingLayerNames); // If the index changes, look up the ID for the new index to store as the new ID if (newLayerIndex != oldLayerIndex) { textComponent.sortingLayerID = SortingLayerHelper.GetSortingLayerIDForIndex(newLayerIndex); } // Expose the manual sorting order int newSortingLayerOrder = EditorGUILayout.IntField(k_OrderInLayerLabel, textComponent.sortingOrder); if (newSortingLayerOrder != textComponent.sortingOrder) { textComponent.sortingOrder = newSortingLayerOrder; } if (EditorGUI.EndChangeCheck()) m_HavePropertiesChanged = true; EditorGUILayout.Space(); } protected void DrawOrthographicMode() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_IsOrthographicProp, k_OrthographicLabel); if (EditorGUI.EndChangeCheck()) m_HavePropertiesChanged = true; } protected void DrawVolumetricSetup() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_IsVolumetricTextProp, k_VolumetricLabel); if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; m_TextComponent.textInfo.ResetVertexLayout(m_IsVolumetricTextProp.boolValue); } EditorGUILayout.Space(); } // Method to handle multi object selection protected override bool IsMixSelectionTypes() { GameObject[] objects = Selection.gameObjects; if (objects.Length > 1) { for (int i = 0; i < objects.Length; i++) { if (objects[i].GetComponent() == null) return true; } } return false; } protected override void OnUndoRedo() { int undoEventId = Undo.GetCurrentGroup(); int lastUndoEventId = s_EventId; if (undoEventId != lastUndoEventId) { for (int i = 0; i < targets.Length; i++) { //Debug.Log("Undo & Redo Performed detected in Editor Panel. Event ID:" + Undo.GetCurrentGroup()); TMPro_EventManager.ON_TEXTMESHPRO_PROPERTY_CHANGED(true, targets[i] as TextMeshPro); s_EventId = undoEventId; } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_EditorPanel.cs.meta ================================================ fileFormatVersion: 2 guid: 34f6695d37a94370a3697f6b068f5d5e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_EditorUtility.cs ================================================ using UnityEngine; using UnityEditor; using System.Text; using System.IO; using System.Collections; using System.Collections.Generic; namespace TMPro.EditorUtilities { public static class TMP_EditorUtility { /// /// Returns the relative path of the package. /// public static string packageRelativePath { get { if (string.IsNullOrEmpty(m_PackagePath)) m_PackagePath = GetPackageRelativePath(); return m_PackagePath; } } [SerializeField] private static string m_PackagePath; /// /// Returns the fully qualified path of the package. /// public static string packageFullPath { get { if (string.IsNullOrEmpty(m_PackageFullPath)) m_PackageFullPath = GetPackageFullPath(); return m_PackageFullPath; } } [SerializeField] private static string m_PackageFullPath; // Static Fields Related to locating the TextMesh Pro Asset private static string folderPath = "Not Found"; private static EditorWindow Gameview; private static bool isInitialized = false; private static void GetGameview() { System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly; System.Type type = assembly.GetType("UnityEditor.GameView"); Gameview = EditorWindow.GetWindow(type); } public static void RepaintAll() { if (isInitialized == false) { GetGameview(); isInitialized = true; } SceneView.RepaintAll(); Gameview.Repaint(); } /// /// Create and return a new asset in a smart location based on the current selection and then select it. /// /// /// Name of the new asset. Do not include the .asset extension. /// /// /// The new asset. /// public static T CreateAsset(string name) where T : ScriptableObject { string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (path.Length == 0) { // no asset selected, place in asset root path = "Assets/" + name + ".asset"; } else if (Directory.Exists(path)) { // place in currently selected directory path += "/" + name + ".asset"; } else { // place in current selection's containing directory path = Path.GetDirectoryName(path) + "/" + name + ".asset"; } T asset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(asset, AssetDatabase.GenerateUniqueAssetPath(path)); EditorUtility.FocusProjectWindow(); Selection.activeObject = asset; return asset; } // Function used to find all materials which reference a font atlas so we can update all their references. public static Material[] FindMaterialReferences(TMP_FontAsset fontAsset) { List refs = new List(); Material mat = fontAsset.material; refs.Add(mat); // Get materials matching the search pattern. string searchPattern = "t:Material" + " " + fontAsset.name.Split(new char[] { ' ' })[0]; string[] materialAssetGUIDs = AssetDatabase.FindAssets(searchPattern); for (int i = 0; i < materialAssetGUIDs.Length; i++) { string materialPath = AssetDatabase.GUIDToAssetPath(materialAssetGUIDs[i]); Material targetMaterial = AssetDatabase.LoadAssetAtPath(materialPath); if (targetMaterial.HasProperty(ShaderUtilities.ID_MainTex) && targetMaterial.GetTexture(ShaderUtilities.ID_MainTex) != null && mat.GetTexture(ShaderUtilities.ID_MainTex) != null && targetMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID() == mat.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID()) { if (!refs.Contains(targetMaterial)) refs.Add(targetMaterial); } else { // TODO: Find a more efficient method to unload resources. //Resources.UnloadAsset(targetMaterial.GetTexture(ShaderUtilities.ID_MainTex)); } } return refs.ToArray(); } // Function used to find the Font Asset which matches the given Material Preset and Font Atlas Texture. public static TMP_FontAsset FindMatchingFontAsset(Material mat) { if (mat.GetTexture(ShaderUtilities.ID_MainTex) == null) return null; // Find the dependent assets of this material. string[] dependentAssets = AssetDatabase.GetDependencies(AssetDatabase.GetAssetPath(mat), false); for (int i = 0; i < dependentAssets.Length; i++) { TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath(dependentAssets[i]); if (fontAsset != null) return fontAsset; } return null; } private static string GetPackageRelativePath() { // Check for potential UPM package string packagePath = Path.GetFullPath("Packages/com.unity.textmeshpro"); if (Directory.Exists(packagePath)) { return "Packages/com.unity.textmeshpro"; } packagePath = Path.GetFullPath("Assets/.."); if (Directory.Exists(packagePath)) { // Search default location for development package if (Directory.Exists(packagePath + "/Assets/Packages/com.unity.TextMeshPro/Editor Resources")) { return "Assets/Packages/com.unity.TextMeshPro"; } // Search for default location of normal TextMesh Pro AssetStore package if (Directory.Exists(packagePath + "/Assets/TextMesh Pro/Editor Resources")) { return "Assets/TextMesh Pro"; } // Search for potential alternative locations in the user project string[] matchingPaths = Directory.GetDirectories(packagePath, "TextMesh Pro", SearchOption.AllDirectories); packagePath = ValidateLocation(matchingPaths, packagePath); if (packagePath != null) return packagePath; } return null; } private static string GetPackageFullPath() { // Check for potential UPM package string packagePath = Path.GetFullPath("Packages/com.unity.textmeshpro"); if (Directory.Exists(packagePath)) { return packagePath; } packagePath = Path.GetFullPath("Assets/.."); if (Directory.Exists(packagePath)) { // Search default location for development package if (Directory.Exists(packagePath + "/Assets/Packages/com.unity.TextMeshPro/Editor Resources")) { return packagePath + "/Assets/Packages/com.unity.TextMeshPro"; } // Search for default location of normal TextMesh Pro AssetStore package if (Directory.Exists(packagePath + "/Assets/TextMesh Pro/Editor Resources")) { return packagePath + "/Assets/TextMesh Pro"; } // Search for potential alternative locations in the user project string[] matchingPaths = Directory.GetDirectories(packagePath, "TextMesh Pro", SearchOption.AllDirectories); string path = ValidateLocation(matchingPaths, packagePath); if (path != null) return packagePath + path; } return null; } /// /// Method to validate the location of the asset folder by making sure the GUISkins folder exists. /// /// /// private static string ValidateLocation(string[] paths, string projectPath) { for (int i = 0; i < paths.Length; i++) { // Check if any of the matching directories contain a GUISkins directory. if (Directory.Exists(paths[i] + "/Editor Resources")) { folderPath = paths[i].Replace(projectPath, ""); folderPath = folderPath.TrimStart('\\', '/'); return folderPath; } } return null; } /// /// Function which returns a string containing a sequence of Decimal character ranges. /// /// /// public static string GetDecimalCharacterSequence(int[] characterSet) { if (characterSet == null || characterSet.Length == 0) return string.Empty; string characterSequence = string.Empty; int count = characterSet.Length; int first = characterSet[0]; int last = first; for (int i = 1; i < count; i++) { if (characterSet[i - 1] + 1 == characterSet[i]) { last = characterSet[i]; } else { if (first == last) characterSequence += first + ","; else characterSequence += first + "-" + last + ","; first = last = characterSet[i]; } } // handle the final group if (first == last) characterSequence += first; else characterSequence += first + "-" + last; return characterSequence; } /// /// Function which returns a string containing a sequence of Unicode (Hex) character ranges. /// /// /// public static string GetUnicodeCharacterSequence(int[] characterSet) { if (characterSet == null || characterSet.Length == 0) return string.Empty; string characterSequence = string.Empty; int count = characterSet.Length; int first = characterSet[0]; int last = first; for (int i = 1; i < count; i++) { if (characterSet[i - 1] + 1 == characterSet[i]) { last = characterSet[i]; } else { if (first == last) characterSequence += first.ToString("X2") + ","; else characterSequence += first.ToString("X2") + "-" + last.ToString("X2") + ","; first = last = characterSet[i]; } } // handle the final group if (first == last) characterSequence += first.ToString("X2"); else characterSequence += first.ToString("X2") + "-" + last.ToString("X2"); return characterSequence; } /// /// /// /// /// /// public static void DrawBox(Rect rect, float thickness, Color color) { EditorGUI.DrawRect(new Rect(rect.x - thickness, rect.y + thickness, rect.width + thickness * 2, thickness), color); EditorGUI.DrawRect(new Rect(rect.x - thickness, rect.y + thickness, thickness, rect.height - thickness * 2), color); EditorGUI.DrawRect(new Rect(rect.x - thickness, rect.y + rect.height - thickness * 2, rect.width + thickness * 2, thickness), color); EditorGUI.DrawRect(new Rect(rect.x + rect.width, rect.y + thickness, thickness, rect.height - thickness * 2), color); } /// /// Function to return the horizontal alignment grid value. /// /// /// public static int GetHorizontalAlignmentGridValue(int value) { if ((value & 0x1) == 0x1) return 0; else if ((value & 0x2) == 0x2) return 1; else if ((value & 0x4) == 0x4) return 2; else if ((value & 0x8) == 0x8) return 3; else if ((value & 0x10) == 0x10) return 4; else if ((value & 0x20) == 0x20) return 5; return 0; } /// /// Function to return the vertical alignment grid value. /// /// /// public static int GetVerticalAlignmentGridValue(int value) { if ((value & 0x100) == 0x100) return 0; if ((value & 0x200) == 0x200) return 1; if ((value & 0x400) == 0x400) return 2; if ((value & 0x800) == 0x800) return 3; if ((value & 0x1000) == 0x1000) return 4; if ((value & 0x2000) == 0x2000) return 5; return 0; } public static void DrawColorProperty(Rect rect, SerializedProperty property) { int oldIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; if (EditorGUIUtility.wideMode) { EditorGUI.PropertyField(new Rect(rect.x, rect.y, 50f, rect.height), property, GUIContent.none); rect.x += 50f; rect.width = Mathf.Min(100f, rect.width - 55f); } else { rect.height /= 2f; rect.width = Mathf.Min(100f, rect.width - 5f); EditorGUI.PropertyField(rect, property, GUIContent.none); rect.y += rect.height; } EditorGUI.BeginChangeCheck(); string colorString = EditorGUI.TextField(rect, string.Format("#{0}", ColorUtility.ToHtmlStringRGBA(property.colorValue))); if (EditorGUI.EndChangeCheck()) { if (ColorUtility.TryParseHtmlString(colorString, out Color color)) { property.colorValue = color; } } EditorGUI.indentLevel = oldIndent; } public static bool EditorToggle(Rect position, bool value, GUIContent content, GUIStyle style) { var id = GUIUtility.GetControlID(content, FocusType.Keyboard, position); var evt = Event.current; // Toggle selected toggle on space or return key if (GUIUtility.keyboardControl == id && evt.type == EventType.KeyDown && (evt.keyCode == KeyCode.Space || evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)) { value = !value; evt.Use(); GUI.changed = true; } if (evt.type == EventType.MouseDown && position.Contains(Event.current.mousePosition)) { GUIUtility.keyboardControl = id; EditorGUIUtility.editingTextField = false; HandleUtility.Repaint(); } return GUI.Toggle(position, id, value, content, style); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_EditorUtility.cs.meta ================================================ fileFormatVersion: 2 guid: 2300e75732d74890b38a8ff257a3ae15 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_FontAssetEditor.cs ================================================ using UnityEngine; using UnityEditor; using UnityEditorInternal; using System.Collections; using System.Collections.Generic; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_FontWeightPair))] public class FontWeightDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_regular = property.FindPropertyRelative("regularTypeface"); SerializedProperty prop_italic = property.FindPropertyRelative("italicTypeface"); float width = position.width; position.width = EditorGUIUtility.labelWidth; EditorGUI.LabelField(position, label); int oldIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; // NORMAL TYPEFACE if (label.text[0] == '4') GUI.enabled = false; position.x += position.width; position.width = (width - position.width) / 2; EditorGUI.PropertyField(position, prop_regular, GUIContent.none); // ITALIC TYPEFACE GUI.enabled = true; position.x += position.width; EditorGUI.PropertyField(position, prop_italic, GUIContent.none); EditorGUI.indentLevel = oldIndent; } } [CustomEditor(typeof(TMP_FontAsset))] public class TMP_FontAssetEditor : Editor { private struct UI_PanelState { public static bool faceInfoPanel = true; public static bool generationSettingsPanel = true; public static bool fontAtlasInfoPanel = true; public static bool fontWeightPanel = true; public static bool fallbackFontAssetPanel = true; public static bool glyphTablePanel = false; public static bool characterTablePanel = false; public static bool fontFeatureTablePanel = false; } private struct AtlasSettings { public GlyphRenderMode glyphRenderMode; public int pointSize; public int padding; public int atlasWidth; public int atlasHeight; } /// /// Material used to display SDF glyphs in the Character and Glyph tables. /// internal static Material internalSDFMaterial { get { if (s_InternalSDFMaterial == null) { Shader shader = Shader.Find("Hidden/TextMeshPro/Internal/Distance Field SSD"); if (shader != null) s_InternalSDFMaterial = new Material(shader); } return s_InternalSDFMaterial; } } static Material s_InternalSDFMaterial; /// /// Material used to display Bitmap glyphs in the Character and Glyph tables. /// internal static Material internalBitmapMaterial { get { if (s_InternalBitmapMaterial == null) { Shader shader = Shader.Find("Hidden/Internal-GUITextureClipText"); if (shader != null) s_InternalBitmapMaterial = new Material(shader); } return s_InternalBitmapMaterial; } } static Material s_InternalBitmapMaterial; private static string[] s_UiStateLabel = new string[] { "(Click to collapse) ", "(Click to expand) " }; private GUIContent[] m_AtlasResolutionLabels = { new GUIContent("8"), new GUIContent("16"), new GUIContent("32"), new GUIContent("64"), new GUIContent("128"), new GUIContent("256"), new GUIContent("512"), new GUIContent("1024"), new GUIContent("2048"), new GUIContent("4096"), new GUIContent("8192") }; private int[] m_AtlasResolutions = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; private struct Warning { public bool isEnabled; public double expirationTime; } private int m_CurrentGlyphPage = 0; private int m_CurrentCharacterPage = 0; private int m_CurrentKerningPage = 0; private int m_SelectedGlyphRecord = -1; private int m_SelectedCharacterRecord = -1; private int m_SelectedAdjustmentRecord = -1; private string m_dstGlyphID; private string m_dstUnicode; private const string k_placeholderUnicodeHex = "New Unicode (Hex)"; private string m_unicodeHexLabel = k_placeholderUnicodeHex; private const string k_placeholderGlyphID = "New Glyph ID"; private string m_GlyphIDLabel = k_placeholderGlyphID; private Warning m_AddGlyphWarning; private Warning m_AddCharacterWarning; private bool m_DisplayDestructiveChangeWarning; private AtlasSettings m_AtlasSettings; private bool m_MaterialPresetsRequireUpdate; private string m_GlyphSearchPattern; private List m_GlyphSearchList; private string m_CharacterSearchPattern; private List m_CharacterSearchList; private string m_KerningTableSearchPattern; private List m_KerningTableSearchList; private bool m_isSearchDirty; private const string k_UndoRedo = "UndoRedoPerformed"; private SerializedProperty m_AtlasPopulationMode_prop; private SerializedProperty font_atlas_prop; private SerializedProperty font_material_prop; private SerializedProperty m_AtlasRenderMode_prop; private SerializedProperty m_SamplingPointSize_prop; private SerializedProperty m_AtlasPadding_prop; private SerializedProperty m_AtlasWidth_prop; private SerializedProperty m_AtlasHeight_prop; private SerializedProperty fontWeights_prop; //private SerializedProperty fallbackFontAssets_prop; private ReorderableList m_list; private SerializedProperty font_normalStyle_prop; private SerializedProperty font_normalSpacing_prop; private SerializedProperty font_boldStyle_prop; private SerializedProperty font_boldSpacing_prop; private SerializedProperty font_italicStyle_prop; private SerializedProperty font_tabSize_prop; private SerializedProperty m_FaceInfo_prop; private SerializedProperty m_GlyphTable_prop; private SerializedProperty m_CharacterTable_prop; private TMP_FontFeatureTable m_FontFeatureTable; private SerializedProperty m_FontFeatureTable_prop; private SerializedProperty m_GlyphPairAdjustmentRecords_prop; private TMP_SerializedPropertyHolder m_SerializedPropertyHolder; private SerializedProperty m_EmptyGlyphPairAdjustmentRecord_prop; private TMP_FontAsset m_fontAsset; private Material[] m_materialPresets; private bool isAssetDirty = false; private int errorCode; private System.DateTime timeStamp; public void OnEnable() { m_FaceInfo_prop = serializedObject.FindProperty("m_FaceInfo"); font_atlas_prop = serializedObject.FindProperty("m_AtlasTextures").GetArrayElementAtIndex(0); font_material_prop = serializedObject.FindProperty("material"); m_AtlasPopulationMode_prop = serializedObject.FindProperty("m_AtlasPopulationMode"); m_AtlasRenderMode_prop = serializedObject.FindProperty("m_AtlasRenderMode"); m_SamplingPointSize_prop = m_FaceInfo_prop.FindPropertyRelative("m_PointSize"); m_AtlasPadding_prop = serializedObject.FindProperty("m_AtlasPadding"); m_AtlasWidth_prop = serializedObject.FindProperty("m_AtlasWidth"); m_AtlasHeight_prop = serializedObject.FindProperty("m_AtlasHeight"); fontWeights_prop = serializedObject.FindProperty("m_FontWeightTable"); m_list = new ReorderableList(serializedObject, serializedObject.FindProperty("m_FallbackFontAssetTable"), true, true, true, true); m_list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = m_list.serializedProperty.GetArrayElementAtIndex(index); rect.y += 2; EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none); }; m_list.drawHeaderCallback = rect => { EditorGUI.LabelField(rect, "Fallback List"); }; // Clean up fallback list in the event if contains null elements. CleanFallbackFontAssetTable(); font_normalStyle_prop = serializedObject.FindProperty("normalStyle"); font_normalSpacing_prop = serializedObject.FindProperty("normalSpacingOffset"); font_boldStyle_prop = serializedObject.FindProperty("boldStyle"); font_boldSpacing_prop = serializedObject.FindProperty("boldSpacing"); font_italicStyle_prop = serializedObject.FindProperty("italicStyle"); font_tabSize_prop = serializedObject.FindProperty("tabSize"); m_CharacterTable_prop = serializedObject.FindProperty("m_CharacterTable"); m_GlyphTable_prop = serializedObject.FindProperty("m_GlyphTable"); m_FontFeatureTable_prop = serializedObject.FindProperty("m_FontFeatureTable"); m_GlyphPairAdjustmentRecords_prop = m_FontFeatureTable_prop.FindPropertyRelative("m_GlyphPairAdjustmentRecords"); m_fontAsset = target as TMP_FontAsset; m_FontFeatureTable = m_fontAsset.fontFeatureTable; // Upgrade Font Feature Table if necessary if (m_fontAsset.m_KerningTable != null && m_fontAsset.m_KerningTable.kerningPairs != null && m_fontAsset.m_KerningTable.kerningPairs.Count > 0) m_fontAsset.ReadFontAssetDefinition(); // Create serialized object to allow us to use a serialized property of an empty kerning pair. m_SerializedPropertyHolder = CreateInstance(); m_SerializedPropertyHolder.fontAsset = m_fontAsset; SerializedObject internalSerializedObject = new SerializedObject(m_SerializedPropertyHolder); m_EmptyGlyphPairAdjustmentRecord_prop = internalSerializedObject.FindProperty("glyphPairAdjustmentRecord"); m_materialPresets = TMP_EditorUtility.FindMaterialReferences(m_fontAsset); m_GlyphSearchList = new List(); m_KerningTableSearchList = new List(); } public void OnDisable() { // Revert changes if user closes or changes selection without having made a choice. if (m_DisplayDestructiveChangeWarning) { m_DisplayDestructiveChangeWarning = false; RestoreAtlasGenerationSettings(); GUIUtility.keyboardControl = 0; serializedObject.ApplyModifiedProperties(); } } public override void OnInspectorGUI() { //Debug.Log("OnInspectorGUI Called."); Event currentEvent = Event.current; serializedObject.Update(); Rect rect = EditorGUILayout.GetControlRect(false, 24); float labelWidth = EditorGUIUtility.labelWidth; float fieldWidth = EditorGUIUtility.fieldWidth; // FACE INFO PANEL #region Face info GUI.Label(rect, new GUIContent("Face Info - v" + m_fontAsset.version), TMP_UIStyleManager.sectionHeader); rect.x += rect.width - 132f; rect.y += 2; rect.width = 130f; rect.height = 18f; if (GUI.Button(rect, new GUIContent("Update Atlas Texture"))) { TMPro_FontAssetCreatorWindow.ShowFontAtlasCreatorWindow(target as TMP_FontAsset); } EditorGUI.indentLevel = 1; GUI.enabled = false; // Lock UI // TODO : Consider creating a property drawer for these. EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_FamilyName")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_StyleName")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_PointSize")); GUI.enabled = true; EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_Scale")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_LineHeight")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_AscentLine")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_CapLine")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_MeanLine")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_Baseline")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_DescentLine")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_UnderlineOffset")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_UnderlineThickness")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_StrikethroughOffset")); //EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("strikethroughThickness")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_SuperscriptOffset")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_SuperscriptSize")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_SubscriptOffset")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_SubscriptSize")); EditorGUILayout.PropertyField(m_FaceInfo_prop.FindPropertyRelative("m_TabWidth")); // TODO : Add clamping for some of these values. //subSize_prop.floatValue = Mathf.Clamp(subSize_prop.floatValue, 0.25f, 1f); EditorGUILayout.Space(); #endregion // GENERATION SETTINGS #region Generation Settings rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Generation Settings"), TMP_UIStyleManager.sectionHeader)) UI_PanelState.generationSettingsPanel = !UI_PanelState.generationSettingsPanel; GUI.Label(rect, (UI_PanelState.generationSettingsPanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.generationSettingsPanel) { EditorGUI.indentLevel = 1; EditorGUI.BeginChangeCheck(); Font sourceFont = (Font)EditorGUILayout.ObjectField("Source Font File", m_fontAsset.m_SourceFontFile_EditorRef, typeof(Font), false); if (EditorGUI.EndChangeCheck()) { string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(sourceFont)); m_fontAsset.m_SourceFontFileGUID = guid; m_fontAsset.m_SourceFontFile_EditorRef = sourceFont; } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_AtlasPopulationMode_prop, new GUIContent("Atlas Population Mode")); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); bool isDatabaseRefreshRequired = false; if (m_AtlasPopulationMode_prop.intValue == 0) { m_fontAsset.sourceFontFile = null; // Set atlas textures to non readable. //for (int i = 0; i < m_fontAsset.atlasTextures.Length; i++) //{ // Texture2D tex = m_fontAsset.atlasTextures[i]; // if (tex != null && tex.isReadable) // { // string texPath = AssetDatabase.GetAssetPath(tex); // var texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter; // if (texImporter != null) // { // texImporter.isReadable = false; // AssetDatabase.ImportAsset(texPath); // isDatabaseRefreshRequired = true; // } // } //} Debug.Log("Atlas Population mode set to [Static]."); } else if (m_AtlasPopulationMode_prop.intValue == 1) { if (m_fontAsset.m_SourceFontFile_EditorRef.dynamic == false) { Debug.LogWarning("Please set the [" + m_fontAsset.name + "] font to dynamic mode as this is required for Dynamic SDF support.", m_fontAsset.m_SourceFontFile_EditorRef); m_AtlasPopulationMode_prop.intValue = 0; serializedObject.ApplyModifiedProperties(); } else { m_fontAsset.sourceFontFile = m_fontAsset.m_SourceFontFile_EditorRef; /* // Set atlas textures to non readable. for (int i = 0; i < m_fontAsset.atlasTextures.Length; i++) { Texture2D tex = m_fontAsset.atlasTextures[i]; if (tex != null && tex.isReadable == false) { string texPath = AssetDatabase.GetAssetPath(tex.GetInstanceID()); Object[] paths = AssetDatabase.LoadAllAssetsAtPath(texPath); var texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter; if (texImporter != null) { texImporter.isReadable = true; AssetDatabase.ImportAsset(texPath); isDatabaseRefreshRequired = true; } } } */ Debug.Log("Atlas Population mode set to [Dynamic]."); } } if (isDatabaseRefreshRequired) AssetDatabase.Refresh(); serializedObject.Update(); isAssetDirty = true; } GUI.enabled = true; // Save state of atlas settings if (m_DisplayDestructiveChangeWarning == false) { SavedAtlasGenerationSettings(); //Undo.RegisterCompleteObjectUndo(m_fontAsset, "Font Asset Changes"); } EditorGUI.BeginChangeCheck(); // TODO: Switch shaders depending on GlyphRenderMode. EditorGUILayout.PropertyField(m_AtlasRenderMode_prop); EditorGUILayout.PropertyField(m_SamplingPointSize_prop, new GUIContent("Sampling Point Size")); if (EditorGUI.EndChangeCheck()) { m_DisplayDestructiveChangeWarning = true; } // Changes to these properties require updating Material Presets for this font asset. EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_AtlasPadding_prop, new GUIContent("Padding")); EditorGUILayout.IntPopup(m_AtlasWidth_prop, m_AtlasResolutionLabels, m_AtlasResolutions, new GUIContent("Atlas Width")); EditorGUILayout.IntPopup(m_AtlasHeight_prop, m_AtlasResolutionLabels, m_AtlasResolutions, new GUIContent("Atlas Height")); if (EditorGUI.EndChangeCheck()) { m_MaterialPresetsRequireUpdate = true; m_DisplayDestructiveChangeWarning = true; } if (m_DisplayDestructiveChangeWarning) { // These changes are destructive on the font asset rect = EditorGUILayout.GetControlRect(false, 60); rect.x += 15; rect.width -= 15; EditorGUI.HelpBox(rect, "Changing these settings will clear the font asset's character, glyph and texture data.", MessageType.Warning); if (GUI.Button(new Rect(rect.width - 140, rect.y + 36, 80, 18), new GUIContent("Apply"))) { m_DisplayDestructiveChangeWarning = false; // Update face info is sampling point size was changed. if (m_AtlasSettings.pointSize != m_SamplingPointSize_prop.intValue) { FontEngine.LoadFontFace(m_fontAsset.sourceFontFile, m_SamplingPointSize_prop.intValue); m_fontAsset.faceInfo = FontEngine.GetFaceInfo(); } // Update material m_fontAsset.material.SetFloat(ShaderUtilities.ID_TextureWidth, m_AtlasWidth_prop.intValue); m_fontAsset.material.SetFloat(ShaderUtilities.ID_TextureHeight, m_AtlasHeight_prop.intValue); m_fontAsset.material.SetFloat(ShaderUtilities.ID_GradientScale, m_AtlasPadding_prop.intValue + 1); // Update material presets if any of the relevant properties have been changed. if (m_MaterialPresetsRequireUpdate) { m_MaterialPresetsRequireUpdate = false; Material[] materialPresets = TMP_EditorUtility.FindMaterialReferences(m_fontAsset); for (int i = 0; i < materialPresets.Length; i++) { Material mat = materialPresets[i]; mat.SetFloat(ShaderUtilities.ID_TextureWidth, m_AtlasWidth_prop.intValue); mat.SetFloat(ShaderUtilities.ID_TextureHeight, m_AtlasHeight_prop.intValue); mat.SetFloat(ShaderUtilities.ID_GradientScale, m_AtlasPadding_prop.intValue + 1); } } m_fontAsset.ClearFontAssetData(); GUIUtility.keyboardControl = 0; isAssetDirty = true; // Update Font Asset Creation Settings to reflect new changes. UpdateFontAssetCreationSettings(); // TODO: Clear undo buffers. //Undo.ClearUndo(m_fontAsset); } if (GUI.Button(new Rect(rect.width - 56, rect.y + 36, 80, 18), new GUIContent("Revert"))) { m_DisplayDestructiveChangeWarning = false; RestoreAtlasGenerationSettings(); GUIUtility.keyboardControl = 0; // TODO: Clear undo buffers. //Undo.ClearUndo(m_fontAsset); } } EditorGUILayout.Space(); } #endregion // ATLAS & MATERIAL PANEL #region Atlas & Material rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Atlas & Material"), TMP_UIStyleManager.sectionHeader)) UI_PanelState.fontAtlasInfoPanel = !UI_PanelState.fontAtlasInfoPanel; GUI.Label(rect, (UI_PanelState.fontAtlasInfoPanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.fontAtlasInfoPanel) { EditorGUI.indentLevel = 1; GUI.enabled = false; EditorGUILayout.PropertyField(font_atlas_prop, new GUIContent("Font Atlas")); EditorGUILayout.PropertyField(font_material_prop, new GUIContent("Font Material")); GUI.enabled = true; EditorGUILayout.Space(); } #endregion string evt_cmd = Event.current.commandName; // Get Current Event CommandName to check for Undo Events // FONT WEIGHT PANEL #region Font Weights rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Font Weights", "The Font Assets that will be used for different font weights and the settings used to simulate a typeface when no asset is available."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.fontWeightPanel = !UI_PanelState.fontWeightPanel; GUI.Label(rect, (UI_PanelState.fontWeightPanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.fontWeightPanel) { EditorGUIUtility.labelWidth *= 0.75f; EditorGUIUtility.fieldWidth *= 0.25f; EditorGUILayout.BeginVertical(); EditorGUI.indentLevel = 1; rect = EditorGUILayout.GetControlRect(true); rect.x += EditorGUIUtility.labelWidth; rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f; GUI.Label(rect, "Regular Tyepface", EditorStyles.label); rect.x += rect.width; GUI.Label(rect, "Italic Typeface", EditorStyles.label); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(1), new GUIContent("100 - Thin")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(2), new GUIContent("200 - Extra-Light")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(3), new GUIContent("300 - Light")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(4), new GUIContent("400 - Regular")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(5), new GUIContent("500 - Medium")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(6), new GUIContent("600 - Semi-Bold")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(7), new GUIContent("700 - Bold")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(8), new GUIContent("800 - Heavy")); EditorGUILayout.PropertyField(fontWeights_prop.GetArrayElementAtIndex(9), new GUIContent("900 - Black")); EditorGUILayout.EndVertical(); EditorGUILayout.Space(); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(font_normalStyle_prop, new GUIContent("Normal Weight")); font_normalStyle_prop.floatValue = Mathf.Clamp(font_normalStyle_prop.floatValue, -3.0f, 3.0f); if (GUI.changed || evt_cmd == k_UndoRedo) { GUI.changed = false; // Modify the material property on matching material presets. for (int i = 0; i < m_materialPresets.Length; i++) m_materialPresets[i].SetFloat("_WeightNormal", font_normalStyle_prop.floatValue); } EditorGUILayout.PropertyField(font_boldStyle_prop, new GUIContent("Bold Weight")); font_boldStyle_prop.floatValue = Mathf.Clamp(font_boldStyle_prop.floatValue, -3.0f, 3.0f); if (GUI.changed || evt_cmd == k_UndoRedo) { GUI.changed = false; // Modify the material property on matching material presets. for (int i = 0; i < m_materialPresets.Length; i++) m_materialPresets[i].SetFloat("_WeightBold", font_boldStyle_prop.floatValue); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(font_normalSpacing_prop, new GUIContent("Spacing Offset")); font_normalSpacing_prop.floatValue = Mathf.Clamp(font_normalSpacing_prop.floatValue, -100, 100); if (GUI.changed || evt_cmd == k_UndoRedo) { GUI.changed = false; } EditorGUILayout.PropertyField(font_boldSpacing_prop, new GUIContent("Bold Spacing")); font_boldSpacing_prop.floatValue = Mathf.Clamp(font_boldSpacing_prop.floatValue, 0, 100); if (GUI.changed || evt_cmd == k_UndoRedo) { GUI.changed = false; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(font_italicStyle_prop, new GUIContent("Italic Style")); font_italicStyle_prop.intValue = Mathf.Clamp(font_italicStyle_prop.intValue, 15, 60); EditorGUILayout.PropertyField(font_tabSize_prop, new GUIContent("Tab Multiple")); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.Space(); } EditorGUIUtility.labelWidth = 0; EditorGUIUtility.fieldWidth = 0; #endregion // FALLBACK FONT ASSETS #region Fallback Font Asset rect = EditorGUILayout.GetControlRect(false, 24); EditorGUI.indentLevel = 0; if (GUI.Button(rect, new GUIContent("Fallback Font Assets", "Select the Font Assets that will be searched and used as fallback when characters are missing from this font asset."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.fallbackFontAssetPanel = !UI_PanelState.fallbackFontAssetPanel; GUI.Label(rect, (UI_PanelState.fallbackFontAssetPanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.fallbackFontAssetPanel) { EditorGUIUtility.labelWidth = 120; EditorGUI.indentLevel = 0; m_list.DoLayoutList(); EditorGUILayout.Space(); } #endregion // CHARACTER TABLE TABLE #region Character Table EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; EditorGUI.indentLevel = 0; rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Character Table", "List of characters contained in this font asset."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.characterTablePanel = !UI_PanelState.characterTablePanel; GUI.Label(rect, (UI_PanelState.characterTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.characterTablePanel) { int arraySize = m_CharacterTable_prop.arraySize; int itemsPerPage = 15; // Display Glyph Management Tools EditorGUILayout.BeginVertical(EditorStyles.helpBox); { // Search Bar implementation #region DISPLAY SEARCH BAR EditorGUILayout.BeginHorizontal(); { EditorGUIUtility.labelWidth = 130f; EditorGUI.BeginChangeCheck(); string searchPattern = EditorGUILayout.TextField("Character Search", m_CharacterSearchPattern, "SearchTextField"); if (EditorGUI.EndChangeCheck() || m_isSearchDirty) { if (string.IsNullOrEmpty(searchPattern) == false) { m_CharacterSearchPattern = searchPattern; // Search Character Table for potential matches SearchCharacterTable (m_CharacterSearchPattern, ref m_CharacterSearchList); } else m_CharacterSearchPattern = null; m_isSearchDirty = false; } string styleName = string.IsNullOrEmpty(m_CharacterSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton"; if (GUILayout.Button(GUIContent.none, styleName)) { GUIUtility.keyboardControl = 0; m_CharacterSearchPattern = string.Empty; } } EditorGUILayout.EndHorizontal(); #endregion // Display Page Navigation if (!string.IsNullOrEmpty(m_CharacterSearchPattern)) arraySize = m_CharacterSearchList.Count; DisplayPageNavigation(ref m_CurrentCharacterPage, arraySize, itemsPerPage); } EditorGUILayout.EndVertical(); // Display Character Table Elements if (arraySize > 0) { // Display each character entry using the CharacterPropertyDrawer. for (int i = itemsPerPage * m_CurrentCharacterPage; i < arraySize && i < itemsPerPage * (m_CurrentCharacterPage + 1); i++) { // Define the start of the selection region of the element. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); int elementIndex = i; if (!string.IsNullOrEmpty(m_CharacterSearchPattern)) elementIndex = m_CharacterSearchList[i]; SerializedProperty characterProperty = m_CharacterTable_prop.GetArrayElementAtIndex(elementIndex); EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUI.BeginDisabledGroup(i != m_SelectedCharacterRecord); { EditorGUILayout.PropertyField(characterProperty); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); // Define the end of the selection region of the element. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); // Check for Item selection Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y); if (DoSelectionCheck(selectionArea)) { if (m_SelectedCharacterRecord == i) m_SelectedCharacterRecord = -1; else { m_SelectedCharacterRecord = i; m_AddCharacterWarning.isEnabled = false; m_unicodeHexLabel = k_placeholderUnicodeHex; GUIUtility.keyboardControl = 0; } } // Draw Selection Highlight and Glyph Options if (m_SelectedCharacterRecord == i) { TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255)); // Draw Glyph management options Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f); float optionAreaWidth = controlRect.width * 0.6f; float btnWidth = optionAreaWidth / 3; Rect position = new Rect(controlRect.x + controlRect.width * .4f, controlRect.y, btnWidth, controlRect.height); // Copy Selected Glyph to Target Glyph ID GUI.enabled = !string.IsNullOrEmpty(m_dstUnicode); if (GUI.Button(position, new GUIContent("Copy to"))) { GUIUtility.keyboardControl = 0; // Convert Hex Value to Decimal int dstGlyphID = TMP_TextUtilities.StringHexToInt(m_dstUnicode); //Add new glyph at target Unicode hex id. if (!AddNewCharacter(elementIndex, dstGlyphID)) { m_AddCharacterWarning.isEnabled = true; m_AddCharacterWarning.expirationTime = EditorApplication.timeSinceStartup + 1; } m_dstUnicode = string.Empty; m_isSearchDirty = true; TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, m_fontAsset); } // Target Glyph ID GUI.enabled = true; position.x += btnWidth; GUI.SetNextControlName("CharacterID_Input"); m_dstUnicode = EditorGUI.TextField(position, m_dstUnicode); // Placeholder text EditorGUI.LabelField(position, new GUIContent(m_unicodeHexLabel, "The Unicode (Hex) ID of the duplicated Character"), TMP_UIStyleManager.label); // Only filter the input when the destination glyph ID text field has focus. if (GUI.GetNameOfFocusedControl() == "CharacterID_Input") { m_unicodeHexLabel = string.Empty; //Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F')) { Event.current.character = '\0'; } } else { m_unicodeHexLabel = k_placeholderUnicodeHex; //m_dstUnicode = string.Empty; } // Remove Glyph position.x += btnWidth; if (GUI.Button(position, "Remove")) { GUIUtility.keyboardControl = 0; RemoveCharacterFromList(elementIndex); isAssetDirty = true; m_SelectedCharacterRecord = -1; m_isSearchDirty = true; break; } if (m_AddCharacterWarning.isEnabled && EditorApplication.timeSinceStartup < m_AddCharacterWarning.expirationTime) { EditorGUILayout.HelpBox("The Destination Character ID already exists", MessageType.Warning); } } } } DisplayPageNavigation(ref m_CurrentCharacterPage, arraySize, itemsPerPage); EditorGUILayout.Space(); } #endregion // GLYPH TABLE #region Glyph Table EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; EditorGUI.indentLevel = 0; rect = EditorGUILayout.GetControlRect(false, 24); GUIStyle glyphPanelStyle = new GUIStyle(EditorStyles.helpBox); if (GUI.Button(rect, new GUIContent("Glyph Table", "List of glyphs contained in this font asset."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.glyphTablePanel = !UI_PanelState.glyphTablePanel; GUI.Label(rect, (UI_PanelState.glyphTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.glyphTablePanel) { int arraySize = m_GlyphTable_prop.arraySize; int itemsPerPage = 15; // Display Glyph Management Tools EditorGUILayout.BeginVertical(EditorStyles.helpBox); { // Search Bar implementation #region DISPLAY SEARCH BAR EditorGUILayout.BeginHorizontal(); { EditorGUIUtility.labelWidth = 130f; EditorGUI.BeginChangeCheck(); string searchPattern = EditorGUILayout.TextField("Glyph Search", m_GlyphSearchPattern, "SearchTextField"); if (EditorGUI.EndChangeCheck() || m_isSearchDirty) { if (string.IsNullOrEmpty(searchPattern) == false) { m_GlyphSearchPattern = searchPattern; // Search Glyph Table for potential matches SearchGlyphTable(m_GlyphSearchPattern, ref m_GlyphSearchList); } else m_GlyphSearchPattern = null; m_isSearchDirty = false; } string styleName = string.IsNullOrEmpty(m_GlyphSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton"; if (GUILayout.Button(GUIContent.none, styleName)) { GUIUtility.keyboardControl = 0; m_GlyphSearchPattern = string.Empty; } } EditorGUILayout.EndHorizontal(); #endregion // Display Page Navigation if (!string.IsNullOrEmpty(m_GlyphSearchPattern)) arraySize = m_GlyphSearchList.Count; DisplayPageNavigation(ref m_CurrentGlyphPage, arraySize, itemsPerPage); } EditorGUILayout.EndVertical(); // Display Glyph Table Elements if (arraySize > 0) { // Display each GlyphInfo entry using the GlyphInfo property drawer. for (int i = itemsPerPage * m_CurrentGlyphPage; i < arraySize && i < itemsPerPage * (m_CurrentGlyphPage + 1); i++) { // Define the start of the selection region of the element. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); int elementIndex = i; if (!string.IsNullOrEmpty(m_GlyphSearchPattern)) elementIndex = m_GlyphSearchList[i]; SerializedProperty glyphProperty = m_GlyphTable_prop.GetArrayElementAtIndex(elementIndex); EditorGUILayout.BeginVertical(glyphPanelStyle); using (new EditorGUI.DisabledScope(i != m_SelectedGlyphRecord)) { EditorGUILayout.PropertyField(glyphProperty); } EditorGUILayout.EndVertical(); // Define the end of the selection region of the element. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); // Check for Item selection Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y); if (DoSelectionCheck(selectionArea)) { if (m_SelectedGlyphRecord == i) m_SelectedGlyphRecord = -1; else { m_SelectedGlyphRecord = i; m_AddGlyphWarning.isEnabled = false; m_unicodeHexLabel = k_placeholderUnicodeHex; GUIUtility.keyboardControl = 0; } } // Draw Selection Highlight and Glyph Options if (m_SelectedGlyphRecord == i) { TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255)); // Draw Glyph management options Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f); float optionAreaWidth = controlRect.width * 0.6f; float btnWidth = optionAreaWidth / 3; Rect position = new Rect(controlRect.x + controlRect.width * .4f, controlRect.y, btnWidth, controlRect.height); // Copy Selected Glyph to Target Glyph ID GUI.enabled = !string.IsNullOrEmpty(m_dstGlyphID); if (GUI.Button(position, new GUIContent("Copy to"))) { GUIUtility.keyboardControl = 0; // Convert Hex Value to Decimal int.TryParse(m_dstGlyphID, out int dstGlyphID); //Add new glyph at target Unicode hex id. if (!AddNewGlyph(elementIndex, dstGlyphID)) { m_AddGlyphWarning.isEnabled = true; m_AddGlyphWarning.expirationTime = EditorApplication.timeSinceStartup + 1; } m_dstGlyphID = string.Empty; m_isSearchDirty = true; TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, m_fontAsset); } // Target Glyph ID GUI.enabled = true; position.x += btnWidth; GUI.SetNextControlName("GlyphID_Input"); m_dstGlyphID = EditorGUI.TextField(position, m_dstGlyphID); // Placeholder text EditorGUI.LabelField(position, new GUIContent(m_GlyphIDLabel, "The Glyph ID of the duplicated Glyph"), TMP_UIStyleManager.label); // Only filter the input when the destination glyph ID text field has focus. if (GUI.GetNameOfFocusedControl() == "GlyphID_Input") { m_GlyphIDLabel = string.Empty; //Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9')) { Event.current.character = '\0'; } } else { m_GlyphIDLabel = k_placeholderGlyphID; //m_dstGlyphID = string.Empty; } // Remove Glyph position.x += btnWidth; if (GUI.Button(position, "Remove")) { GUIUtility.keyboardControl = 0; RemoveGlyphFromList(elementIndex); isAssetDirty = true; m_SelectedGlyphRecord = -1; m_isSearchDirty = true; break; } if (m_AddGlyphWarning.isEnabled && EditorApplication.timeSinceStartup < m_AddGlyphWarning.expirationTime) { EditorGUILayout.HelpBox("The Destination Glyph ID already exists", MessageType.Warning); } } } } DisplayPageNavigation(ref m_CurrentGlyphPage, arraySize, itemsPerPage); EditorGUILayout.Space(); } #endregion // FONT FEATURE TABLE #region Font Feature Table EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; EditorGUI.indentLevel = 0; rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Glyph Adjustment Table", "List of glyph adjustment / advanced kerning pairs."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.fontFeatureTablePanel = !UI_PanelState.fontFeatureTablePanel; GUI.Label(rect, (UI_PanelState.fontFeatureTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.fontFeatureTablePanel) { int arraySize = m_GlyphPairAdjustmentRecords_prop.arraySize; int itemsPerPage = 20; // Display Kerning Pair Management Tools EditorGUILayout.BeginVertical(EditorStyles.helpBox); { // Search Bar implementation #region DISPLAY SEARCH BAR EditorGUILayout.BeginHorizontal(); { EditorGUIUtility.labelWidth = 150f; EditorGUI.BeginChangeCheck(); string searchPattern = EditorGUILayout.TextField("Adjustment Pair Search", m_KerningTableSearchPattern, "SearchTextField"); if (EditorGUI.EndChangeCheck() || m_isSearchDirty) { if (string.IsNullOrEmpty(searchPattern) == false) { m_KerningTableSearchPattern = searchPattern; // Search Glyph Table for potential matches SearchKerningTable(m_KerningTableSearchPattern, ref m_KerningTableSearchList); } else m_KerningTableSearchPattern = null; m_isSearchDirty = false; } string styleName = string.IsNullOrEmpty(m_KerningTableSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton"; if (GUILayout.Button(GUIContent.none, styleName)) { GUIUtility.keyboardControl = 0; m_KerningTableSearchPattern = string.Empty; } } EditorGUILayout.EndHorizontal(); #endregion // Display Page Navigation if (!string.IsNullOrEmpty(m_KerningTableSearchPattern)) arraySize = m_KerningTableSearchList.Count; DisplayPageNavigation(ref m_CurrentKerningPage, arraySize, itemsPerPage); } EditorGUILayout.EndVertical(); if (arraySize > 0) { // Display each GlyphInfo entry using the GlyphInfo property drawer. for (int i = itemsPerPage * m_CurrentKerningPage; i < arraySize && i < itemsPerPage * (m_CurrentKerningPage + 1); i++) { // Define the start of the selection region of the element. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); int elementIndex = i; if (!string.IsNullOrEmpty(m_KerningTableSearchPattern)) elementIndex = m_KerningTableSearchList[i]; SerializedProperty pairAdjustmentRecordProperty = m_GlyphPairAdjustmentRecords_prop.GetArrayElementAtIndex(elementIndex); EditorGUILayout.BeginVertical(EditorStyles.helpBox); using (new EditorGUI.DisabledScope(i != m_SelectedAdjustmentRecord)) { EditorGUILayout.PropertyField(pairAdjustmentRecordProperty, new GUIContent("Selectable")); } EditorGUILayout.EndVertical(); // Define the end of the selection region of the element. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); // Check for Item selection Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y); if (DoSelectionCheck(selectionArea)) { if (m_SelectedAdjustmentRecord == i) { m_SelectedAdjustmentRecord = -1; } else { m_SelectedAdjustmentRecord = i; GUIUtility.keyboardControl = 0; } } // Draw Selection Highlight and Kerning Pair Options if (m_SelectedAdjustmentRecord == i) { TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255)); // Draw Glyph management options Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f); float optionAreaWidth = controlRect.width; float btnWidth = optionAreaWidth / 4; Rect position = new Rect(controlRect.x + controlRect.width - btnWidth, controlRect.y, btnWidth, controlRect.height); // Remove Kerning pair GUI.enabled = true; if (GUI.Button(position, "Remove")) { GUIUtility.keyboardControl = 0; RemoveAdjustmentPairFromList(i); isAssetDirty = true; m_SelectedAdjustmentRecord = -1; m_isSearchDirty = true; break; } } } } DisplayPageNavigation(ref m_CurrentKerningPage, arraySize, itemsPerPage); GUILayout.Space(5); // Add new kerning pair EditorGUILayout.BeginVertical(EditorStyles.helpBox); { EditorGUILayout.PropertyField(m_EmptyGlyphPairAdjustmentRecord_prop); } EditorGUILayout.EndVertical(); if (GUILayout.Button("Add New Glyph Adjustment Record")) { SerializedProperty firstAdjustmentRecordProperty = m_EmptyGlyphPairAdjustmentRecord_prop.FindPropertyRelative("m_FirstAdjustmentRecord"); SerializedProperty secondAdjustmentRecordProperty = m_EmptyGlyphPairAdjustmentRecord_prop.FindPropertyRelative("m_SecondAdjustmentRecord"); uint firstGlyphIndex = (uint)firstAdjustmentRecordProperty.FindPropertyRelative("m_GlyphIndex").intValue; uint secondGlyphIndex = (uint)secondAdjustmentRecordProperty.FindPropertyRelative("m_GlyphIndex").intValue; TMP_GlyphValueRecord firstValueRecord = GetValueRecord(firstAdjustmentRecordProperty.FindPropertyRelative("m_GlyphValueRecord")); TMP_GlyphValueRecord secondValueRecord = GetValueRecord(secondAdjustmentRecordProperty.FindPropertyRelative("m_GlyphValueRecord")); errorCode = -1; long pairKey = (long)secondGlyphIndex << 32 | firstGlyphIndex; if (m_FontFeatureTable.m_GlyphPairAdjustmentRecordLookupDictionary.ContainsKey(pairKey) == false) { TMP_GlyphPairAdjustmentRecord adjustmentRecord = new TMP_GlyphPairAdjustmentRecord(new TMP_GlyphAdjustmentRecord(firstGlyphIndex, firstValueRecord), new TMP_GlyphAdjustmentRecord(secondGlyphIndex, secondValueRecord)); m_FontFeatureTable.m_GlyphPairAdjustmentRecords.Add(adjustmentRecord); m_FontFeatureTable.m_GlyphPairAdjustmentRecordLookupDictionary.Add(pairKey, adjustmentRecord); errorCode = 0; } // Add glyphs and characters uint firstCharacter = m_SerializedPropertyHolder.firstCharacter; if (!m_fontAsset.characterLookupTable.ContainsKey(firstCharacter)) m_fontAsset.TryAddCharacterInternal(firstCharacter, out TMP_Character character); uint secondCharacter = m_SerializedPropertyHolder.secondCharacter; if (!m_fontAsset.characterLookupTable.ContainsKey(secondCharacter)) m_fontAsset.TryAddCharacterInternal(secondCharacter, out TMP_Character character); // Sort Kerning Pairs & Reload Font Asset if new kerning pair was added. if (errorCode != -1) { m_FontFeatureTable.SortGlyphPairAdjustmentRecords(); serializedObject.ApplyModifiedProperties(); isAssetDirty = true; m_isSearchDirty = true; } else { timeStamp = System.DateTime.Now.AddSeconds(5); } // Clear Add Kerning Pair Panel // TODO } if (errorCode == -1) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Kerning Pair already exists!", TMP_UIStyleManager.label); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); if (System.DateTime.Now > timeStamp) errorCode = 0; } } #endregion if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo || isAssetDirty) { // Delay callback until user has decided to Apply or Revert the changes. if (m_DisplayDestructiveChangeWarning == false) TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, m_fontAsset); if (m_fontAsset.m_IsFontAssetLookupTablesDirty || evt_cmd == k_UndoRedo) m_fontAsset.ReadFontAssetDefinition(); isAssetDirty = false; EditorUtility.SetDirty(target); } // Clear selection if mouse event was not consumed. GUI.enabled = true; if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0) m_SelectedAdjustmentRecord = -1; } void CleanFallbackFontAssetTable() { SerializedProperty m_FallbackFontAsseTable = serializedObject.FindProperty("m_FallbackFontAssetTable"); bool isListDirty = false; int elementCount = m_FallbackFontAsseTable.arraySize; for (int i = 0; i < elementCount; i++) { SerializedProperty element = m_FallbackFontAsseTable.GetArrayElementAtIndex(i); if (element.objectReferenceValue == null) { m_FallbackFontAsseTable.DeleteArrayElementAtIndex(i); elementCount -= 1; i -= 1; isListDirty = true; } } if (isListDirty) { serializedObject.ApplyModifiedProperties(); serializedObject.Update(); } } void SavedAtlasGenerationSettings() { m_AtlasSettings.glyphRenderMode = (GlyphRenderMode)m_AtlasRenderMode_prop.intValue; m_AtlasSettings.pointSize = m_SamplingPointSize_prop.intValue; m_AtlasSettings.padding = m_AtlasPadding_prop.intValue; m_AtlasSettings.atlasWidth = m_AtlasWidth_prop.intValue; m_AtlasSettings.atlasHeight = m_AtlasHeight_prop.intValue; } void RestoreAtlasGenerationSettings() { m_AtlasRenderMode_prop.intValue = (int)m_AtlasSettings.glyphRenderMode; m_SamplingPointSize_prop.intValue = m_AtlasSettings.pointSize; m_AtlasPadding_prop.intValue = m_AtlasSettings.padding; m_AtlasWidth_prop.intValue = m_AtlasSettings.atlasWidth; m_AtlasHeight_prop.intValue = m_AtlasSettings.atlasHeight; } void UpdateFontAssetCreationSettings() { m_fontAsset.m_CreationSettings.pointSize = m_SamplingPointSize_prop.intValue; m_fontAsset.m_CreationSettings.renderMode = m_AtlasRenderMode_prop.intValue; m_fontAsset.m_CreationSettings.padding = m_AtlasPadding_prop.intValue; m_fontAsset.m_CreationSettings.atlasWidth = m_AtlasWidth_prop.intValue; m_fontAsset.m_CreationSettings.atlasHeight = m_AtlasHeight_prop.intValue; } void UpdateCharacterData(SerializedProperty property, int index) { TMP_Character character = m_fontAsset.characterTable[index]; character.unicode = (uint)property.FindPropertyRelative("m_Unicode").intValue; character.scale = property.FindPropertyRelative("m_Scale").floatValue; SerializedProperty glyphProperty = property.FindPropertyRelative("m_Glyph"); character.glyph.index = (uint)glyphProperty.FindPropertyRelative("m_Index").intValue; SerializedProperty glyphRectProperty = glyphProperty.FindPropertyRelative("m_GlyphRect"); character.glyph.glyphRect = new GlyphRect(glyphRectProperty.FindPropertyRelative("m_X").intValue, glyphRectProperty.FindPropertyRelative("m_Y").intValue, glyphRectProperty.FindPropertyRelative("m_Width").intValue, glyphRectProperty.FindPropertyRelative("m_Height").intValue); SerializedProperty glyphMetricsProperty = glyphProperty.FindPropertyRelative("m_Metrics"); character.glyph.metrics = new GlyphMetrics(glyphMetricsProperty.FindPropertyRelative("m_Width").floatValue, glyphMetricsProperty.FindPropertyRelative("m_Height").floatValue, glyphMetricsProperty.FindPropertyRelative("m_HorizontalBearingX").floatValue, glyphMetricsProperty.FindPropertyRelative("m_HorizontalBearingY").floatValue, glyphMetricsProperty.FindPropertyRelative("m_HorizontalAdvance").floatValue); character.glyph.scale = glyphProperty.FindPropertyRelative("m_Scale").floatValue; character.glyph.atlasIndex = glyphProperty.FindPropertyRelative("m_AtlasIndex").intValue; } void UpdateGlyphData(SerializedProperty property, int index) { Glyph glyph = m_fontAsset.glyphTable[index]; glyph.index = (uint)property.FindPropertyRelative("m_Index").intValue; SerializedProperty glyphRect = property.FindPropertyRelative("m_GlyphRect"); glyph.glyphRect = new GlyphRect(glyphRect.FindPropertyRelative("m_X").intValue, glyphRect.FindPropertyRelative("m_Y").intValue, glyphRect.FindPropertyRelative("m_Width").intValue, glyphRect.FindPropertyRelative("m_Height").intValue); SerializedProperty glyphMetrics = property.FindPropertyRelative("m_Metrics"); glyph.metrics = new GlyphMetrics(glyphMetrics.FindPropertyRelative("m_Width").floatValue, glyphMetrics.FindPropertyRelative("m_Height").floatValue, glyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue, glyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue, glyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue); glyph.scale = property.FindPropertyRelative("m_Scale").floatValue; } void DisplayPageNavigation(ref int currentPage, int arraySize, int itemsPerPage) { Rect pagePos = EditorGUILayout.GetControlRect(false, 20); pagePos.width /= 3; int shiftMultiplier = Event.current.shift ? 10 : 1; // Page + Shift goes 10 page forward // Previous Page GUI.enabled = currentPage > 0; if (GUI.Button(pagePos, "Previous Page")) currentPage -= 1 * shiftMultiplier; // Page Counter GUI.enabled = true; pagePos.x += pagePos.width; int totalPages = (int)(arraySize / (float)itemsPerPage + 0.999f); GUI.Label(pagePos, "Page " + (currentPage + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel); // Next Page pagePos.x += pagePos.width; GUI.enabled = itemsPerPage * (currentPage + 1) < arraySize; if (GUI.Button(pagePos, "Next Page")) currentPage += 1 * shiftMultiplier; // Clamp page range currentPage = Mathf.Clamp(currentPage, 0, arraySize / itemsPerPage); GUI.enabled = true; } /// /// /// /// /// bool AddNewGlyph(int srcIndex, int dstGlyphID) { // Make sure Destination Glyph ID doesn't already contain a Glyph if (m_fontAsset.glyphLookupTable.ContainsKey((uint)dstGlyphID)) return false; // Add new element to glyph list. m_GlyphTable_prop.arraySize += 1; // Get a reference to the source glyph. SerializedProperty sourceGlyph = m_GlyphTable_prop.GetArrayElementAtIndex(srcIndex); int dstIndex = m_GlyphTable_prop.arraySize - 1; // Get a reference to the target / destination glyph. SerializedProperty targetGlyph = m_GlyphTable_prop.GetArrayElementAtIndex(dstIndex); CopyGlyphSerializedProperty(sourceGlyph, ref targetGlyph); // Update the ID of the glyph targetGlyph.FindPropertyRelative("m_Index").intValue = dstGlyphID; serializedObject.ApplyModifiedProperties(); m_fontAsset.SortGlyphTable(); m_fontAsset.ReadFontAssetDefinition(); return true; } /// /// /// /// void RemoveGlyphFromList(int index) { if (index > m_GlyphTable_prop.arraySize) return; int targetGlyphIndex = m_GlyphTable_prop.GetArrayElementAtIndex(index).FindPropertyRelative("m_Index").intValue; m_GlyphTable_prop.DeleteArrayElementAtIndex(index); // Remove all characters referencing this glyph. for (int i = 0; i < m_CharacterTable_prop.arraySize; i++) { int glyphIndex = m_CharacterTable_prop.GetArrayElementAtIndex(i).FindPropertyRelative("m_GlyphIndex").intValue; if (glyphIndex == targetGlyphIndex) { // Remove character m_CharacterTable_prop.DeleteArrayElementAtIndex(i); } } serializedObject.ApplyModifiedProperties(); m_fontAsset.ReadFontAssetDefinition(); } bool AddNewCharacter(int srcIndex, int dstGlyphID) { // Make sure Destination Glyph ID doesn't already contain a Glyph if (m_fontAsset.characterLookupTable.ContainsKey((uint)dstGlyphID)) return false; // Add new element to glyph list. m_CharacterTable_prop.arraySize += 1; // Get a reference to the source glyph. SerializedProperty sourceCharacter = m_CharacterTable_prop.GetArrayElementAtIndex(srcIndex); int dstIndex = m_CharacterTable_prop.arraySize - 1; // Get a reference to the target / destination glyph. SerializedProperty targetCharacter = m_CharacterTable_prop.GetArrayElementAtIndex(dstIndex); CopyCharacterSerializedProperty(sourceCharacter, ref targetCharacter); // Update the ID of the glyph targetCharacter.FindPropertyRelative("m_Unicode").intValue = dstGlyphID; serializedObject.ApplyModifiedProperties(); m_fontAsset.SortCharacterTable(); m_fontAsset.ReadFontAssetDefinition(); return true; } void RemoveCharacterFromList(int index) { if (index > m_CharacterTable_prop.arraySize) return; m_CharacterTable_prop.DeleteArrayElementAtIndex(index); serializedObject.ApplyModifiedProperties(); m_fontAsset.ReadFontAssetDefinition(); } // Check if any of the Style elements were clicked on. private bool DoSelectionCheck(Rect selectionArea) { Event currentEvent = Event.current; switch (currentEvent.type) { case EventType.MouseDown: if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0) { currentEvent.Use(); return true; } break; } return false; } TMP_GlyphValueRecord GetValueRecord(SerializedProperty property) { TMP_GlyphValueRecord record = new TMP_GlyphValueRecord(); record.xPlacement = property.FindPropertyRelative("m_XPlacement").floatValue; record.yPlacement = property.FindPropertyRelative("m_YPlacement").floatValue; record.xAdvance = property.FindPropertyRelative("m_XAdvance").floatValue; record.yAdvance = property.FindPropertyRelative("m_YAdvance").floatValue; return record; } void RemoveAdjustmentPairFromList(int index) { if (index > m_GlyphPairAdjustmentRecords_prop.arraySize) return; m_GlyphPairAdjustmentRecords_prop.DeleteArrayElementAtIndex(index); serializedObject.ApplyModifiedProperties(); m_fontAsset.ReadFontAssetDefinition(); } /// /// /// /// /// void CopyGlyphSerializedProperty(SerializedProperty srcGlyph, ref SerializedProperty dstGlyph) { // TODO : Should make a generic function which copies each of the properties. dstGlyph.FindPropertyRelative("m_Index").intValue = srcGlyph.FindPropertyRelative("m_Index").intValue; // Glyph -> GlyphMetrics SerializedProperty srcGlyphMetrics = srcGlyph.FindPropertyRelative("m_Metrics"); SerializedProperty dstGlyphMetrics = dstGlyph.FindPropertyRelative("m_Metrics"); dstGlyphMetrics.FindPropertyRelative("m_Width").floatValue = srcGlyphMetrics.FindPropertyRelative("m_Width").floatValue; dstGlyphMetrics.FindPropertyRelative("m_Height").floatValue = srcGlyphMetrics.FindPropertyRelative("m_Height").floatValue; dstGlyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue; dstGlyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue; dstGlyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue; // Glyph -> GlyphRect SerializedProperty srcGlyphRect = srcGlyph.FindPropertyRelative("m_GlyphRect"); SerializedProperty dstGlyphRect = dstGlyph.FindPropertyRelative("m_GlyphRect"); dstGlyphRect.FindPropertyRelative("m_X").intValue = srcGlyphRect.FindPropertyRelative("m_X").intValue; dstGlyphRect.FindPropertyRelative("m_Y").intValue = srcGlyphRect.FindPropertyRelative("m_Y").intValue; dstGlyphRect.FindPropertyRelative("m_Width").intValue = srcGlyphRect.FindPropertyRelative("m_Width").intValue; dstGlyphRect.FindPropertyRelative("m_Height").intValue = srcGlyphRect.FindPropertyRelative("m_Height").intValue; dstGlyph.FindPropertyRelative("m_Scale").floatValue = srcGlyph.FindPropertyRelative("m_Scale").floatValue; dstGlyph.FindPropertyRelative("m_AtlasIndex").intValue = srcGlyph.FindPropertyRelative("m_AtlasIndex").intValue; } void CopyCharacterSerializedProperty(SerializedProperty source, ref SerializedProperty target) { // TODO : Should make a generic function which copies each of the properties. int unicode = source.FindPropertyRelative("m_Unicode").intValue; target.FindPropertyRelative("m_Unicode").intValue = unicode; int srcGlyphIndex = source.FindPropertyRelative("m_GlyphIndex").intValue; target.FindPropertyRelative("m_GlyphIndex").intValue = srcGlyphIndex; target.FindPropertyRelative("m_Scale").floatValue = source.FindPropertyRelative("m_Scale").floatValue; } /// /// /// /// /// void SearchGlyphTable (string searchPattern, ref List searchResults) { if (searchResults == null) searchResults = new List(); searchResults.Clear(); int arraySize = m_GlyphTable_prop.arraySize; for (int i = 0; i < arraySize; i++) { SerializedProperty sourceGlyph = m_GlyphTable_prop.GetArrayElementAtIndex(i); int id = sourceGlyph.FindPropertyRelative("m_Index").intValue; // Check for potential match against a character. //if (searchPattern.Length == 1 && id == searchPattern[0]) // searchResults.Add(i); // Check for potential match against decimal id if (id.ToString().Contains(searchPattern)) searchResults.Add(i); //if (id.ToString("x").Contains(searchPattern)) // searchResults.Add(i); //if (id.ToString("X").Contains(searchPattern)) // searchResults.Add(i); } } void SearchCharacterTable(string searchPattern, ref List searchResults) { if (searchResults == null) searchResults = new List(); searchResults.Clear(); int arraySize = m_CharacterTable_prop.arraySize; for (int i = 0; i < arraySize; i++) { SerializedProperty sourceCharacter = m_CharacterTable_prop.GetArrayElementAtIndex(i); int id = sourceCharacter.FindPropertyRelative("m_Unicode").intValue; // Check for potential match against a character. if (searchPattern.Length == 1 && id == searchPattern[0]) searchResults.Add(i); else if (id.ToString("x").Contains(searchPattern)) searchResults.Add(i); else if (id.ToString("X").Contains(searchPattern)) searchResults.Add(i); // Check for potential match against decimal id //if (id.ToString().Contains(searchPattern)) // searchResults.Add(i); } } void SearchKerningTable(string searchPattern, ref List searchResults) { if (searchResults == null) searchResults = new List(); searchResults.Clear(); // Lookup glyph index of potential characters contained in the search pattern. uint firstGlyphIndex = 0; if (searchPattern.Length > 0 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[0], out TMP_Character firstCharacterSearch)) firstGlyphIndex = firstCharacterSearch.glyphIndex; uint secondGlyphIndex = 0; if (searchPattern.Length > 1 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[1], out TMP_Character secondCharacterSearch)) secondGlyphIndex = secondCharacterSearch.glyphIndex; int arraySize = m_GlyphPairAdjustmentRecords_prop.arraySize; for (int i = 0; i < arraySize; i++) { SerializedProperty record = m_GlyphPairAdjustmentRecords_prop.GetArrayElementAtIndex(i); SerializedProperty firstAdjustmentRecord = record.FindPropertyRelative("m_FirstAdjustmentRecord"); SerializedProperty secondAdjustmentRecord = record.FindPropertyRelative("m_SecondAdjustmentRecord"); int firstGlyph = firstAdjustmentRecord.FindPropertyRelative("m_GlyphIndex").intValue; int secondGlyph = secondAdjustmentRecord.FindPropertyRelative("m_GlyphIndex").intValue; if (firstGlyphIndex == firstGlyph && secondGlyphIndex == secondGlyph) searchResults.Add(i); else if (searchPattern.Length == 1 && (firstGlyphIndex == firstGlyph || firstGlyphIndex == secondGlyph)) searchResults.Add(i); else if (firstGlyph.ToString().Contains(searchPattern)) searchResults.Add(i); else if (secondGlyph.ToString().Contains(searchPattern)) searchResults.Add(i); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_FontAssetEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 96b44f7d98314b139324a8a87eb66067 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_FontAsset_CreationMenu.cs ================================================ using UnityEngine; using UnityEditor; using System.Linq; using System.IO; using System.Collections; using System.Collections.Generic; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using TMPro; namespace TMPro { public static class TMP_FontAsset_CreationMenu { /* [MenuItem("Assets/Create/TextMeshPro/Font Asset Fallback", false, 105)] public static void CreateFallbackFontAsset() { Object target = Selection.activeObject; // Make sure the selection is a font file if (target == null || target.GetType() != typeof(TMP_FontAsset)) { Debug.LogWarning("A Font file must first be selected in order to create a Font Asset."); return; } TMP_FontAsset sourceFontAsset = (TMP_FontAsset)target; string sourceFontFilePath = AssetDatabase.GetAssetPath(target); string folderPath = Path.GetDirectoryName(sourceFontFilePath); string assetName = Path.GetFileNameWithoutExtension(sourceFontFilePath); string newAssetFilePathWithName = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + " - Fallback.asset"); //// Create new TM Font Asset. TMP_FontAsset fontAsset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(fontAsset, newAssetFilePathWithName); fontAsset.version = "1.1.0"; fontAsset.faceInfo = sourceFontAsset.faceInfo; fontAsset.m_SourceFontFileGUID = sourceFontAsset.m_SourceFontFileGUID; fontAsset.m_SourceFontFile_EditorRef = sourceFontAsset.m_SourceFontFile_EditorRef; fontAsset.atlasPopulationMode = TMP_FontAsset.AtlasPopulationMode.Dynamic; int atlasWidth = fontAsset.atlasWidth = sourceFontAsset.atlasWidth; int atlasHeight = fontAsset.atlasHeight = sourceFontAsset.atlasHeight; int atlasPadding = fontAsset.atlasPadding = sourceFontAsset.atlasPadding; fontAsset.atlasRenderMode = sourceFontAsset.atlasRenderMode; // Initialize array for the font atlas textures. fontAsset.atlasTextures = new Texture2D[1]; // Create and add font atlas texture Texture2D texture = new Texture2D(atlasWidth, atlasHeight, TextureFormat.Alpha8, false); Color32[] colors = new Color32[atlasWidth * atlasHeight]; texture.SetPixels32(colors); texture.name = assetName + " Atlas"; fontAsset.atlasTextures[0] = texture; AssetDatabase.AddObjectToAsset(texture, fontAsset); // Add free rectangle of the size of the texture. int packingModifier = ((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP ? 0 : 1; fontAsset.m_FreeGlyphRects = new List() { new GlyphRect(0, 0, atlasWidth - packingModifier, atlasHeight - packingModifier) }; fontAsset.m_UsedGlyphRects = new List(); // Create new Material and Add it as Sub-Asset Material tmp_material = new Material(sourceFontAsset.material); tmp_material.name = texture.name + " Material"; tmp_material.SetTexture(ShaderUtilities.ID_MainTex, texture); tmp_material.SetFloat(ShaderUtilities.ID_TextureWidth, atlasWidth); tmp_material.SetFloat(ShaderUtilities.ID_TextureHeight, atlasHeight); tmp_material.SetFloat(ShaderUtilities.ID_GradientScale, atlasPadding + packingModifier); tmp_material.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle); tmp_material.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle); fontAsset.material = tmp_material; AssetDatabase.AddObjectToAsset(tmp_material, fontAsset); // Add Font Asset Creation Settings // TODO // Not sure if this is still necessary in newer versions of Unity. EditorUtility.SetDirty(fontAsset); AssetDatabase.SaveAssets(); } */ //[MenuItem("Assets/Create/TextMeshPro/Font Asset #%F12", true)] //public static bool CreateFontAssetMenuValidation() //{ // return false; //} [MenuItem("Assets/Create/TextMeshPro/Font Asset #%F12", false, 100)] public static void CreateFontAsset() { Object target = Selection.activeObject; // Make sure the selection is a font file if (target == null || target.GetType() != typeof(Font)) { Debug.LogWarning("A Font file must first be selected in order to create a Font Asset."); return; } Font sourceFont = (Font)target; string sourceFontFilePath = AssetDatabase.GetAssetPath(target); string folderPath = Path.GetDirectoryName(sourceFontFilePath); string assetName = Path.GetFileNameWithoutExtension(sourceFontFilePath); string newAssetFilePathWithName = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + " SDF.asset"); //// Create new TM Font Asset. TMP_FontAsset fontAsset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(fontAsset, newAssetFilePathWithName); fontAsset.version = "1.1.0"; // Set face information FontEngine.InitializeFontEngine(); FontEngine.LoadFontFace(sourceFont, 90); fontAsset.faceInfo = FontEngine.GetFaceInfo(); // Set font reference and GUID fontAsset.m_SourceFontFileGUID = AssetDatabase.AssetPathToGUID(sourceFontFilePath); fontAsset.m_SourceFontFile_EditorRef = sourceFont; fontAsset.atlasPopulationMode = AtlasPopulationMode.Dynamic; // Default atlas resolution is 1024 x 1024. int atlasWidth = fontAsset.atlasWidth = 1024; int atlasHeight = fontAsset.atlasHeight = 1024; int atlasPadding = fontAsset.atlasPadding = 9; fontAsset.atlasRenderMode = GlyphRenderMode.SDFAA; // Initialize array for the font atlas textures. fontAsset.atlasTextures = new Texture2D[1]; // Create atlas texture of size zero. Texture2D texture = new Texture2D(0, 0, TextureFormat.Alpha8, false); texture.name = assetName + " Atlas"; fontAsset.atlasTextures[0] = texture; AssetDatabase.AddObjectToAsset(texture, fontAsset); // Add free rectangle of the size of the texture. int packingModifier = ((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP ? 0 : 1; fontAsset.freeGlyphRects = new List() { new GlyphRect(0, 0, atlasWidth - packingModifier, atlasHeight - packingModifier) }; fontAsset.usedGlyphRects = new List(); // Create new Material and Add it as Sub-Asset Shader default_Shader = Shader.Find("TextMeshPro/Distance Field"); Material tmp_material = new Material(default_Shader); tmp_material.name = texture.name + " Material"; tmp_material.SetTexture(ShaderUtilities.ID_MainTex, texture); tmp_material.SetFloat(ShaderUtilities.ID_TextureWidth, atlasWidth); tmp_material.SetFloat(ShaderUtilities.ID_TextureHeight, atlasHeight); tmp_material.SetFloat(ShaderUtilities.ID_GradientScale, atlasPadding + packingModifier); tmp_material.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle); tmp_material.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle); fontAsset.material = tmp_material; AssetDatabase.AddObjectToAsset(tmp_material, fontAsset); // Add Font Asset Creation Settings fontAsset.creationSettings = new FontAssetCreationSettings(fontAsset.m_SourceFontFileGUID, fontAsset.faceInfo.pointSize, 0, atlasPadding, 0, 1024, 1024, 7, string.Empty, (int)GlyphRenderMode.SDFAA); // Not sure if this is still necessary in newer versions of Unity. EditorUtility.SetDirty(fontAsset); AssetDatabase.SaveAssets(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_FontAsset_CreationMenu.cs.meta ================================================ fileFormatVersion: 2 guid: 7496af95dfe67cf429ac65edaaf99106 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEditor; using System.Collections; using System.Text.RegularExpressions; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_GlyphPairAdjustmentRecord))] public class TMP_GlyphPairAdjustmentRecordPropertyDrawer : PropertyDrawer { private bool isEditingEnabled = false; private bool isSelectable = false; private string m_FirstCharacter = string.Empty; private string m_SecondCharacter = string.Empty; private string m_PreviousInput; static GUIContent s_CharacterTextFieldLabel = new GUIContent("Char:", "Enter the character or its UTF16 or UTF32 Unicode character escape sequence. For UTF16 use \"\\uFF00\" and for UTF32 use \"\\UFF00FF00\" representation."); public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_FirstAdjustmentRecord = property.FindPropertyRelative("m_FirstAdjustmentRecord"); SerializedProperty prop_SecondAdjustmentRecord = property.FindPropertyRelative("m_SecondAdjustmentRecord"); SerializedProperty prop_FirstGlyphIndex = prop_FirstAdjustmentRecord.FindPropertyRelative("m_GlyphIndex"); SerializedProperty prop_FirstGlyphValueRecord = prop_FirstAdjustmentRecord.FindPropertyRelative("m_GlyphValueRecord"); SerializedProperty prop_SecondGlyphIndex = prop_SecondAdjustmentRecord.FindPropertyRelative("m_GlyphIndex"); SerializedProperty prop_SecondGlyphValueRecord = prop_SecondAdjustmentRecord.FindPropertyRelative("m_GlyphValueRecord"); SerializedProperty prop_FontFeatureLookupFlags = property.FindPropertyRelative("m_FeatureLookupFlags"); position.yMin += 2; float width = position.width / 2; float padding = 5.0f; Rect rect; isEditingEnabled = GUI.enabled; isSelectable = label.text == "Selectable" ? true : false; if (isSelectable) GUILayoutUtility.GetRect(position.width, 75); else GUILayoutUtility.GetRect(position.width, 55); GUIStyle style = new GUIStyle(EditorStyles.label); style.richText = true; // First Glyph GUI.enabled = isEditingEnabled; if (isSelectable) { rect = new Rect(position.x + 70, position.y, position.width, 49); float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_FirstGlyphIndex.intValue)).x; EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: " + prop_FirstGlyphIndex.intValue + ""), style); GUI.enabled = isEditingEnabled; EditorGUIUtility.labelWidth = 30f; rect = new Rect(position.x + 70, position.y + 10, (width - 70) - padding, 18); EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX:")); rect.y += 20; EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY:")); rect.y += 20; EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX:")); //rect.y += 20; //EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_YAdvance"), new GUIContent("AY:")); DrawGlyph((uint)prop_FirstGlyphIndex.intValue, new Rect(position.x, position.y, position.width, position.height), property); } else { rect = new Rect(position.x, position.y, width / 2 * 0.8f - padding, 18); EditorGUIUtility.labelWidth = 40f; // First Character Lookup GUI.SetNextControlName("FirstCharacterField"); EditorGUI.BeginChangeCheck(); string firstCharacter = EditorGUI.TextField(rect, s_CharacterTextFieldLabel, m_FirstCharacter); if (GUI.GetNameOfFocusedControl() == "FirstCharacterField") { if (ValidateInput(firstCharacter)) { //Debug.Log("1st Unicode value: [" + firstCharacter + "]"); uint unicode = GetUnicodeCharacter(firstCharacter); // Lookup glyph index TMP_SerializedPropertyHolder propertyHolder = property.serializedObject.targetObject as TMP_SerializedPropertyHolder; TMP_FontAsset fontAsset = propertyHolder.fontAsset; if (fontAsset != null) { prop_FirstGlyphIndex.intValue = (int)fontAsset.GetGlyphIndex(unicode); propertyHolder.firstCharacter = unicode; } } } if (EditorGUI.EndChangeCheck()) m_FirstCharacter = firstCharacter; // First Glyph Index rect.x += width / 2 * 0.8f; EditorGUIUtility.labelWidth = 25f; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(rect, prop_FirstGlyphIndex, new GUIContent("ID:")); if (EditorGUI.EndChangeCheck()) { } GUI.enabled = isEditingEnabled; EditorGUIUtility.labelWidth = 25f; rect = new Rect(position.x, position.y + 20, width * 0.5f - padding, 18); EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX")); rect.x += width * 0.5f; EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY")); rect.x = position.x; rect.y += 20; EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX")); //rect.x += width * 0.5f; //EditorGUI.PropertyField(rect, prop_FirstGlyphAdjustment.FindPropertyRelative("m_YAdvance"), new GUIContent("AY")); } // Second Glyph GUI.enabled = isEditingEnabled; if (isSelectable) { float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_SecondGlyphIndex.intValue)).x; EditorGUI.LabelField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: " + prop_SecondGlyphIndex.intValue + ""), style); GUI.enabled = isEditingEnabled; EditorGUIUtility.labelWidth = 30f; rect = new Rect(position.width / 2 + 20 + 70, position.y + 10, (width - 70) - padding, 18); EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX:")); rect.y += 20; EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY:")); rect.y += 20; EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX:")); //rect.y += 20; //EditorGUI.PropertyField(rect, prop_SecondGlyphAdjustment.FindPropertyRelative("m_YAdvance"), new GUIContent("AY")); DrawGlyph((uint)prop_SecondGlyphIndex.intValue, new Rect(position.width / 2 + 20, position.y, position.width, position.height), property); } else { rect = new Rect(position.width / 2 + 20, position.y, width / 2 * 0.8f - padding, 18); EditorGUIUtility.labelWidth = 40f; // Second Character Lookup GUI.SetNextControlName("SecondCharacterField"); EditorGUI.BeginChangeCheck(); string secondCharacter = EditorGUI.TextField(rect, s_CharacterTextFieldLabel, m_SecondCharacter); if (GUI.GetNameOfFocusedControl() == "SecondCharacterField") { if (ValidateInput(secondCharacter)) { //Debug.Log("2nd Unicode value: [" + secondCharacter + "]"); uint unicode = GetUnicodeCharacter(secondCharacter); // Lookup glyph index TMP_SerializedPropertyHolder propertyHolder = property.serializedObject.targetObject as TMP_SerializedPropertyHolder; TMP_FontAsset fontAsset = propertyHolder.fontAsset; if (fontAsset != null) { prop_SecondGlyphIndex.intValue = (int)fontAsset.GetGlyphIndex(unicode); propertyHolder.secondCharacter = unicode; } } } if (EditorGUI.EndChangeCheck()) m_SecondCharacter = secondCharacter; // Second Glyph Index rect.x += width / 2 * 0.8f; EditorGUIUtility.labelWidth = 25f; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(rect, prop_SecondGlyphIndex, new GUIContent("ID:")); if (EditorGUI.EndChangeCheck()) { } GUI.enabled = isEditingEnabled; EditorGUIUtility.labelWidth = 25f; rect = new Rect(position.width / 2 + 20, position.y + 20, width * 0.5f - padding, 18); EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX")); rect.x += width * 0.5f; EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY")); rect.x = position.width / 2 + 20; rect.y += 20; EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX")); //rect.x += width * 0.5f; //EditorGUI.PropertyField(rect, prop_SecondGlyphAdjustment.FindPropertyRelative("m_YAdvance"), new GUIContent("AY")); } // Font Feature Lookup Flags if (isSelectable) { EditorGUIUtility.labelWidth = 55f; rect.x = position.width - 255; rect.y += 23; rect.width = 270; // width - 70 - padding; FontFeatureLookupFlags flags = (FontFeatureLookupFlags)prop_FontFeatureLookupFlags.intValue; EditorGUI.BeginChangeCheck(); flags = (FontFeatureLookupFlags)EditorGUI.EnumFlagsField(rect, new GUIContent("Options:"), flags); if (EditorGUI.EndChangeCheck()) { prop_FontFeatureLookupFlags.intValue = (int)flags; } } } bool ValidateInput(string source) { int length = string.IsNullOrEmpty(source) ? 0 : source.Length; ////Filter out unwanted characters. Event evt = Event.current; char c = evt.character; if (c != '\0') { switch (length) { case 0: break; case 1: if (source != m_PreviousInput) return true; if ((source[0] == '\\' && (c == 'u' || c == 'U')) == false) evt.character = '\0'; break; case 2: case 3: case 4: case 5: if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F')) evt.character = '\0'; break; case 6: case 7: case 8: case 9: if (source[1] == 'u' || (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F')) evt.character = '\0'; // Validate input if (length == 6 && source[1] == 'u' && source != m_PreviousInput) return true; break; case 10: if (source != m_PreviousInput) return true; evt.character = '\0'; break; } } m_PreviousInput = source; return false; } uint GetUnicodeCharacter (string source) { uint unicode; if (source.Length == 1) unicode = source[0]; else if (source.Length == 6) unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", "")); else unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", "")); return unicode; } void DrawGlyph(uint glyphIndex, Rect position, SerializedProperty property) { // Get a reference to the sprite texture TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset; if (fontAsset == null) return; // Check if glyph currently exists in the atlas texture. if (!fontAsset.glyphLookupTable.TryGetValue(glyphIndex, out Glyph glyph)) return; // Get reference to atlas texture. int atlasIndex = fontAsset.m_AtlasTextureIndex; Texture2D atlasTexture = fontAsset.atlasTextures.Length > atlasIndex ? fontAsset.atlasTextures[atlasIndex] : null; if (atlasTexture == null) return; Material mat; if (((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP) { mat = TMP_FontAssetEditor.internalBitmapMaterial; if (mat == null) return; mat.mainTexture = atlasTexture; } else { mat = TMP_FontAssetEditor.internalSDFMaterial; if (mat == null) return; mat.mainTexture = atlasTexture; mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1); } // Draw glyph from atlas texture. Rect glyphDrawPosition = new Rect(position.x, position.y + 2, 64, 60); GlyphRect glyphRect = glyph.glyphRect; float normalizedHeight = fontAsset.faceInfo.ascentLine - fontAsset.faceInfo.descentLine; float scale = glyphDrawPosition.width / normalizedHeight; // Compute the normalized texture coordinates Rect texCoords = new Rect((float)glyphRect.x / atlasTexture.width, (float)glyphRect.y / atlasTexture.height, (float)glyphRect.width / atlasTexture.width, (float)glyphRect.height / atlasTexture.height); if (Event.current.type == EventType.Repaint) { glyphDrawPosition.x += (glyphDrawPosition.width - glyphRect.width * scale) / 2; glyphDrawPosition.y += (glyphDrawPosition.height - glyphRect.height * scale) / 2; glyphDrawPosition.width = glyphRect.width * scale; glyphDrawPosition.height = glyphRect.height * scale; // Could switch to using the default material of the font asset which would require passing scale to the shader. Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: d256fa541faf5d4409992c631adb98a1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_GlyphPropertyDrawer.cs ================================================  using UnityEngine; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(Glyph))] public class TMP_GlyphPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_GlyphIndex = property.FindPropertyRelative("m_Index"); SerializedProperty prop_GlyphMetrics = property.FindPropertyRelative("m_Metrics"); SerializedProperty prop_GlyphRect = property.FindPropertyRelative("m_GlyphRect"); SerializedProperty prop_Scale = property.FindPropertyRelative("m_Scale"); SerializedProperty prop_AtlasIndex = property.FindPropertyRelative("m_AtlasIndex"); GUIStyle style = new GUIStyle(EditorStyles.label); style.richText = true; Rect rect = new Rect(position.x + 70, position.y, position.width, 49); float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_GlyphIndex.intValue)).x; EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 85, 64f, 18f), new GUIContent("ID: " + prop_GlyphIndex.intValue + ""), style); //EditorGUIUtility.labelWidth = 22f; //EditorGUI.DelayedIntField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 89, 58f, 18f), prop_GlyphIndex, new GUIContent("ID:")); // We get Rect since a valid position may not be provided by the caller. EditorGUI.PropertyField(new Rect(rect.x, rect.y, position.width, 49), prop_GlyphRect); rect.y += 45; EditorGUI.PropertyField(rect, prop_GlyphMetrics); EditorGUIUtility.labelWidth = 40f; EditorGUI.PropertyField(new Rect(rect.x, rect.y + 65, 75, 18), prop_Scale, new GUIContent("Scale:")); // new GUIContent("Scale: " + prop_Scale.floatValue + ""), style); EditorGUIUtility.labelWidth = 74f; EditorGUI.PropertyField(new Rect(rect.x + 85, rect.y + 65, 95, 18), prop_AtlasIndex, new GUIContent("Atlas Index:")); // new GUIContent("Atlas Index: " + prop_AtlasIndex.intValue + ""), style); DrawGlyph(position, property); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 130f; } void DrawGlyph(Rect position, SerializedProperty property) { // Get a reference to the sprite texture TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset; if (fontAsset == null) return; // Get reference to atlas texture. int atlasIndex = property.FindPropertyRelative("m_AtlasIndex").intValue; Texture2D atlasTexture = fontAsset.atlasTextures.Length > atlasIndex ? fontAsset.atlasTextures[atlasIndex] : null; if (atlasTexture == null) return; Material mat; if (((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP) { mat = TMP_FontAssetEditor.internalBitmapMaterial; if (mat == null) return; mat.mainTexture = atlasTexture; mat.SetColor("_Color", Color.white); } else { mat = TMP_FontAssetEditor.internalSDFMaterial; if (mat == null) return; mat.mainTexture = atlasTexture; mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1); } // Draw glyph from atlas texture. Rect glyphDrawPosition = new Rect(position.x, position.y + 2, 64, 80); SerializedProperty prop_GlyphRect = property.FindPropertyRelative("m_GlyphRect"); int glyphOriginX = prop_GlyphRect.FindPropertyRelative("m_X").intValue; int glyphOriginY = prop_GlyphRect.FindPropertyRelative("m_Y").intValue; int glyphWidth = prop_GlyphRect.FindPropertyRelative("m_Width").intValue; int glyphHeight = prop_GlyphRect.FindPropertyRelative("m_Height").intValue; float normalizedHeight = fontAsset.faceInfo.ascentLine - fontAsset.faceInfo.descentLine; float scale = glyphDrawPosition.width / normalizedHeight; // Compute the normalized texture coordinates Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height); if (Event.current.type == EventType.Repaint) { glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2; glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2; glyphDrawPosition.width = glyphWidth * scale; glyphDrawPosition.height = glyphHeight * scale; // Could switch to using the default material of the font asset which would require passing scale to the shader. Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_GlyphPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: c4777500b5da6094e956c3d4f04de4db MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_InputFieldEditor.cs ================================================ using UnityEngine; using UnityEngine.UI; using UnityEditor; using UnityEditor.UI; using UnityEditor.AnimatedValues; namespace TMPro.EditorUtilities { [CanEditMultipleObjects] [CustomEditor(typeof(TMP_InputField), true)] public class TMP_InputFieldEditor : SelectableEditor { private struct m_foldout { // Track Inspector foldout panel states, globally. public static bool textInput = true; public static bool fontSettings = true; public static bool extraSettings = true; //public static bool shadowSetting = false; //public static bool materialEditor = true; } SerializedProperty m_TextViewport; SerializedProperty m_TextComponent; SerializedProperty m_Text; SerializedProperty m_ContentType; SerializedProperty m_LineType; SerializedProperty m_LineLimit; SerializedProperty m_InputType; SerializedProperty m_CharacterValidation; SerializedProperty m_InputValidator; SerializedProperty m_RegexValue; SerializedProperty m_KeyboardType; SerializedProperty m_CharacterLimit; SerializedProperty m_CaretBlinkRate; SerializedProperty m_CaretWidth; SerializedProperty m_CaretColor; SerializedProperty m_CustomCaretColor; SerializedProperty m_SelectionColor; SerializedProperty m_HideMobileKeyboard; SerializedProperty m_HideMobileInput; SerializedProperty m_Placeholder; SerializedProperty m_VerticalScrollbar; SerializedProperty m_ScrollbarScrollSensitivity; SerializedProperty m_OnValueChanged; SerializedProperty m_OnEndEdit; SerializedProperty m_OnSelect; SerializedProperty m_OnDeselect; SerializedProperty m_ReadOnly; SerializedProperty m_RichText; SerializedProperty m_RichTextEditingAllowed; SerializedProperty m_ResetOnDeActivation; SerializedProperty m_RestoreOriginalTextOnEscape; SerializedProperty m_OnFocusSelectAll; SerializedProperty m_GlobalPointSize; SerializedProperty m_GlobalFontAsset; AnimBool m_CustomColor; //TMP_InputValidator m_ValidationScript; protected override void OnEnable() { base.OnEnable(); m_TextViewport = serializedObject.FindProperty("m_TextViewport"); m_TextComponent = serializedObject.FindProperty("m_TextComponent"); m_Text = serializedObject.FindProperty("m_Text"); m_ContentType = serializedObject.FindProperty("m_ContentType"); m_LineType = serializedObject.FindProperty("m_LineType"); m_LineLimit = serializedObject.FindProperty("m_LineLimit"); m_InputType = serializedObject.FindProperty("m_InputType"); m_CharacterValidation = serializedObject.FindProperty("m_CharacterValidation"); m_InputValidator = serializedObject.FindProperty("m_InputValidator"); m_RegexValue = serializedObject.FindProperty("m_RegexValue"); m_KeyboardType = serializedObject.FindProperty("m_KeyboardType"); m_CharacterLimit = serializedObject.FindProperty("m_CharacterLimit"); m_CaretBlinkRate = serializedObject.FindProperty("m_CaretBlinkRate"); m_CaretWidth = serializedObject.FindProperty("m_CaretWidth"); m_CaretColor = serializedObject.FindProperty("m_CaretColor"); m_CustomCaretColor = serializedObject.FindProperty("m_CustomCaretColor"); m_SelectionColor = serializedObject.FindProperty("m_SelectionColor"); m_HideMobileKeyboard = serializedObject.FindProperty("m_HideSoftKeyboard"); m_HideMobileInput = serializedObject.FindProperty("m_HideMobileInput"); m_Placeholder = serializedObject.FindProperty("m_Placeholder"); m_VerticalScrollbar = serializedObject.FindProperty("m_VerticalScrollbar"); m_ScrollbarScrollSensitivity = serializedObject.FindProperty("m_ScrollSensitivity"); m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged"); m_OnEndEdit = serializedObject.FindProperty("m_OnEndEdit"); m_OnSelect = serializedObject.FindProperty("m_OnSelect"); m_OnDeselect = serializedObject.FindProperty("m_OnDeselect"); m_ReadOnly = serializedObject.FindProperty("m_ReadOnly"); m_RichText = serializedObject.FindProperty("m_RichText"); m_RichTextEditingAllowed = serializedObject.FindProperty("m_isRichTextEditingAllowed"); m_ResetOnDeActivation = serializedObject.FindProperty("m_ResetOnDeActivation"); m_RestoreOriginalTextOnEscape = serializedObject.FindProperty("m_RestoreOriginalTextOnEscape"); m_OnFocusSelectAll = serializedObject.FindProperty("m_OnFocusSelectAll"); m_GlobalPointSize = serializedObject.FindProperty("m_GlobalPointSize"); m_GlobalFontAsset = serializedObject.FindProperty("m_GlobalFontAsset"); m_CustomColor = new AnimBool(m_CustomCaretColor.boolValue); m_CustomColor.valueChanged.AddListener(Repaint); } protected override void OnDisable() { base.OnDisable(); m_CustomColor.valueChanged.RemoveListener(Repaint); } public override void OnInspectorGUI() { serializedObject.Update(); base.OnInspectorGUI(); EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_TextViewport); EditorGUILayout.PropertyField(m_TextComponent); TextMeshProUGUI text = null; if (m_TextComponent != null && m_TextComponent.objectReferenceValue != null) { text = m_TextComponent.objectReferenceValue as TextMeshProUGUI; //if (text.supportRichText) //{ // EditorGUILayout.HelpBox("Using Rich Text with input is unsupported.", MessageType.Warning); //} } EditorGUI.BeginDisabledGroup(m_TextComponent == null || m_TextComponent.objectReferenceValue == null); // TEXT INPUT BOX EditorGUILayout.PropertyField(m_Text); // INPUT FIELD SETTINGS #region INPUT FIELD SETTINGS m_foldout.fontSettings = EditorGUILayout.Foldout(m_foldout.fontSettings, "Input Field Settings", true, TMP_UIStyleManager.boldFoldout); if (m_foldout.fontSettings) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_GlobalFontAsset, new GUIContent("Font Asset", "Set the Font Asset for both Placeholder and Input Field text object.")); if (EditorGUI.EndChangeCheck()) { TMP_InputField inputField = target as TMP_InputField; inputField.SetGlobalFontAsset(m_GlobalFontAsset.objectReferenceValue as TMP_FontAsset); } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_GlobalPointSize, new GUIContent("Point Size", "Set the point size of both Placeholder and Input Field text object.")); if (EditorGUI.EndChangeCheck()) { TMP_InputField inputField = target as TMP_InputField; inputField.SetGlobalPointSize(m_GlobalPointSize.floatValue); } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_CharacterLimit); EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_ContentType); if (!m_ContentType.hasMultipleDifferentValues) { EditorGUI.indentLevel++; if (m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Standard || m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Autocorrected || m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Custom) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_LineType); if (EditorGUI.EndChangeCheck()) { if (text != null) { if (m_LineType.enumValueIndex == (int)TMP_InputField.LineType.SingleLine) text.enableWordWrapping = false; else { text.enableWordWrapping = true; } } } if (m_LineType.enumValueIndex != (int)TMP_InputField.LineType.SingleLine) { EditorGUILayout.PropertyField(m_LineLimit); } } if (m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Custom) { EditorGUILayout.PropertyField(m_InputType); EditorGUILayout.PropertyField(m_KeyboardType); EditorGUILayout.PropertyField(m_CharacterValidation); if (m_CharacterValidation.enumValueIndex == (int)TMP_InputField.CharacterValidation.Regex) { EditorGUILayout.PropertyField(m_RegexValue); } else if (m_CharacterValidation.enumValueIndex == (int)TMP_InputField.CharacterValidation.CustomValidator) { EditorGUILayout.PropertyField(m_InputValidator); } } EditorGUI.indentLevel--; } EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_Placeholder); EditorGUILayout.PropertyField(m_VerticalScrollbar); if (m_VerticalScrollbar.objectReferenceValue != null) EditorGUILayout.PropertyField(m_ScrollbarScrollSensitivity); EditorGUILayout.PropertyField(m_CaretBlinkRate); EditorGUILayout.PropertyField(m_CaretWidth); EditorGUILayout.PropertyField(m_CustomCaretColor); m_CustomColor.target = m_CustomCaretColor.boolValue; if (EditorGUILayout.BeginFadeGroup(m_CustomColor.faded)) { EditorGUILayout.PropertyField(m_CaretColor); } EditorGUILayout.EndFadeGroup(); EditorGUILayout.PropertyField(m_SelectionColor); EditorGUI.indentLevel--; } #endregion // CONTROL SETTINGS #region CONTROL SETTINGS m_foldout.extraSettings = EditorGUILayout.Foldout(m_foldout.extraSettings, "Control Settings", true, TMP_UIStyleManager.boldFoldout); if (m_foldout.extraSettings) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(m_OnFocusSelectAll, new GUIContent("OnFocus - Select All", "Should all the text be selected when the Input Field is selected.")); EditorGUILayout.PropertyField(m_ResetOnDeActivation, new GUIContent("Reset On DeActivation", "Should the Text and Caret position be reset when Input Field is DeActivated.")); EditorGUILayout.PropertyField(m_RestoreOriginalTextOnEscape, new GUIContent("Restore On ESC Key", "Should the original text be restored when pressing ESC.")); EditorGUILayout.PropertyField(m_HideMobileKeyboard, new GUIContent("Hide Soft Keyboard", "Controls the visibility of the mobile virtual keyboard.")); EditorGUILayout.PropertyField(m_HideMobileInput, new GUIContent("Hide Mobile Input", "Controls the visibility of the editable text field above the mobile virtual keyboard. Not supported on all mobile platforms.")); EditorGUILayout.PropertyField(m_ReadOnly); EditorGUILayout.PropertyField(m_RichText); EditorGUILayout.PropertyField(m_RichTextEditingAllowed, new GUIContent("Allow Rich Text Editing")); EditorGUI.indentLevel--; } #endregion EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_OnValueChanged); EditorGUILayout.PropertyField(m_OnEndEdit); EditorGUILayout.PropertyField(m_OnSelect); EditorGUILayout.PropertyField(m_OnDeselect); EditorGUI.EndDisabledGroup(); serializedObject.ApplyModifiedProperties(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_InputFieldEditor.cs.meta ================================================ fileFormatVersion: 2 guid: aa160f27c3fe4052a5850e21108811b6 timeCreated: 1457861621 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_MeshRendererEditor.cs ================================================ // When enabled, allows setting the material by dropping a material onto the MeshRenderer inspector component. // The drawback is that the MeshRenderer inspector will not have properties for light probes, so if you need light probe support, do not enable this. //#define ALLOW_MESHRENDERER_MATERIAL_DRAG_N_DROP using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { // Disabled for compatibility reason as lightprobe setup isn't supported due to inability to inherit from MeshRendererEditor class #if ALLOW_MESHRENDERER_MATERIAL_DRAG_N_DROP [CanEditMultipleObjects] [CustomEditor(typeof(MeshRenderer))] public class TMP_MeshRendererEditor : Editor { private SerializedProperty m_Materials; void OnEnable() { m_Materials = serializedObject.FindProperty("m_Materials"); } public override void OnInspectorGUI() { serializedObject.Update(); // Get a reference to the current material. SerializedProperty material_prop = m_Materials.GetArrayElementAtIndex(0); Material currentMaterial = material_prop.objectReferenceValue as Material; EditorGUI.BeginChangeCheck(); base.OnInspectorGUI(); if (EditorGUI.EndChangeCheck()) { material_prop = m_Materials.GetArrayElementAtIndex(0); TMP_FontAsset newFontAsset = null; Material newMaterial = null; if (material_prop != null) newMaterial = material_prop.objectReferenceValue as Material; // Check if the new material is referencing a different font atlas texture. if (newMaterial != null && currentMaterial.GetInstanceID() != newMaterial.GetInstanceID()) { // Search for the Font Asset matching the new font atlas texture. newFontAsset = TMP_EditorUtility.FindMatchingFontAsset(newMaterial); } GameObject[] objects = Selection.gameObjects; for (int i = 0; i < objects.Length; i++) { // Assign new font asset if (newFontAsset != null) { TMP_Text textComponent = objects[i].GetComponent(); if (textComponent != null) { Undo.RecordObject(textComponent, "Font Asset Change"); textComponent.font = newFontAsset; } } TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(objects[i], currentMaterial, newMaterial); } } } } #endif } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_MeshRendererEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 6d437b997e074079b4b2f6e395394f4b timeCreated: 1462864011 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_PackageUtilities.cs ================================================ using UnityEngine; using UnityEditor; using System; using System.IO; using System.Linq; using System.Collections; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using TMPro.EditorUtilities; namespace TMPro { /// /// Data structure containing the target and replacement fileIDs and GUIDs which will require remapping from previous version of TextMesh Pro to the new TextMesh Pro UPM package. /// [System.Serializable] struct AssetConversionRecord { public string referencedResource; public string target; public string replacement; } /// /// Data structure containing a list of target and replacement fileID and GUID requiring remapping from previous versions of TextMesh Pro to the new TextMesh Pro UPM package. /// This data structure is populated with the data contained in the PackageConversionData.json file included in the package. /// [System.Serializable] class AssetConversionData { public List assetRecords; } public class TMP_ProjectConversionUtility : EditorWindow { // Create Sprite Asset Editor Window [MenuItem("Window/TextMeshPro/Project Files GUID Remapping Tool", false, 2100)] static void ShowConverterWindow() { var window = GetWindow(); window.titleContent = new GUIContent("Conversion Tool"); window.Focus(); } private static HashSet m_IgnoreAssetTypes = new HashSet() { typeof(AnimatorOverrideController), typeof(AudioClip), typeof(AvatarMask), typeof(ComputeShader), typeof(Cubemap), typeof(DefaultAsset), typeof(Flare), typeof(Font), typeof(GUISkin), typeof(HumanTemplate), typeof(LightingDataAsset), typeof(Mesh), typeof(MonoScript), typeof(PhysicMaterial), typeof(PhysicsMaterial2D), typeof(RenderTexture), typeof(Shader), typeof(TerrainData), typeof(TextAsset), typeof(Texture2D), typeof(Texture2DArray), typeof(Texture3D), typeof(UnityEditor.Animations.AnimatorController), typeof(UnityEditorInternal.AssemblyDefinitionAsset), typeof(UnityEngine.AI.NavMeshData), typeof(UnityEngine.Tilemaps.Tile), typeof(UnityEngine.U2D.SpriteAtlas), typeof(UnityEngine.Video.VideoClip), }; /// /// /// struct AssetModificationRecord { public string assetFilePath; public string assetDataFile; } struct AssetFileRecord { public string assetFilePath; public string assetMetaFilePath; public AssetFileRecord(string filePath, string metaFilePath) { this.assetFilePath = filePath; this.assetMetaFilePath = metaFilePath; } } private static string m_ProjectPath; private static string m_ProjectFolderToScan; private static bool m_IsAlreadyScanningProject; private static bool m_CancelScanProcess; private static string k_ProjectScanReportDefaultText = "Project Scan Results\n"; private static string k_ProjectScanLabelPrefix = "Scanning: "; private static string m_ProjectScanResults = string.Empty; private static Vector2 m_ProjectScanResultScrollPosition; private static float m_ProgressPercentage = 0; private static int m_ScanningTotalFiles; private static int m_RemainingFilesToScan; private static int m_ScanningCurrentFileIndex; private static string m_ScanningCurrentFileName; private static AssetConversionData m_ConversionData; private static List m_ModifiedAssetList = new List(); void OnEnable() { // Set Editor Window Size SetEditorWindowSize(); m_ProjectScanResults = k_ProjectScanReportDefaultText; } void OnGUI() { GUILayout.BeginVertical(); { // Scan project files and resources GUILayout.BeginVertical(EditorStyles.helpBox); { GUILayout.Label("Scan Project Files", EditorStyles.boldLabel); GUILayout.Label("Press the Scan Project Files button to begin scanning your project for files & resources that were created with a previous version of TextMesh Pro.", TMP_UIStyleManager.label); GUILayout.Space(10f); GUILayout.Label("Project folder to be scanned. Example \"Assets/TextMesh Pro\""); m_ProjectFolderToScan = EditorGUILayout.TextField("Folder Path: Assets/", m_ProjectFolderToScan); GUILayout.Space(5f); GUI.enabled = m_IsAlreadyScanningProject == false ? true : false; if (GUILayout.Button("Scan Project Files")) { m_CancelScanProcess = false; // Make sure Asset Serialization mode is set to ForceText and Version Control mode to Visible Meta Files. if (CheckProjectSerializationAndSourceControlModes() == true) { m_ProjectPath = Path.GetFullPath("Assets/.."); TMP_EditorCoroutine.StartCoroutine(ScanProjectFiles()); } else { EditorUtility.DisplayDialog("Project Settings Change Required", "In menu options \"Edit - Project Settings - Editor\", please change Asset Serialization Mode to ForceText and Source Control Mode to Visible Meta Files.", "OK", string.Empty); } } GUI.enabled = true; // Display progress bar Rect rect = GUILayoutUtility.GetRect(0f, 20f, GUILayout.ExpandWidth(true)); EditorGUI.ProgressBar(rect, m_ProgressPercentage, "Scan Progress (" + m_ScanningCurrentFileIndex + "/" + m_ScanningTotalFiles + ")"); // Display cancel button and name of file currently being scanned. if (m_IsAlreadyScanningProject) { Rect cancelRect = new Rect(rect.width - 20, rect.y + 2, 20, 16); if (GUI.Button(cancelRect, "X")) { m_CancelScanProcess = true; } GUILayout.Label(k_ProjectScanLabelPrefix + m_ScanningCurrentFileName, TMP_UIStyleManager.label); } else GUILayout.Label(string.Empty); GUILayout.Space(5); // Creation Feedback GUILayout.BeginVertical(TMP_UIStyleManager.textAreaBoxWindow, GUILayout.ExpandHeight(true)); { m_ProjectScanResultScrollPosition = EditorGUILayout.BeginScrollView(m_ProjectScanResultScrollPosition, GUILayout.ExpandHeight(true)); EditorGUILayout.LabelField(m_ProjectScanResults, TMP_UIStyleManager.label); EditorGUILayout.EndScrollView(); } GUILayout.EndVertical(); GUILayout.Space(5f); } GUILayout.EndVertical(); // Scan project files and resources GUILayout.BeginVertical(EditorStyles.helpBox); { GUILayout.Label("Save Modified Project Files", EditorStyles.boldLabel); GUILayout.Label("Pressing the Save Modified Project Files button will update the files in the Project Scan Results listed above. Please make sure that you have created a backup of your project first as these file modifications are permanent and cannot be undone.", TMP_UIStyleManager.label); GUILayout.Space(5f); GUI.enabled = m_IsAlreadyScanningProject == false && m_ModifiedAssetList.Count > 0 ? true : false; if (GUILayout.Button("Save Modified Project Files")) { UpdateProjectFiles(); } GUILayout.Space(10f); } GUILayout.EndVertical(); } GUILayout.EndVertical(); GUILayout.Space(5f); } void OnInspectorUpdate() { Repaint(); } /// /// Limits the minimum size of the editor window. /// void SetEditorWindowSize() { EditorWindow editorWindow = this; Vector2 currentWindowSize = editorWindow.minSize; editorWindow.minSize = new Vector2(Mathf.Max(640, currentWindowSize.x), Mathf.Max(420, currentWindowSize.y)); } /// /// /// /// /// private static bool ShouldIgnoreFile(string filePath) { string fileExtension = Path.GetExtension(filePath); Type fileType = AssetDatabase.GetMainAssetTypeAtPath(filePath); if (m_IgnoreAssetTypes.Contains(fileType)) return true; // Exclude FBX if (fileType == typeof(GameObject) && fileExtension.ToLower() == ".fbx") { return true; } return false; } private IEnumerator ScanProjectFiles() { m_IsAlreadyScanningProject = true; string packageFullPath = EditorUtilities.TMP_EditorUtility.packageFullPath; // List containing assets that have been modified. m_ProjectScanResults = k_ProjectScanReportDefaultText; m_ModifiedAssetList.Clear(); m_ProgressPercentage = 0; // Read Conversion Data from Json file. if (m_ConversionData == null) m_ConversionData = JsonUtility.FromJson(File.ReadAllText(packageFullPath + "/PackageConversionData.json")); // Get list of GUIDs for assets that might contain references to previous GUIDs that require updating. string searchFolder = string.IsNullOrEmpty(m_ProjectFolderToScan) ? "Assets" : ("Assets/" + m_ProjectFolderToScan); string[] guids = AssetDatabase.FindAssets("t:Object", new string[] { searchFolder }).Distinct().ToArray(); k_ProjectScanLabelPrefix = "Phase 1 - Filtering: "; m_ScanningTotalFiles = guids.Length; m_ScanningCurrentFileIndex = 0; List projectFilesToScan = new List(); foreach (var guid in guids) { if (m_CancelScanProcess) break; string assetFilePath = AssetDatabase.GUIDToAssetPath(guid); m_ScanningCurrentFileIndex += 1; m_ScanningCurrentFileName = assetFilePath; m_ProgressPercentage = (float)m_ScanningCurrentFileIndex / m_ScanningTotalFiles; // Filter out file types we have no interest in searching if (ShouldIgnoreFile(assetFilePath)) continue; string assetMetaFilePath = AssetDatabase.GetTextMetaFilePathFromAssetPath(assetFilePath); projectFilesToScan.Add(new AssetFileRecord(assetFilePath, assetMetaFilePath)); yield return null; } m_RemainingFilesToScan = m_ScanningTotalFiles = projectFilesToScan.Count; k_ProjectScanLabelPrefix = "Phase 2 - Scanning: "; for (int i = 0; i < m_ScanningTotalFiles; i++) { if (m_CancelScanProcess) break; AssetFileRecord fileRecord = projectFilesToScan[i]; Task.Run(() => { ScanProjectFileAsync(fileRecord); m_ScanningCurrentFileName = fileRecord.assetFilePath; int completedScans = m_ScanningTotalFiles - Interlocked.Decrement(ref m_RemainingFilesToScan); m_ScanningCurrentFileIndex = completedScans; m_ProgressPercentage = (float)completedScans / m_ScanningTotalFiles; }); if (i % 64 == 0) yield return new WaitForSeconds(2.0f); } while (m_RemainingFilesToScan > 0 && !m_CancelScanProcess) yield return null; m_IsAlreadyScanningProject = false; m_ScanningCurrentFileName = string.Empty; } static void ScanProjectFileAsync(AssetFileRecord fileRecord) { if (m_CancelScanProcess) return; // Read the asset data file string assetDataFile = string.Empty; bool hasFileChanged = false; try { assetDataFile = File.ReadAllText(m_ProjectPath + "/" + fileRecord.assetFilePath); } catch { // Continue to the next asset if we can't read the current one. return; } // Read the asset meta data file string assetMetaFile = File.ReadAllText(m_ProjectPath + "/" + fileRecord.assetMetaFilePath); bool hasMetaFileChanges = false; foreach (AssetConversionRecord record in m_ConversionData.assetRecords) { if (assetDataFile.Contains(record.target)) { hasFileChanged = true; assetDataFile = assetDataFile.Replace(record.target, record.replacement); } //// Check meta file if (assetMetaFile.Contains(record.target)) { hasMetaFileChanges = true; assetMetaFile = assetMetaFile.Replace(record.target, record.replacement); } } if (hasFileChanged) { AssetModificationRecord modifiedAsset; modifiedAsset.assetFilePath = fileRecord.assetFilePath; modifiedAsset.assetDataFile = assetDataFile; m_ModifiedAssetList.Add(modifiedAsset); m_ProjectScanResults += fileRecord.assetFilePath + "\n"; } if (hasMetaFileChanges) { AssetModificationRecord modifiedAsset; modifiedAsset.assetFilePath = fileRecord.assetMetaFilePath; modifiedAsset.assetDataFile = assetMetaFile; m_ModifiedAssetList.Add(modifiedAsset); m_ProjectScanResults += fileRecord.assetMetaFilePath + "\n"; } } /// /// /// private static void ResetScanProcess() { m_IsAlreadyScanningProject = false; m_ScanningCurrentFileName = string.Empty; m_ProgressPercentage = 0; m_ScanningCurrentFileIndex = 0; m_ScanningTotalFiles = 0; } /// /// /// private static void UpdateProjectFiles() { // Make sure Asset Serialization mode is set to ForceText with Visible Meta Files. CheckProjectSerializationAndSourceControlModes(); string projectPath = Path.GetFullPath("Assets/.."); // Display dialogue to show user a list of project files that will be modified upon their consent. if (EditorUtility.DisplayDialog("Save Modified Asset(s)?", "Are you sure you want to save all modified assets?", "YES", "NO")) { for (int i = 0; i < m_ModifiedAssetList.Count; i++) { // Make sure all file streams that might have been opened by Unity are closed. //AssetDatabase.ReleaseCachedFileHandles(); //Debug.Log("Writing asset file [" + m_ModifiedAssetList[i].assetFilePath + "]."); File.WriteAllText(projectPath + "/" + m_ModifiedAssetList[i].assetFilePath, m_ModifiedAssetList[i].assetDataFile); } } AssetDatabase.Refresh(); m_ProgressPercentage = 0; m_ProjectScanResults = k_ProjectScanReportDefaultText; } /// /// Check project Asset Serialization and Source Control modes /// private static bool CheckProjectSerializationAndSourceControlModes() { // Check Project Asset Serialization and Visible Meta Files mode. if (EditorSettings.serializationMode != SerializationMode.ForceText || EditorSettings.externalVersionControl != "Visible Meta Files") { return false; } return true; } } public class TMP_PackageUtilities : Editor { enum SaveAssetDialogueOptions { Unset = 0, Save = 1, SaveAll = 2, DoNotSave = 3 }; private static SerializationMode m_ProjectAssetSerializationMode; private static string m_ProjectExternalVersionControl; struct AssetRemappingRecord { public string oldGuid; public string newGuid; public string assetPath; } struct AssetModificationRecord { public string assetFilePath; public string assetDataFile; } // Create Sprite Asset Editor Window //[MenuItem("Window/TextMeshPro/Generate New Package GUIDs", false, 1500)] public static void GenerateNewPackageGUIDs_Menu() { GenerateNewPackageGUIDs(); } /// /// /// [MenuItem("Window/TextMeshPro/Import TMP Essential Resources", false, 2050)] public static void ImportProjectResourcesMenu() { ImportProjectResources(); } /// /// /// [MenuItem("Window/TextMeshPro/Import TMP Examples and Extras", false, 2051)] public static void ImportExamplesContentMenu() { ImportExtraContent(); } // Create Sprite Asset Editor Window //[MenuItem("Window/TextMeshPro/Convert TMP Project Files to UPM", false, 1510)] public static void ConvertProjectGUIDsMenu() { ConvertProjectGUIDsToUPM(); //GetVersionInfo(); } // Create Sprite Asset Editor Window //[MenuItem("Window/TextMeshPro/Convert GUID (Source to DLL)", false, 2010)] public static void ConvertGUIDFromSourceToDLLMenu() { //ConvertGUIDFromSourceToDLL(); //GetVersionInfo(); } // Create Sprite Asset Editor Window //[MenuItem("Window/TextMeshPro/Convert GUID (DLL to Source)", false, 2020)] public static void ConvertGUIDFromDllToSourceMenu() { //ConvertGUIDFromDLLToSource(); //GetVersionInfo(); } // Create Sprite Asset Editor Window //[MenuItem("Window/TextMeshPro/Extract Package GUIDs", false, 1530)] public static void ExtractPackageGUIDMenu() { ExtractPackageGUIDs(); } private static void GetVersionInfo() { string version = TMP_Settings.version; Debug.Log("The version of this TextMesh Pro UPM package is (" + version + ")."); } /// /// /// private static void ImportExtraContent() { string packageFullPath = EditorUtilities.TMP_EditorUtility.packageFullPath; AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Examples & Extras.unitypackage", true); } /// /// /// private static void ImportProjectResources() { string packageFullPath = EditorUtilities.TMP_EditorUtility.packageFullPath; AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Essential Resources.unitypackage", true); } /// /// /// private static void GenerateNewPackageGUIDs() { // Make sure Asset Serialization mode is set to ForceText with Visible Meta Files. SetProjectSerializationAndSourceControlModes(); string projectPath = Path.GetFullPath("Assets/.."); // Clear existing dictionary of AssetRecords List assetRecords = new List(); // Get full list of GUIDs used in the package which including folders. string[] packageGUIDs = AssetDatabase.FindAssets("t:Object", new string[] { "Assets/Packages/com.unity.TextMeshPro" }); for (int i = 0; i < packageGUIDs.Length; i++) { // Could add a progress bar for this process (if needed) string guid = packageGUIDs[i]; string assetFilePath = AssetDatabase.GUIDToAssetPath(guid); string assetMetaFilePath = AssetDatabase.GetTextMetaFilePathFromAssetPath(assetFilePath); //System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetFilePath); AssetRemappingRecord assetRecord; assetRecord.oldGuid = guid; assetRecord.assetPath = assetFilePath; string newGUID = GenerateUniqueGUID(); assetRecord.newGuid = newGUID; if (assetRecords.FindIndex(item => item.oldGuid == guid) != -1) continue; assetRecords.Add(assetRecord); // Read the meta file for the given asset. string assetMetaFile = File.ReadAllText(projectPath + "/" + assetMetaFilePath); assetMetaFile = assetMetaFile.Replace("guid: " + guid, "guid: " + newGUID); File.WriteAllText(projectPath + "/" + assetMetaFilePath, assetMetaFile); //Debug.Log("Asset: [" + assetFilePath + "] Type: " + assetType + " Current GUID: [" + guid + "] New GUID: [" + newGUID + "]"); } AssetDatabase.Refresh(); // Get list of GUIDs for assets that might need references to previous GUIDs which need to be updated. packageGUIDs = AssetDatabase.FindAssets("t:Object"); // ("t:Object", new string[] { "Assets/Asset Importer" }); for (int i = 0; i < packageGUIDs.Length; i++) { // Could add a progress bar for this process string guid = packageGUIDs[i]; string assetFilePath = AssetDatabase.GUIDToAssetPath(guid); System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetFilePath); // Filter out file types we are not interested in if (assetType == typeof(DefaultAsset) || assetType == typeof(MonoScript) || assetType == typeof(Texture2D) || assetType == typeof(TextAsset) || assetType == typeof(Shader)) continue; // Read the asset data file string assetDataFile = File.ReadAllText(projectPath + "/" + assetFilePath); //Debug.Log("Searching Asset: [" + assetFilePath + "] of type: " + assetType); bool hasFileChanged = false; foreach (AssetRemappingRecord record in assetRecords) { if (assetDataFile.Contains(record.oldGuid)) { hasFileChanged = true; assetDataFile = assetDataFile.Replace(record.oldGuid, record.newGuid); Debug.Log("Replacing old GUID: [" + record.oldGuid + "] by new GUID: [" + record.newGuid + "] in asset file: [" + assetFilePath + "]."); } } if (hasFileChanged) { // Add file to list of changed files File.WriteAllText(projectPath + "/" + assetFilePath, assetDataFile); } } AssetDatabase.Refresh(); // Restore project Asset Serialization and Source Control modes. RestoreProjectSerializationAndSourceControlModes(); } private static void ExtractPackageGUIDs() { // Make sure Asset Serialization mode is set to ForceText with Visible Meta Files. SetProjectSerializationAndSourceControlModes(); string projectPath = Path.GetFullPath("Assets/.."); // Create new instance of AssetConversionData file AssetConversionData data = new AssetConversionData(); data.assetRecords = new List(); // Get full list of GUIDs used in the package which including folders. string[] packageGUIDs = AssetDatabase.FindAssets("t:Object", new string[] { "Assets/Packages/com.unity.TextMeshPro" }); for (int i = 0; i < packageGUIDs.Length; i++) { // Could add a progress bar for this process (if needed) string guid = packageGUIDs[i]; string assetFilePath = AssetDatabase.GUIDToAssetPath(guid); //string assetMetaFilePath = AssetDatabase.GetTextMetaFilePathFromAssetPath(assetFilePath); //ObjectIdentifier[] localIdentifider = BundleBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(guid), BuildTarget.NoTarget); //System.Type[] types = BundleBuildInterface.GetTypeForObjects(localIdentifider); System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetFilePath); // Filter out file types we are not interested in if (assetType == typeof(DefaultAsset)) continue; string newGuid = GenerateUniqueGUID(); AssetConversionRecord record; record.referencedResource = Path.GetFileName(assetFilePath); record.target = "fileID: 2108210716, guid: " + newGuid; record.replacement = "fileID: 11500000, guid: " + guid; //if (m_AssetRecords.FindIndex(item => item.oldGuid == guid) != -1) // continue; data.assetRecords.Add(record); // Read the meta file for the given asset. //string assetMetaFile = File.ReadAllText(projectPath + "/" + assetMetaFilePath); //assetMetaFile = assetMetaFile.Replace("guid: " + guid, "guid: " + newGUID); //File.WriteAllText(projectPath + "/" + assetMetaFilePath, assetMetaFile); Debug.Log("Asset: [" + Path.GetFileName(assetFilePath) + "] Type: " + assetType + " Current GUID: [" + guid + "] New GUID: [" + newGuid + "]"); } // Write new information into JSON file string dataFile = JsonUtility.ToJson(data, true); File.WriteAllText(projectPath + "/Assets/Packages/com.unity.TextMeshPro/PackageConversionData.json", dataFile); // Restore project Asset Serialization and Source Control modes. RestoreProjectSerializationAndSourceControlModes(); } /// /// /// private static void ConvertProjectGUIDsToUPM() { // Make sure Asset Serialization mode is set to ForceText with Visible Meta Files. SetProjectSerializationAndSourceControlModes(); string projectPath = Path.GetFullPath("Assets/.."); string packageFullPath = EditorUtilities.TMP_EditorUtility.packageFullPath; // List containing assets that have been modified. List modifiedAssetList = new List(); // Read Conversion Data from Json file. AssetConversionData conversionData = JsonUtility.FromJson(File.ReadAllText(packageFullPath + "/PackageConversionData.json")); // Get list of GUIDs for assets that might contain references to previous GUIDs that require updating. string[] projectGUIDs = AssetDatabase.FindAssets("t:Object"); for (int i = 0; i < projectGUIDs.Length; i++) { // Could add a progress bar for this process string guid = projectGUIDs[i]; string assetFilePath = AssetDatabase.GUIDToAssetPath(guid); System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetFilePath); // Filter out file types we are not interested in if (assetType == typeof(DefaultAsset) || assetType == typeof(MonoScript) || assetType == typeof(Texture2D) || assetType == typeof(TextAsset) || assetType == typeof(Shader)) continue; // Read the asset data file string assetDataFile = File.ReadAllText(projectPath + "/" + assetFilePath); //Debug.Log("Searching Asset: [" + assetFilePath + "] of type: " + assetType); bool hasFileChanged = false; foreach (AssetConversionRecord record in conversionData.assetRecords) { if (assetDataFile.Contains(record.target)) { hasFileChanged = true; assetDataFile = assetDataFile.Replace(record.target, record.replacement); Debug.Log("Replacing Reference to [" + record.referencedResource + "] using [" + record.target + "] with [" + record.replacement + "] in asset file: [" + assetFilePath + "]."); } } if (hasFileChanged) { Debug.Log("Adding [" + assetFilePath + "] to list of assets to be modified."); AssetModificationRecord modifiedAsset; modifiedAsset.assetFilePath = assetFilePath; modifiedAsset.assetDataFile = assetDataFile; modifiedAssetList.Add(modifiedAsset); } } // Scan project meta files to update GUIDs of assets whose GUID has changed. projectGUIDs = AssetDatabase.FindAssets("t:Object"); for (int i = 0; i < projectGUIDs.Length; i++) { string guid = projectGUIDs[i]; string assetFilePath = AssetDatabase.GUIDToAssetPath(guid); string assetMetaFilePath = AssetDatabase.GetTextMetaFilePathFromAssetPath(assetFilePath); // Read the asset meta data file string assetMetaFile = File.ReadAllText(projectPath + "/" + assetMetaFilePath); bool hasFileChanged = false; foreach (AssetConversionRecord record in conversionData.assetRecords) { if (assetMetaFile.Contains(record.target)) { hasFileChanged = true; assetMetaFile = assetMetaFile.Replace(record.target, record.replacement); Debug.Log("Replacing Reference to [" + record.referencedResource + "] using [" + record.target + "] with [" + record.replacement + "] in asset file: [" + assetMetaFilePath + "]."); } } if (hasFileChanged) { Debug.Log("Adding [" + assetMetaFilePath + "] to list of meta files to be modified."); AssetModificationRecord modifiedAsset; modifiedAsset.assetFilePath = assetMetaFilePath; modifiedAsset.assetDataFile = assetMetaFile; modifiedAssetList.Add(modifiedAsset); } } // Display dialogue to show user a list of project files that will be modified upon their consent. if (EditorUtility.DisplayDialog("Save Modified Asset(s)?", "Are you sure you want to save all modified assets?", "YES", "NO")) { for (int i = 0; i < modifiedAssetList.Count; i++) { // Make sure all file streams that might have been opened by Unity are closed. //AssetDatabase.ReleaseCachedFileHandles(); Debug.Log("Writing asset file [" + modifiedAssetList[i].assetFilePath + "]."); //File.WriteAllText(projectPath + "/" + modifiedAssetList[i].assetFilePath, modifiedAssetList[i].assetDataFile); } } AssetDatabase.Refresh(); // Restore project Asset Serialization and Source Control modes. RestoreProjectSerializationAndSourceControlModes(); } /// /// /// /// private static string GenerateUniqueGUID() { string monoGuid = System.Guid.NewGuid().ToString(); char[] charGuid = new char[32]; int index = 0; for (int i = 0; i < monoGuid.Length; i++) { if (monoGuid[i] != '-') charGuid[index++] = monoGuid[i]; } string guid = new string(charGuid); // Make sure new GUID is not already used by some other asset. if (AssetDatabase.GUIDToAssetPath(guid) != string.Empty) guid = GenerateUniqueGUID(); return guid; } /// /// Change project asset serialization mode to ForceText (if necessary) /// private static void SetProjectSerializationAndSourceControlModes() { // Make sure Asset Serialization mode is set to ForceText with Visible Meta Files. m_ProjectAssetSerializationMode = EditorSettings.serializationMode; if (m_ProjectAssetSerializationMode != SerializationMode.ForceText) UnityEditor.EditorSettings.serializationMode = SerializationMode.ForceText; m_ProjectExternalVersionControl = EditorSettings.externalVersionControl; if (m_ProjectExternalVersionControl != "Visible Meta Files") UnityEditor.EditorSettings.externalVersionControl = "Visible Meta Files"; } /// /// Revert potential change to asset serialization mode (if necessary) /// private static void RestoreProjectSerializationAndSourceControlModes() { // Make sure Asset Serialization mode is set to ForceText with Visible Meta Files. if (m_ProjectAssetSerializationMode != EditorSettings.serializationMode) EditorSettings.serializationMode = m_ProjectAssetSerializationMode; if (m_ProjectExternalVersionControl != EditorSettings.externalVersionControl) EditorSettings.externalVersionControl = m_ProjectExternalVersionControl; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_PackageUtilities.cs.meta ================================================ fileFormatVersion: 2 guid: 68eedd4e5b33b37429c02c4add0036fe MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_PostBuildProcessHandler.cs ================================================ using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; using System.IO; namespace TMPro { public class TMP_PostBuildProcessHandler { [PostProcessBuildAttribute(10000)] public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) { // Check if TMP Essential Resource are present in user project. if (target == BuildTarget.iOS && File.Exists(GetEssentialProjectResourcesPath() + "/Resources/TMP Settings.asset") && TMP_Settings.enableEmojiSupport) { string file = Path.Combine(pathToBuiltProject, "Classes/UI/Keyboard.mm"); string content = File.ReadAllText(file); content = content.Replace("FILTER_EMOJIS_IOS_KEYBOARD 1", "FILTER_EMOJIS_IOS_KEYBOARD 0"); File.WriteAllText(file, content); } } private static string GetEssentialProjectResourcesPath() { // Find the potential location of the TextMesh Pro folder in the user project. string projectPath = Path.GetFullPath("Assets/.."); if (Directory.Exists(projectPath)) { // Search for default location of TMP Essential Resources if (Directory.Exists(projectPath + "/Assets/TextMesh Pro/Resources")) { return "Assets/TextMesh Pro"; } // Search for potential alternative locations in the user project string[] matchingPaths = Directory.GetDirectories(projectPath, "TextMesh Pro", SearchOption.AllDirectories); projectPath = ValidateLocation(matchingPaths, projectPath); if (projectPath != null) return projectPath; } return null; } private static string ValidateLocation(string[] paths, string projectPath) { for (int i = 0; i < paths.Length; i++) { // Check if any of the matching directories contain a GUISkins directory. if (Directory.Exists(paths[i] + "/Resources")) { string folderPath = paths[i].Replace(projectPath, ""); folderPath = folderPath.TrimStart('\\', '/'); return folderPath; } } return null; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_PostBuildProcessHandler.cs.meta ================================================ fileFormatVersion: 2 guid: 6fdea2af3daa40fe8f88e5e9cfc17abb timeCreated: 1479886230 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ProjectTextSettings.cs ================================================ #if !UNITY_2018_3_OR_NEWER using UnityEditor; namespace TMPro { public static class TMP_ProjectTextSettings { // Open Project Text Settings [MenuItem("Edit/Project Settings/TextMeshPro Settings", false, 309)] public static void SelectProjectTextSettings() { TMP_Settings textSettings = TMP_Settings.instance; if (textSettings) { Selection.activeObject = textSettings; // TODO: Do we want to ping the Project Text Settings asset in the Project Inspector EditorUtility.FocusProjectWindow(); EditorGUIUtility.PingObject(textSettings); } else TMPro_EventManager.RESOURCE_LOAD_EVENT.Add(ON_RESOURCES_LOADED); } // Event received when TMP resources have been loaded. static void ON_RESOURCES_LOADED() { TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED); TMP_Settings textSettings = TMP_Settings.instance; Selection.activeObject = textSettings; // TODO: Do we want to ping the Project Text Settings asset in the Project Inspector EditorUtility.FocusProjectWindow(); EditorGUIUtility.PingObject(textSettings); } } } #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ProjectTextSettings.cs.meta ================================================ fileFormatVersion: 2 guid: 0e751e877ed14d71a6b8e63ac54949cf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ResourcesLoader.cs ================================================ using UnityEditor; using UnityEngine; using System.Collections; namespace TMPro.EditorUtilities { //[InitializeOnLoad] class TMP_ResourcesLoader { /// /// Function to pre-load the TMP Resources /// public static void LoadTextMeshProResources() { //TMP_Settings.LoadDefaultSettings(); //TMP_StyleSheet.LoadDefaultStyleSheet(); } static TMP_ResourcesLoader() { //Debug.Log("Loading TMP Resources..."); // Get current targetted platform //string Settings = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone); //TMPro.TMP_Settings.LoadDefaultSettings(); //TMPro.TMP_StyleSheet.LoadDefaultStyleSheet(); } //[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] //static void OnBeforeSceneLoaded() //{ //Debug.Log("Before scene is loaded."); // //TMPro.TMP_Settings.LoadDefaultSettings(); // //TMPro.TMP_StyleSheet.LoadDefaultStyleSheet(); // //ShaderVariantCollection collection = new ShaderVariantCollection(); // //Shader s0 = Shader.Find("TextMeshPro/Mobile/Distance Field"); // //ShaderVariantCollection.ShaderVariant tmp_Variant = new ShaderVariantCollection.ShaderVariant(s0, UnityEngine.Rendering.PassType.Normal, string.Empty); // //collection.Add(tmp_Variant); // //collection.WarmUp(); //} } //static class TMP_ProjectSettings //{ // [InitializeOnLoadMethod] // static void SetProjectDefineSymbols() // { // string currentBuildSettings = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup); // //Check for and inject TMP_INSTALLED // if (!currentBuildSettings.Contains("TMP_PRESENT")) // { // PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, currentBuildSettings + ";TMP_PRESENT"); // } // } //} } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_ResourcesLoader.cs.meta ================================================ fileFormatVersion: 2 guid: 7241c7dc25374fc1a6ab3ef9da79c363 timeCreated: 1465441092 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SDFShaderGUI.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { public class TMP_SDFShaderGUI : TMP_BaseShaderGUI { static ShaderFeature s_OutlineFeature, s_UnderlayFeature, s_BevelFeature, s_GlowFeature, s_MaskFeature; static bool s_Face = true, s_Outline = true, s_Underlay, s_Lighting, s_Glow, s_Bevel, s_Light, s_Bump, s_Env; static string[] s_FaceUvSpeedNames = { "_FaceUVSpeedX", "_FaceUVSpeedY" }, s_OutlineUvSpeedNames = { "_OutlineUVSpeedX", "_OutlineUVSpeedY" }; static TMP_SDFShaderGUI() { s_OutlineFeature = new ShaderFeature() { undoLabel = "Outline", keywords = new[] { "OUTLINE_ON" } }; s_UnderlayFeature = new ShaderFeature() { undoLabel = "Underlay", keywords = new[] { "UNDERLAY_ON", "UNDERLAY_INNER" }, label = new GUIContent("Underlay Type"), keywordLabels = new[] { new GUIContent("None"), new GUIContent("Normal"), new GUIContent("Inner") } }; s_BevelFeature = new ShaderFeature() { undoLabel = "Bevel", keywords = new[] { "BEVEL_ON" } }; s_GlowFeature = new ShaderFeature() { undoLabel = "Glow", keywords = new[] { "GLOW_ON" } }; s_MaskFeature = new ShaderFeature() { undoLabel = "Mask", keywords = new[] { "MASK_HARD", "MASK_SOFT" }, label = new GUIContent("Mask"), keywordLabels = new[] { new GUIContent("Mask Off"), new GUIContent("Mask Hard"), new GUIContent("Mask Soft") } }; } protected override void DoGUI() { s_Face = BeginPanel("Face", s_Face); if (s_Face) { DoFacePanel(); } EndPanel(); s_Outline = m_Material.HasProperty(ShaderUtilities.ID_OutlineTex) ? BeginPanel("Outline", s_Outline) : BeginPanel("Outline", s_OutlineFeature, s_Outline); if (s_Outline) { DoOutlinePanel(); } EndPanel(); if (m_Material.HasProperty(ShaderUtilities.ID_UnderlayColor)) { s_Underlay = BeginPanel("Underlay", s_UnderlayFeature, s_Underlay); if (s_Underlay) { DoUnderlayPanel(); } EndPanel(); } if (m_Material.HasProperty("_SpecularColor")) { s_Lighting = BeginPanel("Lighting", s_BevelFeature, s_Lighting); if (s_Lighting) { s_Bevel = BeginPanel("Bevel", s_Bevel); if (s_Bevel) { DoBevelPanel(); } EndPanel(); s_Light = BeginPanel("Local Lighting", s_Light); if (s_Light) { DoLocalLightingPanel(); } EndPanel(); s_Bump = BeginPanel("Bump Map", s_Bump); if (s_Bump) { DoBumpMapPanel(); } EndPanel(); s_Env = BeginPanel("Environment Map", s_Env); if (s_Env) { DoEnvMapPanel(); } EndPanel(); } EndPanel(); } else if (m_Material.HasProperty("_SpecColor")) { s_Bevel = BeginPanel("Bevel", s_Bevel); if (s_Bevel) { DoBevelPanel(); } EndPanel(); s_Light = BeginPanel("Surface Lighting", s_Light); if (s_Light) { DoSurfaceLightingPanel(); } EndPanel(); s_Bump = BeginPanel("Bump Map", s_Bump); if (s_Bump) { DoBumpMapPanel(); } EndPanel(); s_Env = BeginPanel("Environment Map", s_Env); if (s_Env) { DoEnvMapPanel(); } EndPanel(); } if (m_Material.HasProperty(ShaderUtilities.ID_GlowColor)) { s_Glow = BeginPanel("Glow", s_GlowFeature, s_Glow); if (s_Glow) { DoGlowPanel(); } EndPanel(); } s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended); if (s_DebugExtended) { DoDebugPanel(); } EndPanel(); } void DoFacePanel() { EditorGUI.indentLevel += 1; DoColor("_FaceColor", "Color"); if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex)) { if (m_Material.HasProperty("_FaceUVSpeedX")) { DoTexture2D("_FaceTex", "Texture", true, s_FaceUvSpeedNames); } else { DoTexture2D("_FaceTex", "Texture", true); } } DoSlider("_OutlineSoftness", "Softness"); DoSlider("_FaceDilate", "Dilate"); if (m_Material.HasProperty(ShaderUtilities.ID_Shininess)) { DoSlider("_FaceShininess", "Gloss"); } EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoOutlinePanel() { EditorGUI.indentLevel += 1; DoColor("_OutlineColor", "Color"); if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex)) { if (m_Material.HasProperty("_OutlineUVSpeedX")) { DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames); } else { DoTexture2D("_OutlineTex", "Texture", true); } } DoSlider("_OutlineWidth", "Thickness"); if (m_Material.HasProperty("_OutlineShininess")) { DoSlider("_OutlineShininess", "Gloss"); } EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoUnderlayPanel() { EditorGUI.indentLevel += 1; s_UnderlayFeature.DoPopup(m_Editor, m_Material); DoColor("_UnderlayColor", "Color"); DoSlider("_UnderlayOffsetX", "Offset X"); DoSlider("_UnderlayOffsetY", "Offset Y"); DoSlider("_UnderlayDilate", "Dilate"); DoSlider("_UnderlaySoftness", "Softness"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } static GUIContent[] s_BevelTypeLabels = { new GUIContent("Outer Bevel"), new GUIContent("Inner Bevel") }; void DoBevelPanel() { EditorGUI.indentLevel += 1; DoPopup("_ShaderFlags", "Type", s_BevelTypeLabels); DoSlider("_Bevel", "Amount"); DoSlider("_BevelOffset", "Offset"); DoSlider("_BevelWidth", "Width"); DoSlider("_BevelRoundness", "Roundness"); DoSlider("_BevelClamp", "Clamp"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoLocalLightingPanel() { EditorGUI.indentLevel += 1; DoSlider("_LightAngle", "Light Angle"); DoColor("_SpecularColor", "Specular Color"); DoSlider("_SpecularPower", "Specular Power"); DoSlider("_Reflectivity", "Reflectivity Power"); DoSlider("_Diffuse", "Diffuse Shadow"); DoSlider("_Ambient", "Ambient Shadow"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoSurfaceLightingPanel() { EditorGUI.indentLevel += 1; DoColor("_SpecColor", "Specular Color"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoBumpMapPanel() { EditorGUI.indentLevel += 1; DoTexture2D("_BumpMap", "Texture"); DoSlider("_BumpFace", "Face"); DoSlider("_BumpOutline", "Outline"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoEnvMapPanel() { EditorGUI.indentLevel += 1; DoColor("_ReflectFaceColor", "Face Color"); DoColor("_ReflectOutlineColor", "Outline Color"); DoCubeMap("_Cube", "Texture"); DoVector3("_EnvMatrixRotation", "Rotation"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoGlowPanel() { EditorGUI.indentLevel += 1; DoColor("_GlowColor", "Color"); DoSlider("_GlowOffset", "Offset"); DoSlider("_GlowInner", "Inner"); DoSlider("_GlowOuter", "Outer"); DoSlider("_GlowPower", "Power"); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoDebugPanel() { EditorGUI.indentLevel += 1; DoTexture2D("_MainTex", "Font Atlas"); DoFloat("_GradientScale", "Gradient Scale"); DoFloat("_TextureWidth", "Texture Width"); DoFloat("_TextureHeight", "Texture Height"); EditorGUILayout.Space(); DoFloat("_ScaleX", "Scale X"); DoFloat("_ScaleY", "Scale Y"); if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness)) DoSlider("_Sharpness", "Sharpness"); DoSlider("_PerspectiveFilter", "Perspective Filter"); EditorGUILayout.Space(); DoFloat("_VertexOffsetX", "Offset X"); DoFloat("_VertexOffsetY", "Offset Y"); if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord)) { EditorGUILayout.Space(); s_MaskFeature.ReadState(m_Material); s_MaskFeature.DoPopup(m_Editor, m_Material); if (s_MaskFeature.Active) { DoMaskSubgroup(); } EditorGUILayout.Space(); DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels); } else if (m_Material.HasProperty("_MaskTex")) { DoMaskTexSubgroup(); } else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX)) { EditorGUILayout.Space(); DoFloat("_MaskSoftnessX", "Softness X"); DoFloat("_MaskSoftnessY", "Softness Y"); DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels); } if (m_Material.HasProperty(ShaderUtilities.ID_StencilID)) { EditorGUILayout.Space(); DoFloat("_Stencil", "Stencil ID"); DoFloat("_StencilComp", "Stencil Comp"); } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF")); if (EditorGUI.EndChangeCheck()) { m_Editor.RegisterPropertyChangeUndo("Use Ratios"); if (useRatios) { m_Material.DisableKeyword("RATIOS_OFF"); } else { m_Material.EnableKeyword("RATIOS_OFF"); } } EditorGUI.BeginDisabledGroup(true); DoFloat("_ScaleRatioA", "Scale Ratio A"); DoFloat("_ScaleRatioB", "Scale Ratio B"); DoFloat("_ScaleRatioC", "Scale Ratio C"); EditorGUI.EndDisabledGroup(); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } void DoMaskSubgroup() { DoVector("_MaskCoord", "Mask Bounds", s_XywhVectorLabels); if (Selection.activeGameObject != null) { Renderer renderer = Selection.activeGameObject.GetComponent(); if (renderer != null) { Rect rect = EditorGUILayout.GetControlRect(); rect.x += EditorGUIUtility.labelWidth; rect.width -= EditorGUIUtility.labelWidth; if (GUI.Button(rect, "Match Renderer Bounds")) { FindProperty("_MaskCoord", m_Properties).vectorValue = new Vector4( 0, 0, Mathf.Round(renderer.bounds.extents.x * 1000) / 1000, Mathf.Round(renderer.bounds.extents.y * 1000) / 1000 ); } } } if (s_MaskFeature.State == 1) { DoFloat("_MaskSoftnessX", "Softness X"); DoFloat("_MaskSoftnessY", "Softness Y"); } } void DoMaskTexSubgroup() { EditorGUILayout.Space(); DoTexture2D("_MaskTex", "Mask Texture"); DoToggle("_MaskInverse", "Inverse Mask"); DoColor("_MaskEdgeColor", "Edge Color"); DoSlider("_MaskEdgeSoftness", "Edge Softness"); DoSlider("_MaskWipeControl", "Wipe Position"); DoFloat("_MaskSoftnessX", "Softness X"); DoFloat("_MaskSoftnessY", "Softness Y"); DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SDFShaderGUI.cs.meta ================================================ fileFormatVersion: 2 guid: 8413ca0e506d42a1a4bd9769f204ad16 timeCreated: 1469844718 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SerializedPropertyHolder.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro { class TMP_SerializedPropertyHolder : ScriptableObject { public TMP_FontAsset fontAsset; public uint firstCharacter; public uint secondCharacter; public TMP_GlyphPairAdjustmentRecord glyphPairAdjustmentRecord = new TMP_GlyphPairAdjustmentRecord(new TMP_GlyphAdjustmentRecord(), new TMP_GlyphAdjustmentRecord()); } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SerializedPropertyHolder.cs.meta ================================================ fileFormatVersion: 2 guid: 9c4a050f089abb04ebd4125e419f4548 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SettingsEditor.cs ================================================ using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditorInternal; #pragma warning disable 0414 // Disabled a few warnings for not yet implemented features. namespace TMPro.EditorUtilities { [CustomEditor(typeof(TMP_Settings))] public class TMP_SettingsEditor : Editor { internal class Styles { public static readonly GUIContent defaultFontAssetLabel = new GUIContent("Default Font Asset", "The Font Asset that will be assigned by default to newly created text objects when no Font Asset is specified."); public static readonly GUIContent defaultFontAssetPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Font Assets and Material Presets are located.\nExample \"Fonts & Materials/\""); public static readonly GUIContent fallbackFontAssetsLabel = new GUIContent("Fallback Font Assets", "The Font Assets that will be searched to locate and replace missing characters from a given Font Asset."); public static readonly GUIContent fallbackFontAssetsListLabel = new GUIContent("Fallback Font Assets List", "The Font Assets that will be searched to locate and replace missing characters from a given Font Asset."); public static readonly GUIContent fallbackMaterialSettingsLabel = new GUIContent("Fallback Material Settings"); public static readonly GUIContent matchMaterialPresetLabel = new GUIContent("Match Material Presets"); public static readonly GUIContent containerDefaultSettingsLabel = new GUIContent("Text Container Default Settings"); public static readonly GUIContent textMeshProLabel = new GUIContent("TextMeshPro"); public static readonly GUIContent textMeshProUiLabel = new GUIContent("TextMeshPro UI"); public static readonly GUIContent enableRaycastTarget = new GUIContent("Enable Raycast Target"); public static readonly GUIContent autoSizeContainerLabel = new GUIContent("Auto Size Text Container", "Set the size of the text container to match the text."); public static readonly GUIContent textComponentDefaultSettingsLabel = new GUIContent("Text Component Default Settings"); public static readonly GUIContent defaultFontSize = new GUIContent("Default Font Size"); public static readonly GUIContent autoSizeRatioLabel = new GUIContent("Text Auto Size Ratios"); public static readonly GUIContent minLabel = new GUIContent("Min"); public static readonly GUIContent maxLabel = new GUIContent("Max"); public static readonly GUIContent wordWrappingLabel = new GUIContent("Word Wrapping"); public static readonly GUIContent kerningLabel = new GUIContent("Kerning"); public static readonly GUIContent extraPaddingLabel = new GUIContent("Extra Padding"); public static readonly GUIContent tintAllSpritesLabel = new GUIContent("Tint All Sprites"); public static readonly GUIContent parseEscapeCharactersLabel = new GUIContent("Parse Escape Sequence"); public static readonly GUIContent dynamicFontSystemSettingsLabel = new GUIContent("Dynamic Font System Settings"); public static readonly GUIContent getFontFeaturesAtRuntime = new GUIContent("Get Font Features at Runtime", "Determines if Glyph Adjustment Data will be retrieved from font files at runtime when new characters and glyphs are added to font assets."); public static readonly GUIContent missingGlyphLabel = new GUIContent("Replacement Character", "The character to be displayed when the requested character is not found in any font asset or fallbacks."); public static readonly GUIContent disableWarningsLabel = new GUIContent("Disable warnings", "Disable warning messages in the Console."); public static readonly GUIContent defaultSpriteAssetLabel = new GUIContent("Default Sprite Asset", "The Sprite Asset that will be assigned by default when using the tag when no Sprite Asset is specified."); public static readonly GUIContent enableEmojiSupportLabel = new GUIContent("iOS Emoji Support", "Enables Emoji support for Touch Screen Keyboards on target devices."); public static readonly GUIContent spriteAssetsPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Sprite Assets are located.\nExample \"Sprite Assets/\""); public static readonly GUIContent defaultStyleSheetLabel = new GUIContent("Default Style Sheet", "The Style Sheet that will be used for all text objects in this project."); public static readonly GUIContent colorGradientPresetsLabel = new GUIContent("Color Gradient Presets", "The relative path to a Resources folder where the Color Gradient Presets are located.\nExample \"Color Gradient Presets/\""); public static readonly GUIContent colorGradientsPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Color Gradient Presets are located.\nExample \"Color Gradient Presets/\""); public static readonly GUIContent lineBreakingLabel = new GUIContent("Line Breaking for Asian languages", "The text assets that contain the Leading and Following characters which define the rules for line breaking with Asian languages."); } SerializedProperty m_PropFontAsset; SerializedProperty m_PropDefaultFontAssetPath; SerializedProperty m_PropDefaultFontSize; SerializedProperty m_PropDefaultAutoSizeMinRatio; SerializedProperty m_PropDefaultAutoSizeMaxRatio; SerializedProperty m_PropDefaultTextMeshProTextContainerSize; SerializedProperty m_PropDefaultTextMeshProUITextContainerSize; SerializedProperty m_PropAutoSizeTextContainer; SerializedProperty m_PropEnableRaycastTarget; SerializedProperty m_PropSpriteAsset; SerializedProperty m_PropSpriteAssetPath; SerializedProperty m_PropEnableEmojiSupport; SerializedProperty m_PropStyleSheet; ReorderableList m_List; SerializedProperty m_PropColorGradientPresetsPath; SerializedProperty m_PropMatchMaterialPreset; SerializedProperty m_PropWordWrapping; SerializedProperty m_PropKerning; SerializedProperty m_PropExtraPadding; SerializedProperty m_PropTintAllSprites; SerializedProperty m_PropParseEscapeCharacters; SerializedProperty m_PropMissingGlyphCharacter; SerializedProperty m_GetFontFeaturesAtRuntime; SerializedProperty m_PropWarningsDisabled; SerializedProperty m_PropLeadingCharacters; SerializedProperty m_PropFollowingCharacters; public void OnEnable() { if (target == null) return; m_PropFontAsset = serializedObject.FindProperty("m_defaultFontAsset"); m_PropDefaultFontAssetPath = serializedObject.FindProperty("m_defaultFontAssetPath"); m_PropDefaultFontSize = serializedObject.FindProperty("m_defaultFontSize"); m_PropDefaultAutoSizeMinRatio = serializedObject.FindProperty("m_defaultAutoSizeMinRatio"); m_PropDefaultAutoSizeMaxRatio = serializedObject.FindProperty("m_defaultAutoSizeMaxRatio"); m_PropDefaultTextMeshProTextContainerSize = serializedObject.FindProperty("m_defaultTextMeshProTextContainerSize"); m_PropDefaultTextMeshProUITextContainerSize = serializedObject.FindProperty("m_defaultTextMeshProUITextContainerSize"); m_PropAutoSizeTextContainer = serializedObject.FindProperty("m_autoSizeTextContainer"); m_PropEnableRaycastTarget = serializedObject.FindProperty("m_EnableRaycastTarget"); m_PropSpriteAsset = serializedObject.FindProperty("m_defaultSpriteAsset"); m_PropSpriteAssetPath = serializedObject.FindProperty("m_defaultSpriteAssetPath"); m_PropEnableEmojiSupport = serializedObject.FindProperty("m_enableEmojiSupport"); m_PropStyleSheet = serializedObject.FindProperty("m_defaultStyleSheet"); m_PropColorGradientPresetsPath = serializedObject.FindProperty("m_defaultColorGradientPresetsPath"); m_List = new ReorderableList(serializedObject, serializedObject.FindProperty("m_fallbackFontAssets"), true, true, true, true); m_List.drawElementCallback = (rect, index, isActive, isFocused) => { var element = m_List.serializedProperty.GetArrayElementAtIndex(index); rect.y += 2; EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none); }; m_List.drawHeaderCallback = rect => { EditorGUI.LabelField(rect, Styles.fallbackFontAssetsListLabel); }; m_PropMatchMaterialPreset = serializedObject.FindProperty("m_matchMaterialPreset"); m_PropWordWrapping = serializedObject.FindProperty("m_enableWordWrapping"); m_PropKerning = serializedObject.FindProperty("m_enableKerning"); m_PropExtraPadding = serializedObject.FindProperty("m_enableExtraPadding"); m_PropTintAllSprites = serializedObject.FindProperty("m_enableTintAllSprites"); m_PropParseEscapeCharacters = serializedObject.FindProperty("m_enableParseEscapeCharacters"); m_PropMissingGlyphCharacter = serializedObject.FindProperty("m_missingGlyphCharacter"); m_PropWarningsDisabled = serializedObject.FindProperty("m_warningsDisabled"); m_GetFontFeaturesAtRuntime = serializedObject.FindProperty("m_GetFontFeaturesAtRuntime"); m_PropLeadingCharacters = serializedObject.FindProperty("m_leadingCharacters"); m_PropFollowingCharacters = serializedObject.FindProperty("m_followingCharacters"); } public override void OnInspectorGUI() { serializedObject.Update(); float labelWidth = EditorGUIUtility.labelWidth; float fieldWidth = EditorGUIUtility.fieldWidth; // TextMeshPro Font Info Panel EditorGUI.indentLevel = 0; // FONT ASSET EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.defaultFontAssetLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropFontAsset, Styles.defaultFontAssetLabel); EditorGUILayout.PropertyField(m_PropDefaultFontAssetPath, Styles.defaultFontAssetPathLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // FALLBACK FONT ASSETs EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.fallbackFontAssetsLabel, EditorStyles.boldLabel); m_List.DoLayoutList(); GUILayout.Label(Styles.fallbackMaterialSettingsLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropMatchMaterialPreset, Styles.matchMaterialPresetLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // MISSING GLYPHS EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.dynamicFontSystemSettingsLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_GetFontFeaturesAtRuntime, Styles.getFontFeaturesAtRuntime); EditorGUILayout.PropertyField(m_PropMissingGlyphCharacter, Styles.missingGlyphLabel); EditorGUILayout.PropertyField(m_PropWarningsDisabled, Styles.disableWarningsLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // TEXT OBJECT DEFAULT PROPERTIES EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.containerDefaultSettingsLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropDefaultTextMeshProTextContainerSize, Styles.textMeshProLabel); EditorGUILayout.PropertyField(m_PropDefaultTextMeshProUITextContainerSize, Styles.textMeshProUiLabel); EditorGUILayout.PropertyField(m_PropEnableRaycastTarget, Styles.enableRaycastTarget); EditorGUILayout.PropertyField(m_PropAutoSizeTextContainer, Styles.autoSizeContainerLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); GUILayout.Label(Styles.textComponentDefaultSettingsLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropDefaultFontSize, Styles.defaultFontSize); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel(Styles.autoSizeRatioLabel); EditorGUIUtility.labelWidth = 32; EditorGUIUtility.fieldWidth = 10; EditorGUI.indentLevel = 0; EditorGUILayout.PropertyField(m_PropDefaultAutoSizeMinRatio, Styles.minLabel); EditorGUILayout.PropertyField(m_PropDefaultAutoSizeMaxRatio, Styles.maxLabel); EditorGUI.indentLevel = 1; } EditorGUILayout.EndHorizontal(); EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; EditorGUILayout.PropertyField(m_PropWordWrapping, Styles.wordWrappingLabel); EditorGUILayout.PropertyField(m_PropKerning, Styles.kerningLabel); EditorGUILayout.PropertyField(m_PropExtraPadding, Styles.extraPaddingLabel); EditorGUILayout.PropertyField(m_PropTintAllSprites, Styles.tintAllSpritesLabel); EditorGUILayout.PropertyField(m_PropParseEscapeCharacters, Styles.parseEscapeCharactersLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // SPRITE ASSET EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.defaultSpriteAssetLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropSpriteAsset, Styles.defaultSpriteAssetLabel); EditorGUILayout.PropertyField(m_PropEnableEmojiSupport, Styles.enableEmojiSupportLabel); EditorGUILayout.PropertyField(m_PropSpriteAssetPath, Styles.spriteAssetsPathLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // STYLE SHEET EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.defaultStyleSheetLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_PropStyleSheet, Styles.defaultStyleSheetLabel); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); TMP_StyleSheet.UpdateStyleSheet(); } EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // COLOR GRADIENT PRESETS EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.colorGradientPresetsLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropColorGradientPresetsPath, Styles.colorGradientsPathLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); // LINE BREAKING RULE EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label(Styles.lineBreakingLabel, EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(m_PropLeadingCharacters); EditorGUILayout.PropertyField(m_PropFollowingCharacters); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); if (serializedObject.ApplyModifiedProperties()) { EditorUtility.SetDirty(target); TMPro_EventManager.ON_TMP_SETTINGS_CHANGED(); } } } #if UNITY_2018_3_OR_NEWER class TMP_ResourceImporterProvider : SettingsProvider { TMP_PackageResourceImporter m_ResourceImporter; public TMP_ResourceImporterProvider() : base("Project/TextMesh Pro", SettingsScope.Project) { } public override void OnGUI(string searchContext) { // Lazy creation that supports domain reload if (m_ResourceImporter == null) m_ResourceImporter = new TMP_PackageResourceImporter(); m_ResourceImporter.OnGUI(); } public override void OnDeactivate() { if (m_ResourceImporter != null) m_ResourceImporter.OnDestroy(); } static UnityEngine.Object GetTMPSettings() { return Resources.Load("TMP Settings"); } [SettingsProviderGroup] static SettingsProvider[] CreateTMPSettingsProvider() { var providers = new List { new TMP_ResourceImporterProvider() }; if (GetTMPSettings() != null) { var provider = new AssetSettingsProvider("Project/TextMesh Pro/Settings", GetTMPSettings); provider.PopulateSearchKeywordsFromGUIContentProperties(); providers.Add(provider); } return providers.ToArray(); } } #endif } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SettingsEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 0386b6eb838c47138cd51d1c1b879a35 timeCreated: 1436658550 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteAssetEditor.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEditor; using UnityEditorInternal; using System.Collections.Generic; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TMP_SpriteAsset))] public class TMP_SpriteAssetEditor : Editor { struct UI_PanelState { public static bool spriteAssetInfoPanel = true; public static bool fallbackSpriteAssetPanel = true; public static bool spriteCharacterTablePanel; public static bool spriteGlyphTablePanel; } private static string[] s_UiStateLabel = new string[] { "(Click to collapse) ", "(Click to expand) " }; int m_moveToIndex; int m_selectedElement = -1; int m_CurrentCharacterPage; int m_CurrentGlyphPage; const string k_UndoRedo = "UndoRedoPerformed"; string m_CharacterSearchPattern; List m_CharacterSearchList; bool m_IsCharacterSearchDirty; string m_GlyphSearchPattern; List m_GlyphSearchList; bool m_IsGlyphSearchDirty; SerializedProperty m_spriteAtlas_prop; SerializedProperty m_material_prop; SerializedProperty m_SpriteCharacterTableProperty; SerializedProperty m_SpriteGlyphTableProperty; ReorderableList m_fallbackSpriteAssetList; TMP_SpriteAsset m_SpriteAsset; bool isAssetDirty; float m_xOffset; float m_yOffset; float m_xAdvance; float m_scale; public void OnEnable() { m_SpriteAsset = target as TMP_SpriteAsset; m_spriteAtlas_prop = serializedObject.FindProperty("spriteSheet"); m_material_prop = serializedObject.FindProperty("material"); m_SpriteCharacterTableProperty = serializedObject.FindProperty("m_SpriteCharacterTable"); m_SpriteGlyphTableProperty = serializedObject.FindProperty("m_SpriteGlyphTable"); // Fallback TMP Sprite Asset list m_fallbackSpriteAssetList = new ReorderableList(serializedObject, serializedObject.FindProperty("fallbackSpriteAssets"), true, true, true, true); m_fallbackSpriteAssetList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = m_fallbackSpriteAssetList.serializedProperty.GetArrayElementAtIndex(index); rect.y += 2; EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none); }; m_fallbackSpriteAssetList.drawHeaderCallback = rect => { EditorGUI.LabelField(rect, new GUIContent("Fallback Sprite Asset List", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset.")); }; } public override void OnInspectorGUI() { //Debug.Log("OnInspectorGUI Called."); Event currentEvent = Event.current; string evt_cmd = currentEvent.commandName; // Get Current Event CommandName to check for Undo Events serializedObject.Update(); Rect rect; // TEXTMESHPRO SPRITE INFO PANEL GUILayout.Label("Sprite Info", EditorStyles.boldLabel); EditorGUI.indentLevel = 1; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_spriteAtlas_prop , new GUIContent("Sprite Atlas")); if (EditorGUI.EndChangeCheck()) { // Assign the new sprite atlas texture to the current material Texture2D tex = m_spriteAtlas_prop.objectReferenceValue as Texture2D; if (tex != null) { Material mat = m_material_prop.objectReferenceValue as Material; if (mat != null) mat.mainTexture = tex; } } EditorGUILayout.PropertyField(m_material_prop, new GUIContent("Default Material")); EditorGUILayout.Space(); // FALLBACK SPRITE ASSETS EditorGUI.indentLevel = 0; UI_PanelState.fallbackSpriteAssetPanel = EditorGUILayout.Foldout(UI_PanelState.fallbackSpriteAssetPanel, new GUIContent("Fallback Sprite Assets", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset."), true, TMP_UIStyleManager.boldFoldout); if (UI_PanelState.fallbackSpriteAssetPanel) { m_fallbackSpriteAssetList.DoLayoutList(); } // SPRITE CHARACTER TABLE #region Display Sprite Character Table EditorGUI.indentLevel = 0; rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Sprite Character Table", "List of sprite characters contained in this sprite asset."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.spriteCharacterTablePanel = !UI_PanelState.spriteCharacterTablePanel; GUI.Label(rect, (UI_PanelState.spriteCharacterTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.spriteCharacterTablePanel) { int arraySize = m_SpriteCharacterTableProperty.arraySize; int itemsPerPage = 10; // Display Glyph Management Tools EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.ExpandWidth(true)); { // Search Bar implementation #region DISPLAY SEARCH BAR EditorGUILayout.BeginHorizontal(); { EditorGUIUtility.labelWidth = 110f; EditorGUI.BeginChangeCheck(); string searchPattern = EditorGUILayout.TextField("Sprite Search", m_CharacterSearchPattern, "SearchTextField"); if (EditorGUI.EndChangeCheck() || m_IsCharacterSearchDirty) { if (string.IsNullOrEmpty(searchPattern) == false) { //GUIUtility.keyboardControl = 0; m_CharacterSearchPattern = searchPattern.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim(); // Search Glyph Table for potential matches SearchCharacterTable(m_CharacterSearchPattern, ref m_CharacterSearchList); } else m_CharacterSearchPattern = null; m_IsCharacterSearchDirty = false; } string styleName = string.IsNullOrEmpty(m_CharacterSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton"; if (GUILayout.Button(GUIContent.none, styleName)) { GUIUtility.keyboardControl = 0; m_CharacterSearchPattern = string.Empty; } } EditorGUILayout.EndHorizontal(); #endregion // Display Page Navigation if (!string.IsNullOrEmpty(m_CharacterSearchPattern)) arraySize = m_CharacterSearchList.Count; // Display Page Navigation DisplayPageNavigation(ref m_CurrentCharacterPage, arraySize, itemsPerPage); } EditorGUILayout.EndVertical(); if (arraySize > 0) { // Display each SpriteInfo entry using the SpriteInfo property drawer. for (int i = itemsPerPage * m_CurrentCharacterPage; i < arraySize && i < itemsPerPage * (m_CurrentCharacterPage + 1); i++) { // Define the start of the selection region of the element. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); int elementIndex = i; if (!string.IsNullOrEmpty(m_CharacterSearchPattern)) elementIndex = m_CharacterSearchList[i]; SerializedProperty spriteCharacterProperty = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(elementIndex); EditorGUILayout.BeginVertical(EditorStyles.helpBox); { EditorGUI.BeginDisabledGroup(i != m_selectedElement); { EditorGUILayout.PropertyField(spriteCharacterProperty); } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndVertical(); // Define the end of the selection region of the element. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); // Check for Item selection Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y); if (DoSelectionCheck(selectionArea)) { if (m_selectedElement == i) { m_selectedElement = -1; } else { m_selectedElement = i; GUIUtility.keyboardControl = 0; } } // Draw & Handle Section Area if (m_selectedElement == i) { // Draw selection highlight TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255)); // Draw options to MoveUp, MoveDown, Add or Remove Sprites Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f); controlRect.width /= 8; // Move sprite up. bool guiEnabled = GUI.enabled; if (i == 0) { GUI.enabled = false; } if (GUI.Button(controlRect, "Up")) { SwapCharacterElements(i, i - 1); } GUI.enabled = guiEnabled; // Move sprite down. controlRect.x += controlRect.width; if (i == arraySize - 1) { GUI.enabled = false; } if (GUI.Button(controlRect, "Down")) { SwapCharacterElements(i, i + 1); } GUI.enabled = guiEnabled; // Move sprite to new index controlRect.x += controlRect.width * 2; //if (i == arraySize - 1) { GUI.enabled = false; } m_moveToIndex = EditorGUI.IntField(controlRect, m_moveToIndex); controlRect.x -= controlRect.width; if (GUI.Button(controlRect, "Goto")) { MoveCharacterToIndex(i, m_moveToIndex); } //controlRect.x += controlRect.width; GUI.enabled = guiEnabled; // Add new Sprite controlRect.x += controlRect.width * 4; if (GUI.Button(controlRect, "+")) { m_SpriteCharacterTableProperty.arraySize += 1; int index = m_SpriteCharacterTableProperty.arraySize - 1; SerializedProperty spriteInfo_prop = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(index); // Copy properties of the selected element CopyCharacterSerializedProperty(m_SpriteCharacterTableProperty.GetArrayElementAtIndex(elementIndex), ref spriteInfo_prop); //spriteInfo_prop.FindPropertyRelative("m_Index").intValue = index; serializedObject.ApplyModifiedProperties(); m_IsCharacterSearchDirty = true; } // Delete selected Sprite controlRect.x += controlRect.width; if (m_selectedElement == -1) GUI.enabled = false; if (GUI.Button(controlRect, "-")) { m_SpriteCharacterTableProperty.DeleteArrayElementAtIndex(elementIndex); m_selectedElement = -1; serializedObject.ApplyModifiedProperties(); m_IsCharacterSearchDirty = true; return; } } } } DisplayPageNavigation(ref m_CurrentCharacterPage, arraySize, itemsPerPage); EditorGUIUtility.labelWidth = 40f; EditorGUIUtility.fieldWidth = 20f; GUILayout.Space(5f); // GLOBAL TOOLS #region Global Tools /* GUI.enabled = true; EditorGUILayout.BeginVertical(EditorStyles.helpBox); rect = EditorGUILayout.GetControlRect(false, 40); float width = (rect.width - 75f) / 4; EditorGUI.LabelField(rect, "Global Offsets & Scale", EditorStyles.boldLabel); rect.x += 70; bool old_ChangedState = GUI.changed; GUI.changed = false; m_xOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 0, rect.y + 20, width - 5f, 18), new GUIContent("OX:"), m_xOffset); if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingX", m_xOffset); m_yOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 1, rect.y + 20, width - 5f, 18), new GUIContent("OY:"), m_yOffset); if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingY", m_yOffset); m_xAdvance = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 2, rect.y + 20, width - 5f, 18), new GUIContent("ADV."), m_xAdvance); if (GUI.changed) UpdateGlobalProperty("m_HorizontalAdvance", m_xAdvance); m_scale = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 3, rect.y + 20, width - 5f, 18), new GUIContent("SF."), m_scale); if (GUI.changed) UpdateGlobalProperty("m_Scale", m_scale); EditorGUILayout.EndVertical(); GUI.changed = old_ChangedState; */ #endregion } #endregion // SPRITE GLYPH TABLE #region Display Sprite Glyph Table EditorGUI.indentLevel = 0; rect = EditorGUILayout.GetControlRect(false, 24); if (GUI.Button(rect, new GUIContent("Sprite Glyph Table", "A list of the SpriteGlyphs contained in this sprite asset."), TMP_UIStyleManager.sectionHeader)) UI_PanelState.spriteGlyphTablePanel = !UI_PanelState.spriteGlyphTablePanel; GUI.Label(rect, (UI_PanelState.spriteGlyphTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel); if (UI_PanelState.spriteGlyphTablePanel) { int arraySize = m_SpriteGlyphTableProperty.arraySize; int itemsPerPage = 10; // Display Glyph Management Tools EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.ExpandWidth(true)); { // Search Bar implementation #region DISPLAY SEARCH BAR EditorGUILayout.BeginHorizontal(); { EditorGUIUtility.labelWidth = 110f; EditorGUI.BeginChangeCheck(); string searchPattern = EditorGUILayout.TextField("Sprite Search", m_GlyphSearchPattern, "SearchTextField"); if (EditorGUI.EndChangeCheck() || m_IsGlyphSearchDirty) { if (string.IsNullOrEmpty(searchPattern) == false) { //GUIUtility.keyboardControl = 0; m_GlyphSearchPattern = searchPattern.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim(); // Search Glyph Table for potential matches SearchCharacterTable(m_GlyphSearchPattern, ref m_GlyphSearchList); } else m_GlyphSearchPattern = null; m_IsGlyphSearchDirty = false; } string styleName = string.IsNullOrEmpty(m_GlyphSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton"; if (GUILayout.Button(GUIContent.none, styleName)) { GUIUtility.keyboardControl = 0; m_GlyphSearchPattern = string.Empty; } } EditorGUILayout.EndHorizontal(); #endregion // Display Page Navigation if (!string.IsNullOrEmpty(m_GlyphSearchPattern)) arraySize = m_GlyphSearchList.Count; // Display Page Navigation DisplayPageNavigation(ref m_CurrentGlyphPage, arraySize, itemsPerPage); } EditorGUILayout.EndVertical(); if (arraySize > 0) { // Display each SpriteInfo entry using the SpriteInfo property drawer. for (int i = itemsPerPage * m_CurrentGlyphPage; i < arraySize && i < itemsPerPage * (m_CurrentGlyphPage + 1); i++) { // Define the start of the selection region of the element. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); int elementIndex = i; if (!string.IsNullOrEmpty(m_GlyphSearchPattern)) elementIndex = m_GlyphSearchList[i]; SerializedProperty spriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(elementIndex); EditorGUILayout.BeginVertical(EditorStyles.helpBox); { EditorGUI.BeginDisabledGroup(i != m_selectedElement); { EditorGUILayout.PropertyField(spriteGlyphProperty); } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndVertical(); // Define the end of the selection region of the element. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); // Check for Item selection Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y); if (DoSelectionCheck(selectionArea)) { if (m_selectedElement == i) { m_selectedElement = -1; } else { m_selectedElement = i; GUIUtility.keyboardControl = 0; } } // Draw & Handle Section Area if (m_selectedElement == i) { // Draw selection highlight TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255)); // Draw options to MoveUp, MoveDown, Add or Remove Sprites Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f); controlRect.width /= 8; // Move sprite up. bool guiEnabled = GUI.enabled; if (i == 0) { GUI.enabled = false; } if (GUI.Button(controlRect, "Up")) { SwapGlyphElements(i, i - 1); } GUI.enabled = guiEnabled; // Move sprite down. controlRect.x += controlRect.width; if (i == arraySize - 1) { GUI.enabled = false; } if (GUI.Button(controlRect, "Down")) { SwapGlyphElements(i, i + 1); } GUI.enabled = guiEnabled; // Move sprite to new index controlRect.x += controlRect.width * 2; //if (i == arraySize - 1) { GUI.enabled = false; } m_moveToIndex = EditorGUI.IntField(controlRect, m_moveToIndex); controlRect.x -= controlRect.width; if (GUI.Button(controlRect, "Goto")) { MoveGlyphToIndex(i, m_moveToIndex); } //controlRect.x += controlRect.width; GUI.enabled = guiEnabled; // Add new Sprite controlRect.x += controlRect.width * 4; if (GUI.Button(controlRect, "+")) { m_SpriteGlyphTableProperty.arraySize += 1; int index = m_SpriteGlyphTableProperty.arraySize - 1; SerializedProperty newSpriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(index); // Copy properties of the selected element CopyGlyphSerializedProperty(m_SpriteGlyphTableProperty.GetArrayElementAtIndex(elementIndex), ref newSpriteGlyphProperty); newSpriteGlyphProperty.FindPropertyRelative("m_Index").intValue = index; serializedObject.ApplyModifiedProperties(); m_IsGlyphSearchDirty = true; //m_SpriteAsset.UpdateLookupTables(); } // Delete selected Sprite controlRect.x += controlRect.width; if (m_selectedElement == -1) GUI.enabled = false; if (GUI.Button(controlRect, "-")) { SerializedProperty selectedSpriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(elementIndex); int selectedGlyphIndex = selectedSpriteGlyphProperty.FindPropertyRelative("m_Index").intValue; m_SpriteGlyphTableProperty.DeleteArrayElementAtIndex(elementIndex); // Remove all Sprite Characters referencing this glyph. for (int j = 0; j < m_SpriteCharacterTableProperty.arraySize; j++) { int glyphIndex = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(j).FindPropertyRelative("m_GlyphIndex").intValue; if (glyphIndex == selectedGlyphIndex) { // Remove character m_SpriteCharacterTableProperty.DeleteArrayElementAtIndex(j); } } m_selectedElement = -1; serializedObject.ApplyModifiedProperties(); m_IsGlyphSearchDirty = true; //m_SpriteAsset.UpdateLookupTables(); return; } } } } DisplayPageNavigation(ref m_CurrentGlyphPage, arraySize, itemsPerPage); EditorGUIUtility.labelWidth = 40f; EditorGUIUtility.fieldWidth = 20f; GUILayout.Space(5f); // GLOBAL TOOLS #region Global Tools GUI.enabled = true; EditorGUILayout.BeginVertical(EditorStyles.helpBox); rect = EditorGUILayout.GetControlRect(false, 40); float width = (rect.width - 75f) / 4; EditorGUI.LabelField(rect, "Global Offsets & Scale", EditorStyles.boldLabel); rect.x += 70; bool old_ChangedState = GUI.changed; GUI.changed = false; m_xOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 0, rect.y + 20, width - 5f, 18), new GUIContent("OX:"), m_xOffset); if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingX", m_xOffset); m_yOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 1, rect.y + 20, width - 5f, 18), new GUIContent("OY:"), m_yOffset); if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingY", m_yOffset); m_xAdvance = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 2, rect.y + 20, width - 5f, 18), new GUIContent("ADV."), m_xAdvance); if (GUI.changed) UpdateGlobalProperty("m_HorizontalAdvance", m_xAdvance); m_scale = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 3, rect.y + 20, width - 5f, 18), new GUIContent("SF."), m_scale); if (GUI.changed) UpdateGlobalProperty("m_Scale", m_scale); EditorGUILayout.EndVertical(); #endregion GUI.changed = old_ChangedState; } #endregion if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo || isAssetDirty) { if (m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty || evt_cmd == k_UndoRedo) m_SpriteAsset.UpdateLookupTables(); TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, m_SpriteAsset); isAssetDirty = false; EditorUtility.SetDirty(target); } // Clear selection if mouse event was not consumed. GUI.enabled = true; if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0) m_selectedElement = -1; } /// /// /// /// /// void DisplayPageNavigation(ref int currentPage, int arraySize, int itemsPerPage) { Rect pagePos = EditorGUILayout.GetControlRect(false, 20); pagePos.width /= 3; int shiftMultiplier = Event.current.shift ? 10 : 1; // Page + Shift goes 10 page forward // Previous Page GUI.enabled = currentPage > 0; if (GUI.Button(pagePos, "Previous Page")) { currentPage -= 1 * shiftMultiplier; //m_isNewPage = true; } // Page Counter GUI.enabled = true; pagePos.x += pagePos.width; int totalPages = (int)(arraySize / (float)itemsPerPage + 0.999f); GUI.Label(pagePos, "Page " + (currentPage + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel); // Next Page pagePos.x += pagePos.width; GUI.enabled = itemsPerPage * (currentPage + 1) < arraySize; if (GUI.Button(pagePos, "Next Page")) { currentPage += 1 * shiftMultiplier; //m_isNewPage = true; } // Clamp page range currentPage = Mathf.Clamp(currentPage, 0, arraySize / itemsPerPage); GUI.enabled = true; } /// /// Method to update the properties of all sprites /// /// /// void UpdateGlobalProperty(string property, float value) { int arraySize = m_SpriteGlyphTableProperty.arraySize; for (int i = 0; i < arraySize; i++) { // Get a reference to the sprite glyph. SerializedProperty spriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(i); if (property == "m_Scale") { spriteGlyphProperty.FindPropertyRelative(property).floatValue = value; } else { SerializedProperty glyphMetricsProperty = spriteGlyphProperty.FindPropertyRelative("m_Metrics"); glyphMetricsProperty.FindPropertyRelative(property).floatValue = value; } } GUI.changed = false; } // Check if any of the Style elements were clicked on. private bool DoSelectionCheck(Rect selectionArea) { Event currentEvent = Event.current; switch (currentEvent.type) { case EventType.MouseDown: if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0) { currentEvent.Use(); return true; } break; } return false; } /// /// Swap the sprite item at the currently selected array index to another index. /// /// Selected index. /// New index. void SwapCharacterElements(int selectedIndex, int newIndex) { m_SpriteCharacterTableProperty.MoveArrayElement(selectedIndex, newIndex); m_selectedElement = newIndex; m_IsCharacterSearchDirty = true; m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } /// /// Move Sprite Element at selected index to another index and reorder sprite list. /// /// /// void MoveCharacterToIndex(int selectedIndex, int newIndex) { int arraySize = m_SpriteCharacterTableProperty.arraySize; if (newIndex >= arraySize) newIndex = arraySize - 1; m_SpriteCharacterTableProperty.MoveArrayElement(selectedIndex, newIndex); m_selectedElement = newIndex; m_IsCharacterSearchDirty = true; m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true; // TODO: Need to handle switching pages if the character or glyph is moved to a different page. } /// /// /// /// /// void SwapGlyphElements(int selectedIndex, int newIndex) { m_SpriteGlyphTableProperty.MoveArrayElement(selectedIndex, newIndex); m_selectedElement = newIndex; m_IsGlyphSearchDirty = true; m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } /// /// Move Sprite Element at selected index to another index and reorder sprite list. /// /// /// void MoveGlyphToIndex(int selectedIndex, int newIndex) { int arraySize = m_SpriteGlyphTableProperty.arraySize; if (newIndex >= arraySize) newIndex = arraySize - 1; m_SpriteGlyphTableProperty.MoveArrayElement(selectedIndex, newIndex); m_selectedElement = newIndex; m_IsGlyphSearchDirty = true; m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true; // TODO: Need to handle switching pages if the character or glyph is moved to a different page. } /// /// /// /// /// void CopyCharacterSerializedProperty(SerializedProperty source, ref SerializedProperty target) { target.FindPropertyRelative("m_Name").stringValue = source.FindPropertyRelative("m_Name").stringValue; target.FindPropertyRelative("m_HashCode").intValue = source.FindPropertyRelative("m_HashCode").intValue; target.FindPropertyRelative("m_Unicode").intValue = source.FindPropertyRelative("m_Unicode").intValue; target.FindPropertyRelative("m_GlyphIndex").intValue = source.FindPropertyRelative("m_GlyphIndex").intValue; target.FindPropertyRelative("m_Scale").floatValue = source.FindPropertyRelative("m_Scale").floatValue; } void CopyGlyphSerializedProperty(SerializedProperty srcGlyph, ref SerializedProperty dstGlyph) { // TODO : Should make a generic function which copies each of the properties. // Index dstGlyph.FindPropertyRelative("m_Index").intValue = srcGlyph.FindPropertyRelative("m_Index").intValue; // GlyphMetrics SerializedProperty srcGlyphMetrics = srcGlyph.FindPropertyRelative("m_Metrics"); SerializedProperty dstGlyphMetrics = dstGlyph.FindPropertyRelative("m_Metrics"); dstGlyphMetrics.FindPropertyRelative("m_Width").floatValue = srcGlyphMetrics.FindPropertyRelative("m_Width").floatValue; dstGlyphMetrics.FindPropertyRelative("m_Height").floatValue = srcGlyphMetrics.FindPropertyRelative("m_Height").floatValue; dstGlyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue; dstGlyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue; dstGlyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue; // GlyphRect SerializedProperty srcGlyphRect = srcGlyph.FindPropertyRelative("m_GlyphRect"); SerializedProperty dstGlyphRect = dstGlyph.FindPropertyRelative("m_GlyphRect"); dstGlyphRect.FindPropertyRelative("m_X").intValue = srcGlyphRect.FindPropertyRelative("m_X").intValue; dstGlyphRect.FindPropertyRelative("m_Y").intValue = srcGlyphRect.FindPropertyRelative("m_Y").intValue; dstGlyphRect.FindPropertyRelative("m_Width").intValue = srcGlyphRect.FindPropertyRelative("m_Width").intValue; dstGlyphRect.FindPropertyRelative("m_Height").intValue = srcGlyphRect.FindPropertyRelative("m_Height").intValue; dstGlyph.FindPropertyRelative("m_Scale").floatValue = srcGlyph.FindPropertyRelative("m_Scale").floatValue; dstGlyph.FindPropertyRelative("m_AtlasIndex").intValue = srcGlyph.FindPropertyRelative("m_AtlasIndex").intValue; } /// /// /// /// /// void SearchCharacterTable(string searchPattern, ref List searchResults) { if (searchResults == null) searchResults = new List(); searchResults.Clear(); int arraySize = m_SpriteCharacterTableProperty.arraySize; for (int i = 0; i < arraySize; i++) { SerializedProperty sourceSprite = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(i); // Check for potential match against array index if (i.ToString().Contains(searchPattern)) { searchResults.Add(i); continue; } // Check for potential match against decimal id int id = sourceSprite.FindPropertyRelative("m_GlyphIndex").intValue; if (id.ToString().Contains(searchPattern)) { searchResults.Add(i); continue; } // Check for potential match against name string name = sourceSprite.FindPropertyRelative("m_Name").stringValue.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim(); if (name.Contains(searchPattern)) { searchResults.Add(i); continue; } } } void SearchGlyphTable(string searchPattern, ref List searchResults) { if (searchResults == null) searchResults = new List(); searchResults.Clear(); int arraySize = m_SpriteGlyphTableProperty.arraySize; for (int i = 0; i < arraySize; i++) { SerializedProperty sourceSprite = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(i); // Check for potential match against array index if (i.ToString().Contains(searchPattern)) { searchResults.Add(i); continue; } // Check for potential match against decimal id int id = sourceSprite.FindPropertyRelative("m_GlyphIndex").intValue; if (id.ToString().Contains(searchPattern)) { searchResults.Add(i); continue; } // Check for potential match against name string name = sourceSprite.FindPropertyRelative("m_Name").stringValue.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim(); if (name.Contains(searchPattern)) { searchResults.Add(i); continue; } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteAssetEditor.cs.meta ================================================ fileFormatVersion: 2 guid: b09be1f217d34247af54863a2f5587e1 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteAssetImporter.cs ================================================ using UnityEngine; using UnityEditor; using System.IO; using System.Collections.Generic; using TMPro.EditorUtilities; using TMPro.SpriteAssetUtilities; namespace TMPro { public class TMP_SpriteAssetImporter : EditorWindow { // Create Sprite Asset Editor Window [MenuItem("Window/TextMeshPro/Sprite Importer", false, 2026)] public static void ShowFontAtlasCreatorWindow() { var window = GetWindow(); window.titleContent = new GUIContent("Sprite Importer"); window.Focus(); } Texture2D m_SpriteAtlas; SpriteAssetImportFormats m_SpriteDataFormat = SpriteAssetImportFormats.TexturePacker; TextAsset m_JsonFile; string m_CreationFeedback; TMP_SpriteAsset m_SpriteAsset; List m_SpriteInfoList = new List(); void OnEnable() { // Set Editor Window Size SetEditorWindowSize(); } public void OnGUI() { DrawEditorPanel(); } void DrawEditorPanel() { // label GUILayout.Label("Import Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); // Sprite Texture Selection m_JsonFile = EditorGUILayout.ObjectField("Sprite Data Source", m_JsonFile, typeof(TextAsset), false) as TextAsset; m_SpriteDataFormat = (SpriteAssetImportFormats)EditorGUILayout.EnumPopup("Import Format", m_SpriteDataFormat); // Sprite Texture Selection m_SpriteAtlas = EditorGUILayout.ObjectField("Sprite Texture Atlas", m_SpriteAtlas, typeof(Texture2D), false) as Texture2D; if (EditorGUI.EndChangeCheck()) { m_CreationFeedback = string.Empty; } GUILayout.Space(10); GUI.enabled = m_JsonFile != null && m_SpriteAtlas != null && m_SpriteDataFormat == SpriteAssetImportFormats.TexturePacker; // Create Sprite Asset if (GUILayout.Button("Create Sprite Asset")) { m_CreationFeedback = string.Empty; // Read json data file if (m_JsonFile != null && m_SpriteDataFormat == SpriteAssetImportFormats.TexturePacker) { TexturePacker.SpriteDataObject sprites = JsonUtility.FromJson(m_JsonFile.text); if (sprites != null && sprites.frames != null && sprites.frames.Count > 0) { int spriteCount = sprites.frames.Count; // Update import results m_CreationFeedback = "Import Results\n--------------------\n"; m_CreationFeedback += "" + spriteCount + " Sprites were imported from file."; // Create sprite info list m_SpriteInfoList = CreateSpriteInfoList(sprites); } } } GUI.enabled = true; // Creation Feedback GUILayout.Space(5); GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(60)); { EditorGUILayout.LabelField(m_CreationFeedback, TMP_UIStyleManager.label); } GUILayout.EndVertical(); GUILayout.Space(5); GUI.enabled = m_JsonFile != null && m_SpriteAtlas && m_SpriteInfoList != null && m_SpriteInfoList.Count > 0; // Enable Save Button if font_Atlas is not Null. if (GUILayout.Button("Save Sprite Asset") && m_JsonFile != null) { string filePath = EditorUtility.SaveFilePanel("Save Sprite Asset File", new FileInfo(AssetDatabase.GetAssetPath(m_JsonFile)).DirectoryName, m_JsonFile.name, "asset"); if (filePath.Length == 0) return; SaveSpriteAsset(filePath); } GUI.enabled = true; } /// /// /// List CreateSpriteInfoList(TexturePacker.SpriteDataObject spriteDataObject) { List importedSprites = spriteDataObject.frames; List spriteInfoList = new List(); for (int i = 0; i < importedSprites.Count; i++) { TMP_Sprite sprite = new TMP_Sprite(); sprite.id = i; sprite.name = Path.GetFileNameWithoutExtension(importedSprites[i].filename) ?? ""; sprite.hashCode = TMP_TextUtilities.GetSimpleHashCode(sprite.name); // Attempt to extract Unicode value from name int unicode; int indexOfSeperator = sprite.name.IndexOf('-'); if (indexOfSeperator != -1) unicode = TMP_TextUtilities.StringHexToInt(sprite.name.Substring(indexOfSeperator + 1)); else unicode = TMP_TextUtilities.StringHexToInt(sprite.name); sprite.unicode = unicode; sprite.x = importedSprites[i].frame.x; sprite.y = m_SpriteAtlas.height - (importedSprites[i].frame.y + importedSprites[i].frame.h); sprite.width = importedSprites[i].frame.w; sprite.height = importedSprites[i].frame.h; //Calculate sprite pivot position sprite.pivot = importedSprites[i].pivot; // Properties the can be modified sprite.xAdvance = sprite.width; sprite.scale = 1.0f; sprite.xOffset = 0 - (sprite.width * sprite.pivot.x); sprite.yOffset = sprite.height - (sprite.height * sprite.pivot.y); spriteInfoList.Add(sprite); } return spriteInfoList; } /// /// /// /// void SaveSpriteAsset(string filePath) { filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath. string dataPath = Application.dataPath; if (filePath.IndexOf(dataPath, System.StringComparison.InvariantCultureIgnoreCase) == -1) { Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\""); return; } string relativeAssetPath = filePath.Substring(dataPath.Length - 6); string dirName = Path.GetDirectoryName(relativeAssetPath); string fileName = Path.GetFileNameWithoutExtension(relativeAssetPath); string pathNoExt = dirName + "/" + fileName; // Create new Sprite Asset using this texture m_SpriteAsset = CreateInstance(); AssetDatabase.CreateAsset(m_SpriteAsset, pathNoExt + ".asset"); // Compute the hash code for the sprite asset. m_SpriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(m_SpriteAsset.name); // Assign new Sprite Sheet texture to the Sprite Asset. m_SpriteAsset.spriteSheet = m_SpriteAtlas; m_SpriteAsset.spriteInfoList = m_SpriteInfoList; // Add new default material for sprite asset. AddDefaultMaterial(m_SpriteAsset); } /// /// Create and add new default material to sprite asset. /// /// static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset) { Shader shader = Shader.Find("TextMeshPro/Sprite"); Material material = new Material(shader); material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet); spriteAsset.material = material; material.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(material, spriteAsset); } /// /// Limits the minimum size of the editor window. /// void SetEditorWindowSize() { EditorWindow editorWindow = this; Vector2 currentWindowSize = editorWindow.minSize; editorWindow.minSize = new Vector2(Mathf.Max(230, currentWindowSize.x), Mathf.Max(300, currentWindowSize.y)); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteAssetImporter.cs.meta ================================================ fileFormatVersion: 2 guid: f1ea944dcf8849ebab391e461b99ccb7 timeCreated: 1480023525 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteAssetMenu.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEditor; using System.Linq; using System.IO; using System.Collections; using System.Collections.Generic; namespace TMPro.EditorUtilities { public static class TMP_SpriteAssetMenu { // Add a Context Menu to the Sprite Asset Editor Panel to Create and Add a Default Material. [MenuItem("CONTEXT/TMP_SpriteAsset/Add Default Material", false, 2200)] static void CopyTexture(MenuCommand command) { TMP_SpriteAsset spriteAsset = (TMP_SpriteAsset)command.context; // Make sure the sprite asset already contains a default material if (spriteAsset != null && spriteAsset.material == null) { // Add new default material for sprite asset. AddDefaultMaterial(spriteAsset); } } // Add a Context Menu to the Sprite Asset Editor Panel to update existing sprite assets. [MenuItem("CONTEXT/TMP_SpriteAsset/Update Sprite Asset", false, 2100)] static void UpdateSpriteAsset(MenuCommand command) { TMP_SpriteAsset spriteAsset = (TMP_SpriteAsset)command.context; if (spriteAsset == null) return; // Get a list of all the sprites contained in the texture referenced by the sprite asset. // This only works if the texture is set to sprite mode. string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet); if (string.IsNullOrEmpty(filePath)) return; // Get all the Sprites sorted Left to Right / Top to Bottom Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); List spriteGlyphTable = spriteAsset.spriteGlyphTable; // Finding available glyph indexes to insert new glyphs into. var tempGlyphTable = spriteGlyphTable.OrderBy(glyph => glyph.index).ToList(); List availableGlyphIndexes = new List(); int elementIndex = 0; for (uint i = 0; i < tempGlyphTable[tempGlyphTable.Count - 1].index; i++) { uint currentElementIndex = tempGlyphTable[elementIndex].index; if (i == currentElementIndex) elementIndex += 1; else availableGlyphIndexes.Add(i); } // Iterate over each of the sprites in the texture to try to match them to existing sprites in the sprite asset. for (int i = 0; i < sprites.Length; i++) { int id = sprites[i].GetInstanceID(); int glyphIndex = spriteGlyphTable.FindIndex(item => item.sprite.GetInstanceID() == id); if (glyphIndex == -1) { // Add new Sprite Glyph to the table Sprite sprite = sprites[i]; TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph(); // Get available glyph index if (availableGlyphIndexes.Count > 0) { spriteGlyph.index = availableGlyphIndexes[0]; availableGlyphIndexes.RemoveAt(0); } else spriteGlyph.index = (uint)spriteGlyphTable.Count; spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width); spriteGlyph.glyphRect = new GlyphRect(sprite.rect); spriteGlyph.scale = 1.0f; spriteGlyph.sprite = sprite; spriteGlyphTable.Add(spriteGlyph); TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph); spriteCharacter.name = sprite.name; spriteCharacter.scale = 1.0f; spriteAsset.spriteCharacterTable.Add(spriteCharacter); } else { // Look for changes in existing Sprite Glyph Sprite sprite = sprites[i]; TMP_SpriteGlyph spriteGlyph = spriteGlyphTable[glyphIndex]; // We only update changes to the sprite position / glyph rect. if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) spriteGlyph.glyphRect = new GlyphRect(sprite.rect); } } // Sort glyph table by glyph index spriteAsset.SortGlyphTable(); spriteAsset.UpdateLookupTables(); TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset); } [MenuItem("Assets/Create/TextMeshPro/Sprite Asset", false, 110)] public static void CreateSpriteAsset() { Object target = Selection.activeObject; // Make sure the selection is a texture. if (target == null || target.GetType() != typeof(Texture2D)) { Debug.LogWarning("A texture which contains sprites must first be selected in order to create a TextMesh Pro Sprite Asset."); return; } Texture2D sourceTex = target as Texture2D; // Get the path to the selected texture. string filePathWithName = AssetDatabase.GetAssetPath(sourceTex); string fileNameWithExtension = Path.GetFileName(filePathWithName); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName); string filePath = filePathWithName.Replace(fileNameWithExtension, ""); // Check if Sprite Asset already exists TMP_SpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath(filePath + fileNameWithoutExtension + ".asset", typeof(TMP_SpriteAsset)) as TMP_SpriteAsset; bool isNewAsset = spriteAsset == null ? true : false; if (isNewAsset) { // Create new Sprite Asset using this texture spriteAsset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(spriteAsset, filePath + fileNameWithoutExtension + ".asset"); spriteAsset.version = "1.1.0"; // Compute the hash code for the sprite asset. spriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteAsset.name); // Assign new Sprite Sheet texture to the Sprite Asset. spriteAsset.spriteSheet = sourceTex; List spriteGlyphTable = new List(); List spriteCharacterTable = new List(); PopulateSpriteTables(sourceTex, ref spriteCharacterTable, ref spriteGlyphTable); spriteAsset.spriteCharacterTable = spriteCharacterTable; spriteAsset.spriteGlyphTable = spriteGlyphTable; // Add new default material for sprite asset. AddDefaultMaterial(spriteAsset); } //else //{ // spriteAsset.spriteInfoList = UpdateSpriteInfo(spriteAsset); // // Make sure the sprite asset already contains a default material // if (spriteAsset.material == null) // { // // Add new default material for sprite asset. // AddDefaultMaterial(spriteAsset); // } //} // Update Lookup tables. spriteAsset.UpdateLookupTables(); // Get the Sprites contained in the Sprite Sheet EditorUtility.SetDirty(spriteAsset); //spriteAsset.sprites = sprites; // Set source texture back to Not Readable. //texImporter.isReadable = false; AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(spriteAsset)); // Re-import font asset to get the new updated version. //AssetDatabase.Refresh(); } private static void PopulateSpriteTables(Texture source, ref List spriteCharacterTable, ref List spriteGlyphTable) { //Debug.Log("Creating new Sprite Asset."); string filePath = AssetDatabase.GetAssetPath(source); // Get all the Sprites sorted by Index Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); for (int i = 0; i < sprites.Length; i++) { Sprite sprite = sprites[i]; TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph(); spriteGlyph.index = (uint)i; spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width); spriteGlyph.glyphRect = new GlyphRect(sprite.rect); spriteGlyph.scale = 1.0f; spriteGlyph.sprite = sprite; spriteGlyphTable.Add(spriteGlyph); TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph); spriteCharacter.name = sprite.name; spriteCharacter.scale = 1.0f; spriteCharacterTable.Add(spriteCharacter); } } /// /// Create and add new default material to sprite asset. /// /// private static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset) { Shader shader = Shader.Find("TextMeshPro/Sprite"); Material material = new Material(shader); material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet); spriteAsset.material = material; material.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(material, spriteAsset); } // Update existing SpriteInfo private static List UpdateSpriteInfo(TMP_SpriteAsset spriteAsset) { //Debug.Log("Updating Sprite Asset."); string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet); // Get all the Sprites sorted Left to Right / Top to Bottom Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); for (int i = 0; i < sprites.Length; i++) { Sprite sprite = sprites[i]; // Check if the sprite is already contained in the SpriteInfoList int index = -1; if (spriteAsset.spriteInfoList.Count > i && spriteAsset.spriteInfoList[i].sprite != null) index = spriteAsset.spriteInfoList.FindIndex(item => item.sprite.GetInstanceID() == sprite.GetInstanceID()); // Use existing SpriteInfo if it already exists TMP_Sprite spriteInfo = index == -1 ? new TMP_Sprite() : spriteAsset.spriteInfoList[index]; Rect spriteRect = sprite.rect; spriteInfo.x = spriteRect.x; spriteInfo.y = spriteRect.y; spriteInfo.width = spriteRect.width; spriteInfo.height = spriteRect.height; // Get Sprite Pivot Vector2 pivot = new Vector2(0 - (sprite.bounds.min.x) / (sprite.bounds.extents.x * 2), 0 - (sprite.bounds.min.y) / (sprite.bounds.extents.y * 2)); // The position of the pivot influences the Offset position. spriteInfo.pivot = new Vector2(0 - pivot.x * spriteRect.width, spriteRect.height - pivot.y * spriteRect.height); if (index == -1) { // Find the next available index for this Sprite int[] ids = spriteAsset.spriteInfoList.Select(item => item.id).ToArray(); int id = 0; for (int j = 0; j < ids.Length; j++ ) { if (ids[0] != 0) break; if (j > 0 && (ids[j] - ids[j - 1]) > 1) { id = ids[j - 1] + 1; break; } id = j + 1; } spriteInfo.sprite = sprite; spriteInfo.name = sprite.name; spriteInfo.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteInfo.name); spriteInfo.id = id; spriteInfo.xAdvance = spriteRect.width; spriteInfo.scale = 1.0f; spriteInfo.xOffset = spriteInfo.pivot.x; spriteInfo.yOffset = spriteInfo.pivot.y; spriteAsset.spriteInfoList.Add(spriteInfo); // Sort the Sprites by ID spriteAsset.spriteInfoList = spriteAsset.spriteInfoList.OrderBy(s => s.id).ToList(); } else { spriteAsset.spriteInfoList[index] = spriteInfo; } } return spriteAsset.spriteInfoList; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteAssetMenu.cs.meta ================================================ fileFormatVersion: 2 guid: 1048a87135154606808bf2030da32d18 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteCharacterPropertyDrawer.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_SpriteCharacter))] public class TMP_SpriteCharacterPropertyDrawer : PropertyDrawer { int m_GlyphSelectedForEditing = -1; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_SpriteName = property.FindPropertyRelative("m_Name"); SerializedProperty prop_SpriteNameHashCode = property.FindPropertyRelative("m_HashCode"); SerializedProperty prop_SpriteUnicode = property.FindPropertyRelative("m_Unicode"); SerializedProperty prop_SpriteGlyphIndex = property.FindPropertyRelative("m_GlyphIndex"); SerializedProperty prop_SpriteScale = property.FindPropertyRelative("m_Scale"); GUIStyle style = new GUIStyle(EditorStyles.label); style.richText = true; EditorGUIUtility.labelWidth = 40f; EditorGUIUtility.fieldWidth = 50; Rect rect = new Rect(position.x + 60, position.y, position.width, 49); // Display non-editable fields if (GUI.enabled == false) { // Sprite Character Index int.TryParse(property.displayName.Split(' ')[1], out int spriteCharacterIndex); EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: " + spriteCharacterIndex + ""), style); EditorGUI.LabelField(new Rect(rect.x + 75f, rect.y, 120f, 18), new GUIContent("Unicode: 0x" + prop_SpriteUnicode.intValue.ToString("X") + ""), style); EditorGUI.LabelField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), new GUIContent("Name: " + prop_SpriteName.stringValue + ""), style); EditorGUI.LabelField(new Rect(rect.x, rect.y + 18, 120, 18), new GUIContent("Glyph ID: " + prop_SpriteGlyphIndex.intValue + ""), style); // Draw Sprite Glyph (if exists) DrawSpriteGlyph(position, property); EditorGUI.LabelField(new Rect(rect.x, rect.y + 36, 80, 18), new GUIContent("Scale: " + prop_SpriteScale.floatValue + ""), style); } else // Display editable fields { // Get a reference to the underlying Sprite Asset TMP_SpriteAsset spriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset; // Sprite Character Index int.TryParse(property.displayName.Split(' ')[1], out int spriteCharacterIndex); EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: " + spriteCharacterIndex + ""), style); EditorGUIUtility.labelWidth = 55f; GUI.SetNextControlName("Unicode Input"); EditorGUI.BeginChangeCheck(); string unicode = EditorGUI.DelayedTextField(new Rect(rect.x + 75f, rect.y, 120, 18), "Unicode:", prop_SpriteUnicode.intValue.ToString("X")); if (GUI.GetNameOfFocusedControl() == "Unicode Input") { //Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F')) { Event.current.character = '\0'; } } if (EditorGUI.EndChangeCheck()) { // Update Unicode value prop_SpriteUnicode.intValue = TMP_TextUtilities.StringHexToInt(unicode); spriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } EditorGUIUtility.labelWidth = 41f; EditorGUI.BeginChangeCheck(); EditorGUI.DelayedTextField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), prop_SpriteName, new GUIContent("Name:")); if (EditorGUI.EndChangeCheck()) { // Recompute hashCode for new name prop_SpriteNameHashCode.intValue = TMP_TextUtilities.GetSimpleHashCode(prop_SpriteName.stringValue); spriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } EditorGUIUtility.labelWidth = 59f; EditorGUI.BeginChangeCheck(); EditorGUI.DelayedIntField(new Rect(rect.x, rect.y + 18, 100, 18), prop_SpriteGlyphIndex, new GUIContent("Glyph ID:")); if (EditorGUI.EndChangeCheck()) { spriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } // Draw Sprite Glyph (if exists) DrawSpriteGlyph(position, property); int glyphIndex = prop_SpriteGlyphIndex.intValue; // Reset glyph selection if new character has been selected. if (GUI.enabled && m_GlyphSelectedForEditing != glyphIndex) m_GlyphSelectedForEditing = -1; // Display button to edit the glyph data. if (GUI.Button(new Rect(rect.x + 120, rect.y + 18, 75, 18), new GUIContent("Edit Glyph"))) { if (m_GlyphSelectedForEditing == -1) m_GlyphSelectedForEditing = glyphIndex; else m_GlyphSelectedForEditing = -1; // Button clicks should not result in potential change. GUI.changed = false; } // Show the glyph property drawer if selected if (glyphIndex == m_GlyphSelectedForEditing && GUI.enabled) { if (spriteAsset != null) { // Lookup glyph and draw glyph (if available) int elementIndex = spriteAsset.spriteGlyphTable.FindIndex(item => item.index == glyphIndex); if (elementIndex != -1) { // Get a reference to the Sprite Glyph Table SerializedProperty prop_SpriteGlyphTable = property.serializedObject.FindProperty("m_SpriteGlyphTable"); SerializedProperty prop_SpriteGlyph = prop_SpriteGlyphTable.GetArrayElementAtIndex(elementIndex); SerializedProperty prop_GlyphMetrics = prop_SpriteGlyph.FindPropertyRelative("m_Metrics"); SerializedProperty prop_GlyphRect = prop_SpriteGlyph.FindPropertyRelative("m_GlyphRect"); Rect newRect = EditorGUILayout.GetControlRect(false, 115); EditorGUI.DrawRect(new Rect(newRect.x + 62, newRect.y - 20, newRect.width - 62, newRect.height - 5), new Color(0.1f, 0.1f, 0.1f, 0.45f)); EditorGUI.DrawRect(new Rect(newRect.x + 63, newRect.y - 19, newRect.width - 64, newRect.height - 7), new Color(0.3f, 0.3f, 0.3f, 0.8f)); // Display GlyphRect newRect.x += 65; newRect.y -= 18; newRect.width += 5; EditorGUI.PropertyField(newRect, prop_GlyphRect); // Display GlyphMetrics newRect.y += 45; EditorGUI.PropertyField(newRect, prop_GlyphMetrics); rect.y += 120; } } } EditorGUIUtility.labelWidth = 39f; EditorGUI.PropertyField(new Rect(rect.x, rect.y + 36, 80, 18), prop_SpriteScale, new GUIContent("Scale:")); } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 58; } void DrawSpriteGlyph(Rect position, SerializedProperty property) { // Get a reference to the sprite glyph table TMP_SpriteAsset spriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset; if (spriteAsset == null) return; int glyphIndex = property.FindPropertyRelative("m_GlyphIndex").intValue; // Lookup glyph and draw glyph (if available) int elementIndex = spriteAsset.spriteGlyphTable.FindIndex(item => item.index == glyphIndex); if (elementIndex != -1) { // Get a reference to the Sprite Glyph Table SerializedProperty prop_SpriteGlyphTable = property.serializedObject.FindProperty("m_SpriteGlyphTable"); SerializedProperty prop_SpriteGlyph = prop_SpriteGlyphTable.GetArrayElementAtIndex(elementIndex); SerializedProperty prop_GlyphRect = prop_SpriteGlyph.FindPropertyRelative("m_GlyphRect"); // Get a reference to the sprite texture Texture tex = spriteAsset.spriteSheet; // Return if we don't have a texture assigned to the sprite asset. if (tex == null) { Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + spriteAsset.name + "] Sprite Asset.", spriteAsset); return; } Vector2 spriteTexPosition = new Vector2(position.x, position.y); Vector2 spriteSize = new Vector2(48, 48); Vector2 alignmentOffset = new Vector2((58 - spriteSize.x) / 2, (58 - spriteSize.y) / 2); float x = prop_GlyphRect.FindPropertyRelative("m_X").intValue; float y = prop_GlyphRect.FindPropertyRelative("m_Y").intValue; float spriteWidth = prop_GlyphRect.FindPropertyRelative("m_Width").intValue; float spriteHeight = prop_GlyphRect.FindPropertyRelative("m_Height").intValue; if (spriteWidth >= spriteHeight) { spriteSize.y = spriteHeight * spriteSize.x / spriteWidth; spriteTexPosition.y += (spriteSize.x - spriteSize.y) / 2; } else { spriteSize.x = spriteWidth * spriteSize.y / spriteHeight; spriteTexPosition.x += (spriteSize.y - spriteSize.x) / 2; } // Compute the normalized texture coordinates Rect texCoords = new Rect(x / tex.width, y / tex.height, spriteWidth / tex.width, spriteHeight / tex.height); GUI.DrawTextureWithTexCoords(new Rect(spriteTexPosition.x + alignmentOffset.x, spriteTexPosition.y + alignmentOffset.y, spriteSize.x, spriteSize.y), tex, texCoords, true); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteCharacterPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: 37cff9f5a86ae494c8cb04423580480d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteGlyphPropertyDrawer.cs ================================================ using UnityEngine; using UnityEngine.TextCore; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_SpriteGlyph))] public class TMP_SpriteGlyphPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_GlyphIndex = property.FindPropertyRelative("m_Index"); SerializedProperty prop_GlyphMetrics = property.FindPropertyRelative("m_Metrics"); SerializedProperty prop_GlyphRect = property.FindPropertyRelative("m_GlyphRect"); SerializedProperty prop_Scale = property.FindPropertyRelative("m_Scale"); SerializedProperty prop_AtlasIndex = property.FindPropertyRelative("m_AtlasIndex"); GUIStyle style = new GUIStyle(EditorStyles.label); style.richText = true; Rect rect = new Rect(position.x + 70, position.y, position.width, 49); // Draw GlyphRect EditorGUI.PropertyField(rect, prop_GlyphRect); // Draw GlyphMetrics rect.y += 45; EditorGUI.PropertyField(rect, prop_GlyphMetrics); EditorGUIUtility.labelWidth = 40f; EditorGUI.PropertyField(new Rect(rect.x, rect.y + 65, 75, 18), prop_Scale, new GUIContent("Scale:")); EditorGUIUtility.labelWidth = 74f; EditorGUI.PropertyField(new Rect(rect.x + 85, rect.y + 65, 95, 18), prop_AtlasIndex, new GUIContent("Atlas Index:")); DrawGlyph(position, property); int.TryParse(property.displayName.Split(' ')[1], out int spriteCharacterIndex); float labelWidthIndex = GUI.skin.label.CalcSize(new GUIContent("#" + spriteCharacterIndex)).x; EditorGUI.LabelField(new Rect(position.x, position.y + 5, 64f, 18f), new GUIContent("#" + spriteCharacterIndex), style); float labelWidthID = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_GlyphIndex.intValue)).x; EditorGUI.LabelField(new Rect(position.x + (64 - labelWidthID) / 2, position.y + 110, 64f, 18f), new GUIContent("ID: " + prop_GlyphIndex.intValue + ""), style); } void DrawGlyph(Rect position, SerializedProperty property) { // Get a reference to the sprite texture Texture tex = (property.serializedObject.targetObject as TMP_SpriteAsset).spriteSheet; // Return if we don't have a texture assigned to the sprite asset. if (tex == null) { Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + property.serializedObject.targetObject.name + "] Sprite Asset.", property.serializedObject.targetObject); return; } Vector2 spriteTexPosition = new Vector2(position.x, position.y); Vector2 spriteSize = new Vector2(65, 65); SerializedProperty prop_GlyphRect = property.FindPropertyRelative("m_GlyphRect"); int spriteImageX = prop_GlyphRect.FindPropertyRelative("m_X").intValue; int spriteImageY = prop_GlyphRect.FindPropertyRelative("m_Y").intValue; int spriteImageWidth = prop_GlyphRect.FindPropertyRelative("m_Width").intValue; int spriteImageHeight = prop_GlyphRect.FindPropertyRelative("m_Height").intValue; if (spriteImageWidth >= spriteImageHeight) { spriteSize.y = spriteImageHeight * spriteSize.x / spriteImageWidth; spriteTexPosition.y += (spriteSize.x - spriteSize.y) / 2; } else { spriteSize.x = spriteImageWidth * spriteSize.y / spriteImageHeight; spriteTexPosition.x += (spriteSize.y - spriteSize.x) / 2; } // Compute the normalized texture coordinates Rect texCoords = new Rect((float)spriteImageX / tex.width, (float)spriteImageY / tex.height, (float)spriteImageWidth / tex.width, (float)spriteImageHeight / tex.height); GUI.DrawTextureWithTexCoords(new Rect(spriteTexPosition.x + 5, spriteTexPosition.y + 32f, spriteSize.x, spriteSize.y), tex, texCoords, true); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 130f; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SpriteGlyphPropertyDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: 056819c66570ca54cadb72330a354050 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_StyleAssetMenu.cs ================================================ using UnityEngine; using UnityEditor; using System.IO; using System.Collections; namespace TMPro.EditorUtilities { public static class TMP_StyleAssetMenu { [MenuItem("Assets/Create/TextMeshPro/Style Sheet", false, 120)] public static void CreateTextMeshProObjectPerform() { string filePath; if (Selection.assetGUIDs.Length == 0) { // No asset selected. filePath = "Assets"; } else { // Get the path of the selected folder or asset. filePath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]); // Get the file extension of the selected asset as it might need to be removed. string fileExtension = Path.GetExtension(filePath); if (fileExtension != "") { filePath = Path.GetDirectoryName(filePath); } } string filePathWithName = AssetDatabase.GenerateUniqueAssetPath(filePath + "/TMP StyleSheet.asset"); //// Create new Style Sheet Asset. TMP_StyleSheet styleSheet = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(styleSheet, filePathWithName); EditorUtility.SetDirty(styleSheet); AssetDatabase.SaveAssets(); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_StyleAssetMenu.cs.meta ================================================ fileFormatVersion: 2 guid: 23a562f2cac6401f9f91251c68a1a794 timeCreated: 1432690168 licenseType: Store MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_StyleSheetEditor.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TMP_Style))] public class StyleDrawer : PropertyDrawer { public static readonly float height = 95f; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return height; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty nameProperty = property.FindPropertyRelative("m_Name"); SerializedProperty hashCodeProperty = property.FindPropertyRelative("m_HashCode"); SerializedProperty openingDefinitionProperty = property.FindPropertyRelative("m_OpeningDefinition"); SerializedProperty closingDefinitionProperty = property.FindPropertyRelative("m_ClosingDefinition"); SerializedProperty openingDefinitionArray = property.FindPropertyRelative("m_OpeningTagArray"); SerializedProperty closingDefinitionArray = property.FindPropertyRelative("m_ClosingTagArray"); EditorGUIUtility.labelWidth = 90; position.height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; float labelHeight = position.height + 2f; EditorGUI.BeginChangeCheck(); Rect rect0 = new Rect(position.x, position.y, (position.width) / 2 + 5, position.height); EditorGUI.PropertyField(rect0, nameProperty); if (EditorGUI.EndChangeCheck()) { // Recompute HashCode if name has changed. hashCodeProperty.intValue = TMP_TextUtilities.GetSimpleHashCode(nameProperty.stringValue); property.serializedObject.ApplyModifiedProperties(); // Dictionary needs to be updated since HashCode has changed. TMP_StyleSheet.RefreshStyles(); } // HashCode Rect rect1 = new Rect(rect0.x + rect0.width + 5, position.y, 65, position.height); GUI.Label(rect1, "HashCode"); GUI.enabled = false; rect1.x += 65; rect1.width = position.width / 2 - 75; EditorGUI.PropertyField(rect1, hashCodeProperty, GUIContent.none); GUI.enabled = true; // Text Tags EditorGUI.BeginChangeCheck(); // Opening Tags position.y += labelHeight; GUI.Label(position, "Opening Tags"); Rect textRect1 = new Rect(108, position.y, position.width - 86, 35); openingDefinitionProperty.stringValue = EditorGUI.TextArea(textRect1, openingDefinitionProperty.stringValue); if (EditorGUI.EndChangeCheck()) { // If any properties have changed, we need to update the Opening and Closing Arrays. int size = openingDefinitionProperty.stringValue.Length; // Adjust array size to match new string length. if (openingDefinitionArray.arraySize != size) openingDefinitionArray.arraySize = size; for (int i = 0; i < size; i++) { SerializedProperty element = openingDefinitionArray.GetArrayElementAtIndex(i); element.intValue = openingDefinitionProperty.stringValue[i]; } } EditorGUI.BeginChangeCheck(); // Closing Tags position.y += 38; GUI.Label(position, "Closing Tags"); Rect textRect2 = new Rect(108, position.y, position.width - 86, 35); closingDefinitionProperty.stringValue = EditorGUI.TextArea(textRect2, closingDefinitionProperty.stringValue); if (EditorGUI.EndChangeCheck()) { // If any properties have changed, we need to update the Opening and Closing Arrays. int size = closingDefinitionProperty.stringValue.Length; // Adjust array size to match new string length. if (closingDefinitionArray.arraySize != size) closingDefinitionArray.arraySize = size; for (int i = 0; i < size; i++) { SerializedProperty element = closingDefinitionArray.GetArrayElementAtIndex(i); element.intValue = closingDefinitionProperty.stringValue[i]; } } } } [CustomEditor(typeof(TMP_StyleSheet)), CanEditMultipleObjects] public class TMP_StyleEditor : Editor { SerializedProperty m_StyleListProp; int m_SelectedElement = -1; //private Event m_CurrentEvent; int m_Page; void OnEnable() { m_StyleListProp = serializedObject.FindProperty("m_StyleList"); } public override void OnInspectorGUI() { Event currentEvent = Event.current; serializedObject.Update(); int arraySize = m_StyleListProp.arraySize; int itemsPerPage = (Screen.height - 178) / 111; if (arraySize > 0) { // Display each Style entry using the StyleDrawer PropertyDrawer. for (int i = itemsPerPage * m_Page; i < arraySize && i < itemsPerPage * (m_Page + 1); i++) { // Define the start of the selection region of the element. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); EditorGUILayout.BeginVertical(EditorStyles.helpBox); SerializedProperty spriteInfo = m_StyleListProp.GetArrayElementAtIndex(i); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(spriteInfo); EditorGUILayout.EndVertical(); if (EditorGUI.EndChangeCheck()) { // } // Define the end of the selection region of the element. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)); // Check for Item selection Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y); if (DoSelectionCheck(selectionArea)) { if (m_SelectedElement == i) { m_SelectedElement = -1; } else { m_SelectedElement = i; GUIUtility.keyboardControl = 0; } } // Handle Selection Highlighting if (m_SelectedElement == i) { TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255)); } } } int shiftMultiplier = currentEvent.shift ? 10 : 1; // Page + Shift goes 10 page forward GUILayout.Space(-3f); Rect pagePos = EditorGUILayout.GetControlRect(false, 20); pagePos.width /= 6; // Return if we can't display any items. if (itemsPerPage == 0) return; // Add new style. pagePos.x += pagePos.width * 4; if (GUI.Button(pagePos, "+")) { m_StyleListProp.arraySize += 1; serializedObject.ApplyModifiedProperties(); TMP_StyleSheet.RefreshStyles(); } // Delete selected style. pagePos.x += pagePos.width; if (m_SelectedElement == -1) GUI.enabled = false; if (GUI.Button(pagePos, "-")) { if (m_SelectedElement != -1) m_StyleListProp.DeleteArrayElementAtIndex(m_SelectedElement); m_SelectedElement = -1; serializedObject.ApplyModifiedProperties(); TMP_StyleSheet.RefreshStyles(); } GUILayout.Space(5f); pagePos = EditorGUILayout.GetControlRect(false, 20); pagePos.width /= 3; // Previous Page if (m_Page > 0) GUI.enabled = true; else GUI.enabled = false; if (GUI.Button(pagePos, "Previous")) m_Page -= 1 * shiftMultiplier; // PAGE COUNTER GUI.enabled = true; pagePos.x += pagePos.width; int totalPages = (int)(arraySize / (float)itemsPerPage + 0.999f); GUI.Label(pagePos, "Page " + (m_Page + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel); // Next Page pagePos.x += pagePos.width; if (itemsPerPage * (m_Page + 1) < arraySize) GUI.enabled = true; else GUI.enabled = false; if (GUI.Button(pagePos, "Next")) m_Page += 1 * shiftMultiplier; // Clamp page range m_Page = Mathf.Clamp(m_Page, 0, arraySize / itemsPerPage); if (serializedObject.ApplyModifiedProperties()) TMPro_EventManager.ON_TEXT_STYLE_PROPERTY_CHANGED(true); // Clear selection if mouse event was not consumed. GUI.enabled = true; if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0) m_SelectedElement = -1; } // Check if any of the Style elements were clicked on. static bool DoSelectionCheck(Rect selectionArea) { Event currentEvent = Event.current; switch (currentEvent.type) { case EventType.MouseDown: if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0) { currentEvent.Use(); return true; } break; } return false; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_StyleSheetEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 34e2c9b9d9e44953933afe37461f44e6 timeCreated: 1432683777 licenseType: Store MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SubMeshUI_Editor.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TMP_SubMeshUI)), CanEditMultipleObjects] public class TMP_SubMeshUI_Editor : Editor { private struct m_foldout { // Track Inspector foldout panel states, globally. //public static bool textInput = true; public static bool fontSettings = true; //public static bool extraSettings = false; //public static bool shadowSetting = false; //public static bool materialEditor = true; } private SerializedProperty fontAsset_prop; private SerializedProperty spriteAsset_prop; private TMP_SubMeshUI m_SubMeshComponent; private CanvasRenderer m_canvasRenderer; private Editor m_materialEditor; private Material m_targetMaterial; public void OnEnable() { fontAsset_prop = serializedObject.FindProperty("m_fontAsset"); spriteAsset_prop = serializedObject.FindProperty("m_spriteAsset"); m_SubMeshComponent = target as TMP_SubMeshUI; //m_rectTransform = m_SubMeshComponent.rectTransform; m_canvasRenderer = m_SubMeshComponent.canvasRenderer; // Create new Material Editor if one does not exists if (m_canvasRenderer != null && m_canvasRenderer.GetMaterial() != null) { m_materialEditor = Editor.CreateEditor(m_canvasRenderer.GetMaterial()); m_targetMaterial = m_canvasRenderer.GetMaterial(); } } public void OnDisable() { // Destroy material editor if one exists if (m_materialEditor != null) { //Debug.Log("Destroying Inline Material Editor."); DestroyImmediate(m_materialEditor); } } public override void OnInspectorGUI() { GUI.enabled = false; EditorGUILayout.PropertyField(fontAsset_prop); EditorGUILayout.PropertyField(spriteAsset_prop); GUI.enabled = true; EditorGUILayout.Space(); // If a Custom Material Editor exists, we use it. if (m_canvasRenderer != null && m_canvasRenderer.GetMaterial() != null) { Material mat = m_canvasRenderer.GetMaterial(); //Debug.Log(mat + " " + m_targetMaterial); if (mat != m_targetMaterial) { // Destroy previous Material Instance //Debug.Log("New Material has been assigned."); m_targetMaterial = mat; DestroyImmediate(m_materialEditor); } if (m_materialEditor == null) { m_materialEditor = Editor.CreateEditor(mat); } m_materialEditor.DrawHeader(); m_materialEditor.OnInspectorGUI(); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SubMeshUI_Editor.cs.meta ================================================ fileFormatVersion: 2 guid: 6b01141ed8f74d198965c86f25eb7040 timeCreated: 1452757501 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SubMesh_Editor.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TMP_SubMesh)), CanEditMultipleObjects] public class TMP_SubMesh_Editor : Editor { private struct m_foldout { // Track Inspector foldout panel states, globally. //public static bool textInput = true; public static bool fontSettings = true; //public static bool extraSettings = false; //public static bool shadowSetting = false; //public static bool materialEditor = true; } private SerializedProperty fontAsset_prop; private SerializedProperty spriteAsset_prop; private TMP_SubMesh m_SubMeshComponent; private Renderer m_Renderer; public void OnEnable() { fontAsset_prop = serializedObject.FindProperty("m_fontAsset"); spriteAsset_prop = serializedObject.FindProperty("m_spriteAsset"); m_SubMeshComponent = target as TMP_SubMesh; m_Renderer = m_SubMeshComponent.renderer; } public override void OnInspectorGUI() { EditorGUI.indentLevel = 0; GUI.enabled = false; EditorGUILayout.PropertyField(fontAsset_prop); EditorGUILayout.PropertyField(spriteAsset_prop); GUI.enabled = true; EditorGUI.BeginChangeCheck(); // SORTING LAYERS var sortingLayerNames = SortingLayerHelper.sortingLayerNames; // Look up the layer name using the current layer ID string oldName = SortingLayerHelper.GetSortingLayerNameFromID(m_Renderer.sortingLayerID); // Use the name to look up our array index into the names list int oldLayerIndex = System.Array.IndexOf(sortingLayerNames, oldName); // Show the pop-up for the names int newLayerIndex = EditorGUILayout.Popup("Sorting Layer", oldLayerIndex, sortingLayerNames); // If the index changes, look up the ID for the new index to store as the new ID if (newLayerIndex != oldLayerIndex) { //Undo.RecordObject(renderer, "Edit Sorting Layer"); m_Renderer.sortingLayerID = SortingLayerHelper.GetSortingLayerIDForIndex(newLayerIndex); //EditorUtility.SetDirty(renderer); } // Expose the manual sorting order int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", m_Renderer.sortingOrder); if (newSortingLayerOrder != m_Renderer.sortingOrder) { //Undo.RecordObject(renderer, "Edit Sorting Order"); m_Renderer.sortingOrder = newSortingLayerOrder; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_SubMesh_Editor.cs.meta ================================================ fileFormatVersion: 2 guid: dd2fe74169b54bf58fca17288513ef38 timeCreated: 1456189048 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_TextAlignmentDrawer.cs ================================================ using UnityEngine; using UnityEditor; namespace TMPro.EditorUtilities { [CustomPropertyDrawer(typeof(TextAlignmentOptions))] public class TMP_TextAlignmentDrawer : PropertyDrawer { const int k_AlignmentButtonWidth = 24; const int k_AlignmentButtonHeight = 20; const int k_WideViewWidth = 504; const int k_ControlsSpacing = 6; const int k_GroupWidth = k_AlignmentButtonWidth * 6; static readonly int k_TextAlignmentHash = "DoTextAligmentControl".GetHashCode(); public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return EditorGUIUtility.currentViewWidth > k_WideViewWidth ? k_AlignmentButtonHeight : k_AlignmentButtonHeight * 2 + 3; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { var id = GUIUtility.GetControlID(k_TextAlignmentHash, FocusType.Keyboard, position); EditorGUI.BeginProperty(position, label, property); { var controlArea = EditorGUI.PrefixLabel(position, id, label); var horizontalAligment = new Rect(controlArea.x, controlArea.y, k_GroupWidth, k_AlignmentButtonHeight); var verticalAligment = new Rect(!(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.x : horizontalAligment.xMax + k_ControlsSpacing, !(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.y + k_AlignmentButtonHeight + 3 : controlArea.y, k_GroupWidth, k_AlignmentButtonHeight); EditorGUI.BeginChangeCheck(); var selectedHorizontal = DoHorizontalAligmentControl(horizontalAligment, property); var selectedVertical = DoVerticalAligmentControl(verticalAligment, property); if (EditorGUI.EndChangeCheck()) { var value = (0x1 << selectedHorizontal) | (0x100 << selectedVertical); property.intValue = value; } } EditorGUI.EndProperty(); } static int DoHorizontalAligmentControl(Rect position, SerializedProperty alignment) { var selected = TMP_EditorUtility.GetHorizontalAlignmentGridValue(alignment.intValue); var values = new bool[6]; values[selected] = true; if (alignment.hasMultipleDifferentValues) { foreach (var obj in alignment.serializedObject.targetObjects) { var text = obj as TMP_Text; if (text != null) { values[TMP_EditorUtility.GetHorizontalAlignmentGridValue((int)text.alignment)] = true; } } } position.width = k_AlignmentButtonWidth; for (var i = 0; i < values.Length; i++) { var oldValue = values[i]; var newValue = TMP_EditorUtility.EditorToggle(position, oldValue, TMP_UIStyleManager.alignContentA[i], i == 0 ? TMP_UIStyleManager.alignmentButtonLeft : (i == 5 ? TMP_UIStyleManager.alignmentButtonRight : TMP_UIStyleManager.alignmentButtonMid)); if (newValue != oldValue) { selected = i; } position.x += position.width; } return selected; } static int DoVerticalAligmentControl(Rect position, SerializedProperty alignment) { var selected = TMP_EditorUtility.GetVerticalAlignmentGridValue(alignment.intValue); var values = new bool[6]; values[selected] = true; if (alignment.hasMultipleDifferentValues) { foreach (var obj in alignment.serializedObject.targetObjects) { var text = obj as TMP_Text; if (text != null) { values[TMP_EditorUtility.GetVerticalAlignmentGridValue((int)text.alignment)] = true; } } } position.width = k_AlignmentButtonWidth; for (var i = 0; i < values.Length; i++) { var oldValue = values[i]; var newValue = TMP_EditorUtility.EditorToggle(position, oldValue, TMP_UIStyleManager.alignContentB[i], i == 0 ? TMP_UIStyleManager.alignmentButtonLeft : (i == 5 ? TMP_UIStyleManager.alignmentButtonRight : TMP_UIStyleManager.alignmentButtonMid)); if (newValue != oldValue) { selected = i; } position.x += position.width; } return selected; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_TextAlignmentDrawer.cs.meta ================================================ fileFormatVersion: 2 guid: c55a64c7570474f47a94abe39ebfef04 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_UIStyleManager.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { public static class TMP_UIStyleManager { public static GUIStyle label; public static GUIStyle textAreaBoxWindow; public static GUIStyle boldFoldout; public static GUIStyle panelTitle; public static GUIStyle sectionHeader; public static GUIStyle centeredLabel; public static GUIStyle rightLabel; public static GUIStyle wrappingTextArea; public static GUIStyle alignmentButtonLeft; public static GUIStyle alignmentButtonMid; public static GUIStyle alignmentButtonRight; // Alignment Button Textures public static Texture2D alignLeft; public static Texture2D alignCenter; public static Texture2D alignRight; public static Texture2D alignJustified; public static Texture2D alignFlush; public static Texture2D alignGeoCenter; public static Texture2D alignTop; public static Texture2D alignMiddle; public static Texture2D alignBottom; public static Texture2D alignBaseline; public static Texture2D alignMidline; public static Texture2D alignCapline; public static Texture2D sectionHeaderTexture; public static GUIContent[] alignContentA; public static GUIContent[] alignContentB; static TMP_UIStyleManager() { // Find to location of the TextMesh Pro Asset Folder (as users may have moved it) var tmproAssetFolderPath = TMP_EditorUtility.packageRelativePath; if (EditorGUIUtility.isProSkin) { alignLeft = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignLeft.psd", typeof(Texture2D)) as Texture2D; alignCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenter.psd", typeof(Texture2D)) as Texture2D; alignRight = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignRight.psd", typeof(Texture2D)) as Texture2D; alignJustified = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignJustified.psd", typeof(Texture2D)) as Texture2D; alignFlush = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignFlush.psd", typeof(Texture2D)) as Texture2D; alignGeoCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenterGeo.psd", typeof(Texture2D)) as Texture2D; alignTop = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignTop.psd", typeof(Texture2D)) as Texture2D; alignMiddle = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMiddle.psd", typeof(Texture2D)) as Texture2D; alignBottom = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBottom.psd", typeof(Texture2D)) as Texture2D; alignBaseline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBaseLine.psd", typeof(Texture2D)) as Texture2D; alignMidline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMidLine.psd", typeof(Texture2D)) as Texture2D; alignCapline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCapLine.psd", typeof(Texture2D)) as Texture2D; sectionHeaderTexture = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/SectionHeader_Dark.psd", typeof(Texture2D)) as Texture2D; } else { alignLeft = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignLeft_Light.psd", typeof(Texture2D)) as Texture2D; alignCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenter_Light.psd", typeof(Texture2D)) as Texture2D; alignRight = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignRight_Light.psd", typeof(Texture2D)) as Texture2D; alignJustified = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignJustified_Light.psd", typeof(Texture2D)) as Texture2D; alignFlush = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignFlush_Light.psd", typeof(Texture2D)) as Texture2D; alignGeoCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenterGeo_Light.psd", typeof(Texture2D)) as Texture2D; alignTop = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignTop_Light.psd", typeof(Texture2D)) as Texture2D; alignMiddle = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMiddle_Light.psd", typeof(Texture2D)) as Texture2D; alignBottom = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBottom_Light.psd", typeof(Texture2D)) as Texture2D; alignBaseline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBaseLine_Light.psd", typeof(Texture2D)) as Texture2D; alignMidline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMidLine_Light.psd", typeof(Texture2D)) as Texture2D; alignCapline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCapLine_Light.psd", typeof(Texture2D)) as Texture2D; sectionHeaderTexture = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/SectionHeader_Light.psd", typeof(Texture2D)) as Texture2D; } label = new GUIStyle(EditorStyles.label) { richText = true, wordWrap = true, stretchWidth = true }; textAreaBoxWindow = new GUIStyle(EditorStyles.textArea) { richText = true }; boldFoldout = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold }; panelTitle = new GUIStyle(EditorStyles.label) { fontStyle = FontStyle.Bold }; sectionHeader = new GUIStyle(EditorStyles.label) { fixedHeight = 22, richText = true, border = new RectOffset(9, 9, 0, 0), overflow = new RectOffset(9, 0, 0, 0), padding = new RectOffset(0, 0, 4, 0) }; sectionHeader.normal.background = sectionHeaderTexture; centeredLabel = new GUIStyle(EditorStyles.label) { alignment = TextAnchor.MiddleCenter}; rightLabel = new GUIStyle(EditorStyles.label) { alignment = TextAnchor.MiddleRight, richText = true }; alignmentButtonLeft = new GUIStyle(EditorStyles.miniButtonLeft); alignmentButtonLeft.padding.left = 4; alignmentButtonLeft.padding.right = 4; alignmentButtonLeft.padding.top = 2; alignmentButtonLeft.padding.bottom = 2; alignmentButtonMid = new GUIStyle(EditorStyles.miniButtonMid); alignmentButtonMid.padding.left = 4; alignmentButtonMid.padding.right = 4; alignmentButtonLeft.padding.top = 2; alignmentButtonLeft.padding.bottom = 2; alignmentButtonRight = new GUIStyle(EditorStyles.miniButtonRight); alignmentButtonRight.padding.left = 4; alignmentButtonRight.padding.right = 4; alignmentButtonLeft.padding.top = 2; alignmentButtonLeft.padding.bottom = 2; wrappingTextArea = new GUIStyle(EditorStyles.textArea); wrappingTextArea.wordWrap = true; alignContentA = new [] { new GUIContent(alignLeft, "Left"), new GUIContent(alignCenter, "Center"), new GUIContent(alignRight, "Right"), new GUIContent(alignJustified, "Justified"), new GUIContent(alignFlush, "Flush"), new GUIContent(alignGeoCenter, "Geometry Center") }; alignContentB = new [] { new GUIContent(alignTop, "Top"), new GUIContent(alignMiddle, "Middle"), new GUIContent(alignBottom, "Bottom"), new GUIContent(alignBaseline, "Baseline"), new GUIContent(alignMidline, "Midline"), new GUIContent(alignCapline, "Capline") }; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_UIStyleManager.cs.meta ================================================ fileFormatVersion: 2 guid: 30a939dce2fd4073955f2f20e659d506 timeCreated: 1426454127 licenseType: Store MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_UiEditorPanel.cs ================================================ using UnityEngine; using UnityEngine.UI; using UnityEditor; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TextMeshProUGUI), true), CanEditMultipleObjects] public class TMP_UiEditorPanel : TMP_BaseEditorPanel { static readonly GUIContent k_RaycastTargetLabel = new GUIContent("Raycast Target", "Whether the text blocks raycasts from the Graphic Raycaster."); SerializedProperty m_RaycastTargetProp; protected override void OnEnable() { base.OnEnable(); m_RaycastTargetProp = serializedObject.FindProperty("m_RaycastTarget"); } protected override void DrawExtraSettings() { Foldout.extraSettings = EditorGUILayout.Foldout(Foldout.extraSettings, k_ExtraSettingsLabel, true, TMP_UIStyleManager.boldFoldout); if (Foldout.extraSettings) { EditorGUI.indentLevel += 1; DrawMargins(); DrawGeometrySorting(); DrawRichText(); DrawRaycastTarget(); DrawParsing(); DrawKerning(); DrawPadding(); EditorGUI.indentLevel -= 1; } } protected void DrawRaycastTarget() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_RaycastTargetProp, k_RaycastTargetLabel); if (EditorGUI.EndChangeCheck()) { // Change needs to propagate to the child sub objects. Graphic[] graphicComponents = m_TextComponent.GetComponentsInChildren(); for (int i = 1; i < graphicComponents.Length; i++) graphicComponents[i].raycastTarget = m_RaycastTargetProp.boolValue; m_HavePropertiesChanged = true; } } // Method to handle multi object selection protected override bool IsMixSelectionTypes() { GameObject[] objects = Selection.gameObjects; if (objects.Length > 1) { for (int i = 0; i < objects.Length; i++) { if (objects[i].GetComponent() == null) return true; } } return false; } protected override void OnUndoRedo() { int undoEventId = Undo.GetCurrentGroup(); int lastUndoEventId = s_EventId; if (undoEventId != lastUndoEventId) { for (int i = 0; i < targets.Length; i++) { //Debug.Log("Undo & Redo Performed detected in Editor Panel. Event ID:" + Undo.GetCurrentGroup()); TMPro_EventManager.ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(true, targets[i] as TextMeshProUGUI); s_EventId = undoEventId; } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMP_UiEditorPanel.cs.meta ================================================ fileFormatVersion: 2 guid: 21c0044a7f964773be90d197a78e4703 timeCreated: 1443571501 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_ContextMenus.cs ================================================ using UnityEngine; using UnityEditor; using System.IO; using System.Collections; namespace TMPro.EditorUtilities { public class TMP_ContextMenus : Editor { private static Texture m_copiedTexture; private static Material m_copiedProperties; private static Material m_copiedAtlasProperties; // Add a Context Menu to the Texture Editor Panel to allow Copy / Paste of Texture. [MenuItem("CONTEXT/Texture/Copy", false, 2000)] static void CopyTexture(MenuCommand command) { m_copiedTexture = command.context as Texture; } // Select the currently assigned material or material preset. [MenuItem("CONTEXT/Material/Select Material", false, 500)] static void SelectMaterial(MenuCommand command) { Material mat = command.context as Material; // Select current material EditorUtility.FocusProjectWindow(); EditorGUIUtility.PingObject(mat); } // Add a Context Menu to allow easy duplication of the Material. [MenuItem("CONTEXT/Material/Create Material Preset", false)] static void DuplicateMaterial(MenuCommand command) { // Get the type of text object // If material is not a base material, we get material leaks... Material source_Mat = (Material)command.context; if (!EditorUtility.IsPersistent(source_Mat)) { Debug.LogWarning("Material is an instance and cannot be converted into a permanent asset."); return; } string assetPath = AssetDatabase.GetAssetPath(source_Mat).Split('.')[0]; Material duplicate = new Material(source_Mat); // Need to manually copy the shader keywords duplicate.shaderKeywords = source_Mat.shaderKeywords; AssetDatabase.CreateAsset(duplicate, AssetDatabase.GenerateUniqueAssetPath(assetPath + ".mat")); // Assign duplicate Material to selected object (if one is) if (Selection.activeGameObject != null) { TMP_Text textObject = Selection.activeGameObject.GetComponent(); if (textObject != null) { textObject.fontSharedMaterial = duplicate; } else { TMP_SubMesh subMeshObject = Selection.activeGameObject.GetComponent(); if (subMeshObject != null) subMeshObject.sharedMaterial = duplicate; else { TMP_SubMeshUI subMeshUIObject = Selection.activeGameObject.GetComponent(); if (subMeshUIObject != null) subMeshUIObject.sharedMaterial = duplicate; } } } // Ping newly created Material Preset. EditorUtility.FocusProjectWindow(); EditorGUIUtility.PingObject(duplicate); } //[MenuItem("CONTEXT/MaterialComponent/Copy Material Properties", false)] [MenuItem("CONTEXT/Material/Copy Material Properties", false)] static void CopyMaterialProperties(MenuCommand command) { Material mat = null; if (command.context.GetType() == typeof(Material)) mat = (Material)command.context; else { mat = Selection.activeGameObject.GetComponent().GetMaterial(); } m_copiedProperties = new Material(mat); m_copiedProperties.shaderKeywords = mat.shaderKeywords; m_copiedProperties.hideFlags = HideFlags.DontSave; } // PASTE MATERIAL //[MenuItem("CONTEXT/MaterialComponent/Paste Material Properties", false)] [MenuItem("CONTEXT/Material/Paste Material Properties", false)] static void PasteMaterialProperties(MenuCommand command) { if (m_copiedProperties == null) { Debug.LogWarning("No Material Properties to Paste. Use Copy Material Properties first."); return; } Material mat = null; if (command.context.GetType() == typeof(Material)) mat = (Material)command.context; else { mat = Selection.activeGameObject.GetComponent().GetMaterial(); } Undo.RecordObject(mat, "Paste Material"); ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs if (mat.HasProperty(ShaderUtilities.ID_GradientScale)) { // Preserve unique SDF properties from destination material. m_copiedProperties.SetTexture(ShaderUtilities.ID_MainTex, mat.GetTexture(ShaderUtilities.ID_MainTex)); m_copiedProperties.SetFloat(ShaderUtilities.ID_GradientScale, mat.GetFloat(ShaderUtilities.ID_GradientScale)); m_copiedProperties.SetFloat(ShaderUtilities.ID_TextureWidth, mat.GetFloat(ShaderUtilities.ID_TextureWidth)); m_copiedProperties.SetFloat(ShaderUtilities.ID_TextureHeight, mat.GetFloat(ShaderUtilities.ID_TextureHeight)); } EditorShaderUtilities.CopyMaterialProperties(m_copiedProperties, mat); // Copy ShaderKeywords from one material to the other. mat.shaderKeywords = m_copiedProperties.shaderKeywords; // Let TextMeshPro Objects that this mat has changed. TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, mat); } // Enable Resetting of Material properties without losing unique properties of the font atlas. [MenuItem("CONTEXT/Material/Reset", false, 2100)] static void ResetSettings(MenuCommand command) { Material mat = null; if (command.context.GetType() == typeof(Material)) mat = (Material)command.context; else { mat = Selection.activeGameObject.GetComponent().GetMaterial(); } Undo.RecordObject(mat, "Reset Material"); ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs if (mat.HasProperty(ShaderUtilities.ID_GradientScale)) { // Copy unique properties of the SDF Material var texture = mat.GetTexture(ShaderUtilities.ID_MainTex); var gradientScale = mat.GetFloat(ShaderUtilities.ID_GradientScale); var texWidth = mat.GetFloat(ShaderUtilities.ID_TextureWidth); var texHeight = mat.GetFloat(ShaderUtilities.ID_TextureHeight); var stencilId = 0.0f; var stencilComp = 0.0f; if (mat.HasProperty(ShaderUtilities.ID_StencilID)) { stencilId = mat.GetFloat(ShaderUtilities.ID_StencilID); stencilComp = mat.GetFloat(ShaderUtilities.ID_StencilComp); } var normalWeight = mat.GetFloat(ShaderUtilities.ID_WeightNormal); var boldWeight = mat.GetFloat(ShaderUtilities.ID_WeightBold); // Reset the material Unsupported.SmartReset(mat); // Reset ShaderKeywords mat.shaderKeywords = new string[0]; // { "BEVEL_OFF", "GLOW_OFF", "UNDERLAY_OFF" }; // Copy unique material properties back to the material. mat.SetTexture(ShaderUtilities.ID_MainTex, texture); mat.SetFloat(ShaderUtilities.ID_GradientScale, gradientScale); mat.SetFloat(ShaderUtilities.ID_TextureWidth, texWidth); mat.SetFloat(ShaderUtilities.ID_TextureHeight, texHeight); if (mat.HasProperty(ShaderUtilities.ID_StencilID)) { mat.SetFloat(ShaderUtilities.ID_StencilID, stencilId); mat.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp); } mat.SetFloat(ShaderUtilities.ID_WeightNormal, normalWeight); mat.SetFloat(ShaderUtilities.ID_WeightBold, boldWeight); } else { Unsupported.SmartReset(mat); } TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, mat); } //This function is used for debugging and fixing potentially broken font atlas links. [MenuItem("CONTEXT/Material/Copy Atlas", false, 2000)] static void CopyAtlas(MenuCommand command) { Material mat = command.context as Material; m_copiedAtlasProperties = new Material(mat); m_copiedAtlasProperties.hideFlags = HideFlags.DontSave; } // This function is used for debugging and fixing potentially broken font atlas links [MenuItem("CONTEXT/Material/Paste Atlas", false, 2001)] static void PasteAtlas(MenuCommand command) { Material mat = command.context as Material; if (m_copiedAtlasProperties != null) { Undo.RecordObject(mat, "Paste Texture"); ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs mat.SetTexture(ShaderUtilities.ID_MainTex, m_copiedAtlasProperties.GetTexture(ShaderUtilities.ID_MainTex)); mat.SetFloat(ShaderUtilities.ID_GradientScale, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_GradientScale)); mat.SetFloat(ShaderUtilities.ID_TextureWidth, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureWidth)); mat.SetFloat(ShaderUtilities.ID_TextureHeight, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureHeight)); } else if (m_copiedTexture != null) { Undo.RecordObject(mat, "Paste Texture"); mat.SetTexture(ShaderUtilities.ID_MainTex, m_copiedTexture); } //DestroyImmediate(m_copiedAtlasProperties); } // Context Menus for TMPro Font Assets //This function is used for debugging and fixing potentially broken font atlas links. [MenuItem("CONTEXT/TMP_FontAsset/Extract Atlas", false, 2100)] static void ExtractAtlas(MenuCommand command) { TMP_FontAsset font = command.context as TMP_FontAsset; string fontPath = AssetDatabase.GetAssetPath(font); string texPath = Path.GetDirectoryName(fontPath) + "/" + Path.GetFileNameWithoutExtension(fontPath) + " Atlas.png"; // Create a Serialized Object of the texture to allow us to make it readable. SerializedObject texprop = new SerializedObject(font.material.GetTexture(ShaderUtilities.ID_MainTex)); texprop.FindProperty("m_IsReadable").boolValue = true; texprop.ApplyModifiedProperties(); // Create a copy of the texture. Texture2D tex = Instantiate(font.material.GetTexture(ShaderUtilities.ID_MainTex)) as Texture2D; // Set the texture to not readable again. texprop.FindProperty("m_IsReadable").boolValue = false; texprop.ApplyModifiedProperties(); Debug.Log(texPath); // Saving File for Debug var pngData = tex.EncodeToPNG(); File.WriteAllBytes(texPath, pngData); AssetDatabase.Refresh(); DestroyImmediate(tex); } /// /// /// /// [MenuItem("CONTEXT/TMP_FontAsset/Update Atlas Texture...", false, 2000)] static void RegenerateFontAsset(MenuCommand command) { TMP_FontAsset fontAsset = command.context as TMP_FontAsset; if (fontAsset != null) { TMPro_FontAssetCreatorWindow.ShowFontAtlasCreatorWindow(fontAsset); } } /// /// Clear Font Asset Data /// /// [MenuItem("CONTEXT/TMP_FontAsset/Reset", false, 100)] static void ClearFontAssetData(MenuCommand command) { TMP_FontAsset fontAsset = command.context as TMP_FontAsset; if (fontAsset != null && Selection.activeObject != fontAsset) { Selection.activeObject = fontAsset; } fontAsset.ClearFontAssetData(true); TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset); } [MenuItem("CONTEXT/TrueTypeFontImporter/Create TMP Font Asset...", false, 200)] static void CreateFontAsset(MenuCommand command) { TrueTypeFontImporter importer = command.context as TrueTypeFontImporter; if (importer != null) { Font sourceFontFile = AssetDatabase.LoadAssetAtPath(importer.assetPath); if (sourceFontFile) TMPro_FontAssetCreatorWindow.ShowFontAtlasCreatorWindow(sourceFontFile); } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_ContextMenus.cs.meta ================================================ fileFormatVersion: 2 guid: 44e1d646473a40178712cb2150f54cec MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_CreateObjectMenu.cs ================================================ using UnityEngine; using UnityEditor; using UnityEditor.SceneManagement; using UnityEditor.Experimental.SceneManagement; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.EventSystems; namespace TMPro.EditorUtilities { public static class TMPro_CreateObjectMenu { /// /// Create a TextMeshPro object that works with the Mesh Renderer /// /// [MenuItem("GameObject/3D Object/Text - TextMeshPro", false, 30)] static void CreateTextMeshProObjectPerform(MenuCommand command) { GameObject go = new GameObject("Text (TMP)"); // Add support for new prefab mode StageUtility.PlaceGameObjectInCurrentStage(go); TextMeshPro textMeshPro = go.AddComponent(); textMeshPro.text = "Sample text"; textMeshPro.alignment = TextAlignmentOptions.TopLeft; Undo.RegisterCreatedObjectUndo((Object)go, "Create " + go.name); GameObject contextObject = command.context as GameObject; if (contextObject != null) { GameObjectUtility.SetParentAndAlign(go, contextObject); Undo.SetTransformParent(go.transform, contextObject.transform, "Parent " + go.name); } Selection.activeGameObject = go; } /// /// Create a TextMeshPro object that works with the CanvasRenderer /// /// [MenuItem("GameObject/UI/Text - TextMeshPro", false, 2001)] static void CreateTextMeshProGuiObjectPerform(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateText(GetStandardResources()); // Override text color and font size TMP_Text textComponent = go.GetComponent(); textComponent.color = Color.white; if (textComponent.m_isWaitingOnResourceLoad == false) textComponent.fontSize = TMP_Settings.defaultFontSize; PlaceUIElementRoot(go, menuCommand); } [MenuItem("GameObject/UI/Button - TextMeshPro", false, 2031)] static public void AddButton(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateButton(GetStandardResources()); // Override font size TMP_Text textComponent = go.GetComponentInChildren(); textComponent.fontSize = 24; PlaceUIElementRoot(go, menuCommand); } [MenuItem("GameObject/UI/Input Field - TextMeshPro", false, 2037)] static void AddTextMeshProInputField(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateInputField(GetStandardResources()); PlaceUIElementRoot(go, menuCommand); } [MenuItem("GameObject/UI/Dropdown - TextMeshPro", false, 2036)] static public void AddDropdown(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateDropdown(GetStandardResources()); PlaceUIElementRoot(go, menuCommand); } private const string kUILayerName = "UI"; private const string kStandardSpritePath = "UI/Skin/UISprite.psd"; private const string kBackgroundSpritePath = "UI/Skin/Background.psd"; private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd"; private const string kKnobPath = "UI/Skin/Knob.psd"; private const string kCheckmarkPath = "UI/Skin/Checkmark.psd"; private const string kDropdownArrowPath = "UI/Skin/DropdownArrow.psd"; private const string kMaskPath = "UI/Skin/UIMask.psd"; static private TMP_DefaultControls.Resources s_StandardResources; static private TMP_DefaultControls.Resources GetStandardResources() { if (s_StandardResources.standard == null) { s_StandardResources.standard = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath); s_StandardResources.background = AssetDatabase.GetBuiltinExtraResource(kBackgroundSpritePath); s_StandardResources.inputField = AssetDatabase.GetBuiltinExtraResource(kInputFieldBackgroundPath); s_StandardResources.knob = AssetDatabase.GetBuiltinExtraResource(kKnobPath); s_StandardResources.checkmark = AssetDatabase.GetBuiltinExtraResource(kCheckmarkPath); s_StandardResources.dropdown = AssetDatabase.GetBuiltinExtraResource(kDropdownArrowPath); s_StandardResources.mask = AssetDatabase.GetBuiltinExtraResource(kMaskPath); } return s_StandardResources; } private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform) { // Find the best scene view SceneView sceneView = SceneView.lastActiveSceneView; if (sceneView == null && SceneView.sceneViews.Count > 0) sceneView = SceneView.sceneViews[0] as SceneView; // Couldn't find a SceneView. Don't set position. if (sceneView == null || sceneView.camera == null) return; // Create world space Plane from canvas position. Camera camera = sceneView.camera; Vector3 position = Vector3.zero; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRTransform, new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2), camera, out Vector2 localPlanePosition)) { // Adjust for canvas pivot localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x; localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y; localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x); localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y); // Adjust for anchoring position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x; position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y; Vector3 minLocalPosition; minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) + itemTransform.sizeDelta.x * itemTransform.pivot.x; minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) + itemTransform.sizeDelta.y * itemTransform.pivot.y; Vector3 maxLocalPosition; maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) - itemTransform.sizeDelta.x * itemTransform.pivot.x; maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) - itemTransform.sizeDelta.y * itemTransform.pivot.y; position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x); position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y); } itemTransform.anchoredPosition = position; itemTransform.localRotation = Quaternion.identity; itemTransform.localScale = Vector3.one; } private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand) { GameObject parent = menuCommand.context as GameObject; bool explicitParentChoice = true; if (parent == null) { parent = GetOrCreateCanvasGameObject(); explicitParentChoice = false; // If in Prefab Mode, Canvas has to be part of Prefab contents, // otherwise use Prefab root instead. PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null && !prefabStage.IsPartOfPrefabContents(parent)) parent = prefabStage.prefabContentsRoot; } if (parent.GetComponentInParent() == null) { // Create canvas under context GameObject, // and make that be the parent which UI element is added under. GameObject canvas = CreateNewUI(); canvas.transform.SetParent(parent.transform, false); parent = canvas; } // Setting the element to be a child of an element already in the scene should // be sufficient to also move the element to that scene. // However, it seems the element needs to be already in its destination scene when the // RegisterCreatedObjectUndo is performed; otherwise the scene it was created in is dirtied. SceneManager.MoveGameObjectToScene(element, parent.scene); if (element.transform.parent == null) { Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name); } GameObjectUtility.EnsureUniqueNameForSibling(element); // We have to fix up the undo name since the name of the object was only known after reparenting it. Undo.SetCurrentGroupName("Create " + element.name); GameObjectUtility.SetParentAndAlign(element, parent); if (!explicitParentChoice) // not a context click, so center in sceneview SetPositionVisibleinSceneView(parent.GetComponent(), element.GetComponent()); Undo.RegisterCreatedObjectUndo(element, "Create " + element.name); Selection.activeGameObject = element; } static public GameObject CreateNewUI() { // Root for the UI var root = new GameObject("Canvas"); root.layer = LayerMask.NameToLayer(kUILayerName); Canvas canvas = root.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; root.AddComponent(); root.AddComponent(); // Works for all stages. StageUtility.PlaceGameObjectInCurrentStage(root); bool customScene = false; PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { root.transform.SetParent(prefabStage.prefabContentsRoot.transform, false); customScene = true; } Undo.RegisterCreatedObjectUndo(root, "Create " + root.name); // If there is no event system add one... // No need to place event system in custom scene as these are temporary anyway. // It can be argued for or against placing it in the user scenes, // but let's not modify scene user is not currently looking at. if (!customScene) CreateEventSystem(false); return root; } private static void CreateEventSystem(bool select) { CreateEventSystem(select, null); } private static void CreateEventSystem(bool select, GameObject parent) { var esys = Object.FindObjectOfType(); if (esys == null) { var eventSystem = new GameObject("EventSystem"); GameObjectUtility.SetParentAndAlign(eventSystem, parent); esys = eventSystem.AddComponent(); eventSystem.AddComponent(); Undo.RegisterCreatedObjectUndo(eventSystem, "Create " + eventSystem.name); } if (select && esys != null) { Selection.activeGameObject = esys.gameObject; } } // Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas. static public GameObject GetOrCreateCanvasGameObject() { GameObject selectedGo = Selection.activeGameObject; // Try to find a gameobject that is the selected GO or one if its parents. Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent() : null; if (IsValidCanvas(canvas)) return canvas.gameObject; // No canvas in selection or its parents? Then use any valid canvas. // We have to find all loaded Canvases, not just the ones in main scenes. Canvas[] canvasArray = StageUtility.GetCurrentStageHandle().FindComponentsOfType(); for (int i = 0; i < canvasArray.Length; i++) if (IsValidCanvas(canvasArray[i])) return canvasArray[i].gameObject; // No canvas in the scene at all? Then create a new one. return CreateNewUI(); } static bool IsValidCanvas(Canvas canvas) { if (canvas == null || !canvas.gameObject.activeInHierarchy) return false; // It's important that the non-editable canvas from a prefab scene won't be rejected, // but canvases not visible in the Hierarchy at all do. Don't check for HideAndDontSave. if (EditorUtility.IsPersistent(canvas) || (canvas.hideFlags & HideFlags.HideInHierarchy) != 0) return false; if (StageUtility.GetStageHandle(canvas.gameObject) != StageUtility.GetCurrentStageHandle()) return false; return true; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_CreateObjectMenu.cs.meta ================================================ fileFormatVersion: 2 guid: 7065397ff8184621aa3ca4f854491259 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_EditorShaderUtilities.cs ================================================ using UnityEngine; using UnityEditor; using System.Linq; using System.Collections; namespace TMPro.EditorUtilities { public static class EditorShaderUtilities { /// /// Copy Shader properties from source to destination material. /// /// /// public static void CopyMaterialProperties(Material source, Material destination) { MaterialProperty[] source_prop = MaterialEditor.GetMaterialProperties(new Material[] { source }); for (int i = 0; i < source_prop.Length; i++) { int property_ID = Shader.PropertyToID(source_prop[i].name); if (destination.HasProperty(property_ID)) { //Debug.Log(source_prop[i].name + " Type:" + ShaderUtil.GetPropertyType(source.shader, i)); switch (ShaderUtil.GetPropertyType(source.shader, i)) { case ShaderUtil.ShaderPropertyType.Color: destination.SetColor(property_ID, source.GetColor(property_ID)); break; case ShaderUtil.ShaderPropertyType.Float: destination.SetFloat(property_ID, source.GetFloat(property_ID)); break; case ShaderUtil.ShaderPropertyType.Range: destination.SetFloat(property_ID, source.GetFloat(property_ID)); break; case ShaderUtil.ShaderPropertyType.TexEnv: destination.SetTexture(property_ID, source.GetTexture(property_ID)); break; case ShaderUtil.ShaderPropertyType.Vector: destination.SetVector(property_ID, source.GetVector(property_ID)); break; } } } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_EditorShaderUtilities.cs.meta ================================================ fileFormatVersion: 2 guid: aa76955fe5bb44f7915d91db8c7043c4 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_FontAssetCreatorWindow.cs ================================================ using System; using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Globalization; using System.Threading; using System.IO; using System.Text.RegularExpressions; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using Object = UnityEngine.Object; namespace TMPro.EditorUtilities { public class TMPro_FontAssetCreatorWindow : EditorWindow { [MenuItem("Window/TextMeshPro/Font Asset Creator", false, 2025)] public static void ShowFontAtlasCreatorWindow() { var window = GetWindow(); window.titleContent = new GUIContent("Font Asset Creator"); window.Focus(); // Make sure TMP Essential Resources have been imported. window.CheckEssentialResources(); } public static void ShowFontAtlasCreatorWindow(Font sourceFontFile) { var window = GetWindow(); window.titleContent = new GUIContent("Font Asset Creator"); window.Focus(); window.ClearGeneratedData(); window.m_LegacyFontAsset = null; window.m_SelectedFontAsset = null; // Override selected font asset window.m_SourceFontFile = sourceFontFile; // Make sure TMP Essential Resources have been imported. window.CheckEssentialResources(); } public static void ShowFontAtlasCreatorWindow(TMP_FontAsset fontAsset) { var window = GetWindow(); window.titleContent = new GUIContent("Font Asset Creator"); window.Focus(); // Clear any previously generated data window.ClearGeneratedData(); window.m_LegacyFontAsset = null; // Load font asset creation settings if we have valid settings if (string.IsNullOrEmpty(fontAsset.creationSettings.sourceFontFileGUID) == false) { window.LoadFontCreationSettings(fontAsset.creationSettings); // Override settings to inject character list from font asset window.m_CharacterSetSelectionMode = 6; window.m_CharacterSequence = TMP_EditorUtility.GetUnicodeCharacterSequence(TMP_FontAsset.GetCharactersArray(fontAsset)); window.m_ReferencedFontAsset = fontAsset; window.m_SavedFontAtlas = fontAsset.atlasTexture; } else { window.m_WarningMessage = "Font Asset [" + fontAsset.name + "] does not contain any previous \"Font Asset Creation Settings\". This usually means [" + fontAsset.name + "] was created before this new functionality was added."; window.m_SourceFontFile = null; window.m_LegacyFontAsset = fontAsset; } // Even if we don't have any saved generation settings, we still want to pre-select the source font file. window.m_SelectedFontAsset = fontAsset; // Make sure TMP Essential Resources have been imported. window.CheckEssentialResources(); } [System.Serializable] class FontAssetCreationSettingsContainer { public List fontAssetCreationSettings; } FontAssetCreationSettingsContainer m_FontAssetCreationSettingsContainer; //static readonly string[] m_FontCreationPresets = new string[] { "Recent 1", "Recent 2", "Recent 3", "Recent 4" }; int m_FontAssetCreationSettingsCurrentIndex = 0; const string k_FontAssetCreationSettingsContainerKey = "TextMeshPro.FontAssetCreator.RecentFontAssetCreationSettings.Container"; const string k_FontAssetCreationSettingsCurrentIndexKey = "TextMeshPro.FontAssetCreator.RecentFontAssetCreationSettings.CurrentIndex"; const float k_TwoColumnControlsWidth = 335f; // Diagnostics System.Diagnostics.Stopwatch m_StopWatch; double m_GlyphPackingGenerationTime; double m_GlyphRenderingGenerationTime; string[] m_FontSizingOptions = { "Auto Sizing", "Custom Size" }; int m_PointSizeSamplingMode; string[] m_FontResolutionLabels = { "8", "16","32", "64", "128", "256", "512", "1024", "2048", "4096", "8192" }; int[] m_FontAtlasResolutions = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; string[] m_FontCharacterSets = { "ASCII", "Extended ASCII", "ASCII Lowercase", "ASCII Uppercase", "Numbers + Symbols", "Custom Range", "Unicode Range (Hex)", "Custom Characters", "Characters from File" }; enum FontPackingModes { Fast = 0, Optimum = 4 }; FontPackingModes m_PackingMode = FontPackingModes.Fast; int m_CharacterSetSelectionMode; string m_CharacterSequence = ""; string m_OutputFeedback = ""; string m_WarningMessage; int m_CharacterCount; Vector2 m_ScrollPosition; Vector2 m_OutputScrollPosition; bool m_IsRepaintNeeded; float m_AtlasGenerationProgress; string m_AtlasGenerationProgressLabel = string.Empty; float m_RenderingProgress; bool m_IsRenderingDone; bool m_IsProcessing; bool m_IsGenerationDisabled; bool m_IsGenerationCancelled; bool m_IsFontAtlasInvalid; Object m_SourceFontFile; TMP_FontAsset m_SelectedFontAsset; TMP_FontAsset m_LegacyFontAsset; TMP_FontAsset m_ReferencedFontAsset; TextAsset m_CharactersFromFile; int m_PointSize; int m_Padding = 5; //FaceStyles m_FontStyle = FaceStyles.Normal; //float m_FontStyleValue = 2; GlyphRenderMode m_GlyphRenderMode = GlyphRenderMode.SDFAA; int m_AtlasWidth = 512; int m_AtlasHeight = 512; byte[] m_AtlasTextureBuffer; Texture2D m_FontAtlasTexture; Texture2D m_SavedFontAtlas; // List m_FontGlyphTable = new List(); List m_FontCharacterTable = new List(); Dictionary m_CharacterLookupMap = new Dictionary(); Dictionary> m_GlyphLookupMap = new Dictionary>(); List m_GlyphsToPack = new List(); List m_GlyphsPacked = new List(); List m_FreeGlyphRects = new List(); List m_UsedGlyphRects = new List(); List m_GlyphsToRender = new List(); List m_AvailableGlyphsToAdd = new List(); List m_MissingCharacters = new List(); List m_ExcludedCharacters = new List(); private FaceInfo m_FaceInfo; bool m_IncludeFontFeatures; public void OnEnable() { // Used for Diagnostics m_StopWatch = new System.Diagnostics.Stopwatch(); // Set Editor window size. minSize = new Vector2(315, minSize.y); // Initialize & Get shader property IDs. ShaderUtilities.GetShaderPropertyIDs(); // Load last selected preset if we are not already in the process of regenerating an existing font asset (via the Context menu) if (EditorPrefs.HasKey(k_FontAssetCreationSettingsContainerKey)) { if (m_FontAssetCreationSettingsContainer == null) m_FontAssetCreationSettingsContainer = JsonUtility.FromJson(EditorPrefs.GetString(k_FontAssetCreationSettingsContainerKey)); if (m_FontAssetCreationSettingsContainer.fontAssetCreationSettings != null && m_FontAssetCreationSettingsContainer.fontAssetCreationSettings.Count > 0) { // Load Font Asset Creation Settings preset. if (EditorPrefs.HasKey(k_FontAssetCreationSettingsCurrentIndexKey)) m_FontAssetCreationSettingsCurrentIndex = EditorPrefs.GetInt(k_FontAssetCreationSettingsCurrentIndexKey); LoadFontCreationSettings(m_FontAssetCreationSettingsContainer.fontAssetCreationSettings[m_FontAssetCreationSettingsCurrentIndex]); } } ClearGeneratedData(); } public void OnDisable() { //Debug.Log("TextMeshPro Editor Window has been disabled."); // Destroy Engine only if it has been initialized already FontEngine.DestroyFontEngine(); ClearGeneratedData(); // Remove Glyph Report if one was created. if (File.Exists("Assets/TextMesh Pro/Glyph Report.txt")) { File.Delete("Assets/TextMesh Pro/Glyph Report.txt"); File.Delete("Assets/TextMesh Pro/Glyph Report.txt.meta"); AssetDatabase.Refresh(); } // Save Font Asset Creation Settings Index SaveCreationSettingsToEditorPrefs(SaveFontCreationSettings()); EditorPrefs.SetInt(k_FontAssetCreationSettingsCurrentIndexKey, m_FontAssetCreationSettingsCurrentIndex); // Unregister to event TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED); Resources.UnloadUnusedAssets(); } // Event received when TMP resources have been loaded. void ON_RESOURCES_LOADED() { TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED); m_IsGenerationDisabled = false; } // Make sure TMP Essential Resources have been imported. void CheckEssentialResources() { if (TMP_Settings.instance == null) { if (m_IsGenerationDisabled == false) TMPro_EventManager.RESOURCE_LOAD_EVENT.Add(ON_RESOURCES_LOADED); m_IsGenerationDisabled = true; } } public void OnGUI() { GUILayout.BeginHorizontal(); DrawControls(); if (position.width > position.height && position.width > k_TwoColumnControlsWidth) { DrawPreview(); } GUILayout.EndHorizontal(); } public void Update() { if (m_IsRepaintNeeded) { //Debug.Log("Repainting..."); m_IsRepaintNeeded = false; Repaint(); } // Update Progress bar is we are Rendering a Font. if (m_IsProcessing) { m_AtlasGenerationProgress = FontEngine.generationProgress; m_IsRepaintNeeded = true; } // Update Feedback Window & Create Font Texture once Rendering is done. if (m_IsRenderingDone) { m_IsProcessing = false; m_IsRenderingDone = false; if (m_IsGenerationCancelled == false) { m_AtlasGenerationProgressLabel = "Generation completed in: " + (m_GlyphPackingGenerationTime + m_GlyphRenderingGenerationTime).ToString("0.00 ms."); UpdateRenderFeedbackWindow(); CreateFontAtlasTexture(); // If dynamic make readable ... m_FontAtlasTexture.Apply(false, false); } Repaint(); } } /// /// Method which returns the character corresponding to a decimal value. /// /// /// static uint[] ParseNumberSequence(string sequence) { List unicodeList = new List(); string[] sequences = sequence.Split(','); foreach (string seq in sequences) { string[] s1 = seq.Split('-'); if (s1.Length == 1) try { unicodeList.Add(uint.Parse(s1[0])); } catch { Debug.Log("No characters selected or invalid format."); } else { for (uint j = uint.Parse(s1[0]); j < uint.Parse(s1[1]) + 1; j++) { unicodeList.Add(j); } } } return unicodeList.ToArray(); } /// /// Method which returns the character (decimal value) from a hex sequence. /// /// /// static uint[] ParseHexNumberSequence(string sequence) { List unicodeList = new List(); string[] sequences = sequence.Split(','); foreach (string seq in sequences) { string[] s1 = seq.Split('-'); if (s1.Length == 1) try { unicodeList.Add(uint.Parse(s1[0], NumberStyles.AllowHexSpecifier)); } catch { Debug.Log("No characters selected or invalid format."); } else { for (uint j = uint.Parse(s1[0], NumberStyles.AllowHexSpecifier); j < uint.Parse(s1[1], NumberStyles.AllowHexSpecifier) + 1; j++) { unicodeList.Add(j); } } } return unicodeList.ToArray(); } void DrawControls() { GUILayout.Space(5f); if (position.width > position.height && position.width > k_TwoColumnControlsWidth) { m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition, GUILayout.Width(315)); } else { m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition); } GUILayout.Space(5f); GUILayout.Label(m_SelectedFontAsset != null ? string.Format("Font Settings [{0}]", m_SelectedFontAsset.name) : "Font Settings", EditorStyles.boldLabel); EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUIUtility.labelWidth = 125f; EditorGUIUtility.fieldWidth = 5f; // Disable Options if already generating a font atlas texture. EditorGUI.BeginDisabledGroup(m_IsProcessing); { // FONT TTF SELECTION EditorGUI.BeginChangeCheck(); m_SourceFontFile = EditorGUILayout.ObjectField("Source Font File", m_SourceFontFile, typeof(Font), false) as Font; if (EditorGUI.EndChangeCheck()) { m_SelectedFontAsset = null; m_IsFontAtlasInvalid = true; } // FONT SIZING EditorGUI.BeginChangeCheck(); if (m_PointSizeSamplingMode == 0) { m_PointSizeSamplingMode = EditorGUILayout.Popup("Sampling Point Size", m_PointSizeSamplingMode, m_FontSizingOptions); } else { GUILayout.BeginHorizontal(); m_PointSizeSamplingMode = EditorGUILayout.Popup("Sampling Point Size", m_PointSizeSamplingMode, m_FontSizingOptions, GUILayout.Width(225)); m_PointSize = EditorGUILayout.IntField(m_PointSize); GUILayout.EndHorizontal(); } if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } // FONT PADDING EditorGUI.BeginChangeCheck(); m_Padding = EditorGUILayout.IntField("Padding", m_Padding); m_Padding = (int)Mathf.Clamp(m_Padding, 0f, 64f); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } // FONT PACKING METHOD SELECTION EditorGUI.BeginChangeCheck(); m_PackingMode = (FontPackingModes)EditorGUILayout.EnumPopup("Packing Method", m_PackingMode); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } // FONT ATLAS RESOLUTION SELECTION GUILayout.BeginHorizontal(); GUI.changed = false; EditorGUI.BeginChangeCheck(); EditorGUILayout.PrefixLabel("Atlas Resolution"); m_AtlasWidth = EditorGUILayout.IntPopup(m_AtlasWidth, m_FontResolutionLabels, m_FontAtlasResolutions); m_AtlasHeight = EditorGUILayout.IntPopup(m_AtlasHeight, m_FontResolutionLabels, m_FontAtlasResolutions); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } GUILayout.EndHorizontal(); // FONT CHARACTER SET SELECTION EditorGUI.BeginChangeCheck(); bool hasSelectionChanged = false; m_CharacterSetSelectionMode = EditorGUILayout.Popup("Character Set", m_CharacterSetSelectionMode, m_FontCharacterSets); if (EditorGUI.EndChangeCheck()) { m_CharacterSequence = ""; hasSelectionChanged = true; m_IsFontAtlasInvalid = true; } switch (m_CharacterSetSelectionMode) { case 0: // ASCII //characterSequence = "32 - 126, 130, 132 - 135, 139, 145 - 151, 153, 155, 161, 166 - 167, 169 - 174, 176, 181 - 183, 186 - 187, 191, 8210 - 8226, 8230, 8240, 8242 - 8244, 8249 - 8250, 8252 - 8254, 8260, 8286"; m_CharacterSequence = "32 - 126, 160, 8203, 8230, 9633"; break; case 1: // EXTENDED ASCII m_CharacterSequence = "32 - 126, 160 - 255, 8192 - 8303, 8364, 8482, 9633"; // Could add 9632 for missing glyph break; case 2: // Lowercase m_CharacterSequence = "32 - 64, 91 - 126, 160"; break; case 3: // Uppercase m_CharacterSequence = "32 - 96, 123 - 126, 160"; break; case 4: // Numbers & Symbols m_CharacterSequence = "32 - 64, 91 - 96, 123 - 126, 160"; break; case 5: // Custom Range EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label("Enter a sequence of decimal values to define the characters to be included in the font asset or retrieve one from another font asset.", TMP_UIStyleManager.label); GUILayout.Space(10f); EditorGUI.BeginChangeCheck(); m_ReferencedFontAsset = EditorGUILayout.ObjectField("Select Font Asset", m_ReferencedFontAsset, typeof(TMP_FontAsset), false) as TMP_FontAsset; if (EditorGUI.EndChangeCheck() || hasSelectionChanged) { if (m_ReferencedFontAsset != null) m_CharacterSequence = TMP_EditorUtility.GetDecimalCharacterSequence(TMP_FontAsset.GetCharactersArray(m_ReferencedFontAsset)); m_IsFontAtlasInvalid = true; } // Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < ',' || chr > '-')) { Event.current.character = '\0'; } GUILayout.Label("Character Sequence (Decimal)", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); m_CharacterSequence = EditorGUILayout.TextArea(m_CharacterSequence, TMP_UIStyleManager.textAreaBoxWindow, GUILayout.Height(120), GUILayout.ExpandWidth(true)); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } EditorGUILayout.EndVertical(); break; case 6: // Unicode HEX Range EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label("Enter a sequence of Unicode (hex) values to define the characters to be included in the font asset or retrieve one from another font asset.", TMP_UIStyleManager.label); GUILayout.Space(10f); EditorGUI.BeginChangeCheck(); m_ReferencedFontAsset = EditorGUILayout.ObjectField("Select Font Asset", m_ReferencedFontAsset, typeof(TMP_FontAsset), false) as TMP_FontAsset; if (EditorGUI.EndChangeCheck() || hasSelectionChanged) { if (m_ReferencedFontAsset != null) m_CharacterSequence = TMP_EditorUtility.GetUnicodeCharacterSequence(TMP_FontAsset.GetCharactersArray(m_ReferencedFontAsset)); m_IsFontAtlasInvalid = true; } // Filter out unwanted characters. chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F') && (chr < ',' || chr > '-')) { Event.current.character = '\0'; } GUILayout.Label("Character Sequence (Hex)", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); m_CharacterSequence = EditorGUILayout.TextArea(m_CharacterSequence, TMP_UIStyleManager.textAreaBoxWindow, GUILayout.Height(120), GUILayout.ExpandWidth(true)); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } EditorGUILayout.EndVertical(); break; case 7: // Characters from Font Asset EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.Label("Type the characters to be included in the font asset or retrieve them from another font asset.", TMP_UIStyleManager.label); GUILayout.Space(10f); EditorGUI.BeginChangeCheck(); m_ReferencedFontAsset = EditorGUILayout.ObjectField("Select Font Asset", m_ReferencedFontAsset, typeof(TMP_FontAsset), false) as TMP_FontAsset; if (EditorGUI.EndChangeCheck() || hasSelectionChanged) { if (m_ReferencedFontAsset != null) m_CharacterSequence = TMP_FontAsset.GetCharacters(m_ReferencedFontAsset); m_IsFontAtlasInvalid = true; } EditorGUI.indentLevel = 0; GUILayout.Label("Custom Character List", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); m_CharacterSequence = EditorGUILayout.TextArea(m_CharacterSequence, TMP_UIStyleManager.textAreaBoxWindow, GUILayout.Height(120), GUILayout.ExpandWidth(true)); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } EditorGUILayout.EndVertical(); break; case 8: // Character List from File EditorGUI.BeginChangeCheck(); m_CharactersFromFile = EditorGUILayout.ObjectField("Character File", m_CharactersFromFile, typeof(TextAsset), false) as TextAsset; if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } if (m_CharactersFromFile != null) { Regex rx = new Regex(@"(? { if (match.Value.StartsWith("\\U")) return char.ConvertFromUtf32(int.Parse(match.Value.Replace("\\U", ""), NumberStyles.HexNumber)); return char.ConvertFromUtf32(int.Parse(match.Value.Replace("\\u", ""), NumberStyles.HexNumber)); }); } break; } // FONT STYLE SELECTION //GUILayout.BeginHorizontal(); //EditorGUI.BeginChangeCheck(); ////m_FontStyle = (FaceStyles)EditorGUILayout.EnumPopup("Font Style", m_FontStyle, GUILayout.Width(225)); ////m_FontStyleValue = EditorGUILayout.IntField((int)m_FontStyleValue); //if (EditorGUI.EndChangeCheck()) //{ // m_IsFontAtlasInvalid = true; //} //GUILayout.EndHorizontal(); // Render Mode Selection CheckForLegacyGlyphRenderMode(); EditorGUI.BeginChangeCheck(); m_GlyphRenderMode = (GlyphRenderMode)EditorGUILayout.EnumPopup("Render Mode", m_GlyphRenderMode); if (EditorGUI.EndChangeCheck()) { m_IsFontAtlasInvalid = true; } m_IncludeFontFeatures = EditorGUILayout.Toggle("Get Kerning Pairs", m_IncludeFontFeatures); EditorGUILayout.Space(); } EditorGUI.EndDisabledGroup(); if (!string.IsNullOrEmpty(m_WarningMessage)) { EditorGUILayout.HelpBox(m_WarningMessage, MessageType.Warning); } GUI.enabled = m_SourceFontFile != null && !m_IsProcessing && !m_IsGenerationDisabled; // Enable Preview if we are not already rendering a font. if (GUILayout.Button("Generate Font Atlas") && GUI.enabled) { if (!m_IsProcessing && m_SourceFontFile != null) { DestroyImmediate(m_FontAtlasTexture); m_FontAtlasTexture = null; m_SavedFontAtlas = null; // Initialize font engine FontEngineError errorCode = FontEngine.InitializeFontEngine(); if (errorCode != FontEngineError.Success) { Debug.Log("Font Asset Creator - Error [" + errorCode + "] has occurred while Initializing the FreeType Library."); } // Get file path of the source font file. string fontPath = AssetDatabase.GetAssetPath(m_SourceFontFile); if (errorCode == FontEngineError.Success) { errorCode = FontEngine.LoadFontFace(fontPath); if (errorCode != FontEngineError.Success) { Debug.Log("Font Asset Creator - Error Code [" + errorCode + "] has occurred trying to load the [" + m_SourceFontFile.name + "] font file. This typically results from the use of an incompatible or corrupted font file."); } } // Define an array containing the characters we will render. if (errorCode == FontEngineError.Success) { uint[] characterSet = null; // Get list of characters that need to be packed and rendered to the atlas texture. if (m_CharacterSetSelectionMode == 7 || m_CharacterSetSelectionMode == 8) { List char_List = new List(); for (int i = 0; i < m_CharacterSequence.Length; i++) { uint unicode = m_CharacterSequence[i]; // Handle surrogate pairs if (i < m_CharacterSequence.Length - 1 && char.IsHighSurrogate((char)unicode) && char.IsLowSurrogate(m_CharacterSequence[i + 1])) { unicode = (uint)char.ConvertToUtf32(m_CharacterSequence[i], m_CharacterSequence[i + 1]); i += 1; } // Check to make sure we don't include duplicates if (char_List.FindIndex(item => item == unicode) == -1) char_List.Add(unicode); } characterSet = char_List.ToArray(); } else if (m_CharacterSetSelectionMode == 6) { characterSet = ParseHexNumberSequence(m_CharacterSequence); } else { characterSet = ParseNumberSequence(m_CharacterSequence); } m_CharacterCount = characterSet.Length; m_AtlasGenerationProgress = 0; m_IsProcessing = true; m_IsGenerationCancelled = false; GlyphLoadFlags glyphLoadFlags = ((GlyphRasterModes)m_GlyphRenderMode & GlyphRasterModes.RASTER_MODE_HINTED) == GlyphRasterModes.RASTER_MODE_HINTED ? GlyphLoadFlags.LOAD_RENDER : GlyphLoadFlags.LOAD_RENDER | GlyphLoadFlags.LOAD_NO_HINTING; // AutoResetEvent autoEvent = new AutoResetEvent(false); // Worker thread to pack glyphs in the given texture space. ThreadPool.QueueUserWorkItem(PackGlyphs => { // Start Stop Watch m_StopWatch = System.Diagnostics.Stopwatch.StartNew(); // Clear the various lists used in the generation process. m_AvailableGlyphsToAdd.Clear(); m_MissingCharacters.Clear(); m_ExcludedCharacters.Clear(); m_CharacterLookupMap.Clear(); m_GlyphLookupMap.Clear(); m_GlyphsToPack.Clear(); m_GlyphsPacked.Clear(); // Check if requested characters are available in the source font file. for (int i = 0; i < characterSet.Length; i++) { uint unicode = characterSet[i]; if (FontEngine.TryGetGlyphIndex(unicode, out uint glyphIndex)) { // Skip over potential duplicate characters. if (m_CharacterLookupMap.ContainsKey(unicode)) continue; // Add character to character lookup map. m_CharacterLookupMap.Add(unicode, glyphIndex); // Skip over potential duplicate glyph references. if (m_GlyphLookupMap.ContainsKey(glyphIndex)) { // Add additional glyph reference for this character. m_GlyphLookupMap[glyphIndex].Add(unicode); continue; } // Add glyph reference to glyph lookup map. m_GlyphLookupMap.Add(glyphIndex, new List() { unicode }); // Add glyph index to list of glyphs to add to texture. m_AvailableGlyphsToAdd.Add(glyphIndex); } else { // Add Unicode to list of missing characters. m_MissingCharacters.Add(unicode); } } // Pack available glyphs in the provided texture space. if (m_AvailableGlyphsToAdd.Count > 0) { int packingModifier = ((GlyphRasterModes)m_GlyphRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP ? 0 : 1; if (m_PointSizeSamplingMode == 0) // Auto-Sizing Point Size Mode { // Estimate min / max range for auto sizing of point size. int minPointSize = 0; int maxPointSize = (int)Mathf.Sqrt((m_AtlasWidth * m_AtlasHeight) / m_AvailableGlyphsToAdd.Count) * 3; m_PointSize = (maxPointSize + minPointSize) / 2; bool optimumPointSizeFound = false; for (int iteration = 0; iteration < 15 && optimumPointSizeFound == false; iteration++) { m_AtlasGenerationProgressLabel = "Packing glyphs - Pass (" + iteration + ")"; FontEngine.SetFaceSize(m_PointSize); m_GlyphsToPack.Clear(); m_GlyphsPacked.Clear(); m_FreeGlyphRects.Clear(); m_FreeGlyphRects.Add(new GlyphRect(0, 0, m_AtlasWidth - packingModifier, m_AtlasHeight - packingModifier)); m_UsedGlyphRects.Clear(); for (int i = 0; i < m_AvailableGlyphsToAdd.Count; i++) { uint glyphIndex = m_AvailableGlyphsToAdd[i]; if (FontEngine.TryGetGlyphWithIndexValue(glyphIndex, glyphLoadFlags, out Glyph glyph)) { if (glyph.glyphRect.width > 0 && glyph.glyphRect.height > 0) { m_GlyphsToPack.Add(glyph); } else { m_GlyphsPacked.Add(glyph); } } } FontEngine.TryPackGlyphsInAtlas(m_GlyphsToPack, m_GlyphsPacked, m_Padding, (GlyphPackingMode)m_PackingMode, m_GlyphRenderMode, m_AtlasWidth, m_AtlasHeight, m_FreeGlyphRects, m_UsedGlyphRects); if (m_IsGenerationCancelled) { DestroyImmediate(m_FontAtlasTexture); m_FontAtlasTexture = null; return; } //Debug.Log("Glyphs remaining to add [" + m_GlyphsToAdd.Count + "]. Glyphs added [" + m_GlyphsAdded.Count + "]."); if (m_GlyphsToPack.Count > 0) { if (m_PointSize > minPointSize) { maxPointSize = m_PointSize; m_PointSize = (m_PointSize + minPointSize) / 2; //Debug.Log("Decreasing point size from [" + maxPointSize + "] to [" + m_PointSize + "]."); } } else { if (maxPointSize - minPointSize > 1 && m_PointSize < maxPointSize) { minPointSize = m_PointSize; m_PointSize = (m_PointSize + maxPointSize) / 2; //Debug.Log("Increasing point size from [" + minPointSize + "] to [" + m_PointSize + "]."); } else { //Debug.Log("[" + iteration + "] iterations to find the optimum point size of : [" + m_PointSize + "]."); optimumPointSizeFound = true; } } } } else // Custom Point Size Mode { m_AtlasGenerationProgressLabel = "Packing glyphs..."; // Set point size FontEngine.SetFaceSize(m_PointSize); m_GlyphsToPack.Clear(); m_GlyphsPacked.Clear(); m_FreeGlyphRects.Clear(); m_FreeGlyphRects.Add(new GlyphRect(0, 0, m_AtlasWidth - packingModifier, m_AtlasHeight - packingModifier)); m_UsedGlyphRects.Clear(); for (int i = 0; i < m_AvailableGlyphsToAdd.Count; i++) { uint glyphIndex = m_AvailableGlyphsToAdd[i]; if (FontEngine.TryGetGlyphWithIndexValue(glyphIndex, glyphLoadFlags, out Glyph glyph)) { if (glyph.glyphRect.width > 0 && glyph.glyphRect.height > 0) { m_GlyphsToPack.Add(glyph); } else { m_GlyphsPacked.Add(glyph); } } } FontEngine.TryPackGlyphsInAtlas(m_GlyphsToPack, m_GlyphsPacked, m_Padding, (GlyphPackingMode)m_PackingMode, m_GlyphRenderMode, m_AtlasWidth, m_AtlasHeight, m_FreeGlyphRects, m_UsedGlyphRects); if (m_IsGenerationCancelled) { DestroyImmediate(m_FontAtlasTexture); m_FontAtlasTexture = null; return; } //Debug.Log("Glyphs remaining to add [" + m_GlyphsToAdd.Count + "]. Glyphs added [" + m_GlyphsAdded.Count + "]."); } } else { int packingModifier = ((GlyphRasterModes)m_GlyphRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP ? 0 : 1; FontEngine.SetFaceSize(m_PointSize); m_GlyphsToPack.Clear(); m_GlyphsPacked.Clear(); m_FreeGlyphRects.Clear(); m_FreeGlyphRects.Add(new GlyphRect(0, 0, m_AtlasWidth - packingModifier, m_AtlasHeight - packingModifier)); m_UsedGlyphRects.Clear(); } //Stop StopWatch m_StopWatch.Stop(); m_GlyphPackingGenerationTime = m_StopWatch.Elapsed.TotalMilliseconds; Debug.Log("Glyph packing completed in: " + m_GlyphPackingGenerationTime.ToString("0.000 ms.")); m_StopWatch.Reset(); m_FontCharacterTable.Clear(); m_FontGlyphTable.Clear(); m_GlyphsToRender.Clear(); // Add glyphs and characters successfully added to texture to their respective font tables. foreach (Glyph glyph in m_GlyphsPacked) { uint glyphIndex = glyph.index; m_FontGlyphTable.Add(glyph); // Add glyphs to list of glyphs that need to be rendered. if (glyph.glyphRect.width > 0 && glyph.glyphRect.height > 0) m_GlyphsToRender.Add(glyph); foreach (uint unicode in m_GlyphLookupMap[glyphIndex]) { // Create new Character m_FontCharacterTable.Add(new TMP_Character(unicode, glyph)); } } // foreach (Glyph glyph in m_GlyphsToPack) { foreach (uint unicode in m_GlyphLookupMap[glyph.index]) { m_ExcludedCharacters.Add(unicode); } } // Get the face info for the current sampling point size. m_FaceInfo = FontEngine.GetFaceInfo(); autoEvent.Set(); }); // Worker thread to render glyphs in texture buffer. ThreadPool.QueueUserWorkItem(RenderGlyphs => { autoEvent.WaitOne(); // Start Stop Watch m_StopWatch = System.Diagnostics.Stopwatch.StartNew(); m_IsRenderingDone = false; // Allocate texture data m_AtlasTextureBuffer = new byte[m_AtlasWidth * m_AtlasHeight]; m_AtlasGenerationProgressLabel = "Rendering glyphs..."; // Render and add glyphs to the given atlas texture. if (m_GlyphsToRender.Count > 0) { FontEngine.RenderGlyphsToTexture(m_GlyphsToRender, m_Padding, m_GlyphRenderMode, m_AtlasTextureBuffer, m_AtlasWidth, m_AtlasHeight); } m_IsRenderingDone = true; // Stop StopWatch m_StopWatch.Stop(); m_GlyphRenderingGenerationTime = m_StopWatch.Elapsed.TotalMilliseconds; Debug.Log("Font Atlas generation completed in: " + m_GlyphRenderingGenerationTime.ToString("0.000 ms.")); m_StopWatch.Reset(); }); } SaveCreationSettingsToEditorPrefs(SaveFontCreationSettings()); } } // FONT RENDERING PROGRESS BAR GUILayout.Space(1); Rect progressRect = EditorGUILayout.GetControlRect(false, 20); GUI.enabled = true; progressRect.width -= 22; EditorGUI.ProgressBar(progressRect, Mathf.Max(0.01f, m_AtlasGenerationProgress), m_AtlasGenerationProgressLabel); progressRect.x = progressRect.x + progressRect.width + 2; progressRect.y -= 1; progressRect.width = 20; progressRect.height = 20; GUI.enabled = m_IsProcessing; if (GUI.Button(progressRect, "X")) { FontEngine.SendCancellationRequest(); m_AtlasGenerationProgress = 0; m_IsProcessing = false; m_IsGenerationCancelled = true; } GUILayout.Space(5); // FONT STATUS & INFORMATION GUI.enabled = true; GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(200)); m_OutputScrollPosition = EditorGUILayout.BeginScrollView(m_OutputScrollPosition); EditorGUILayout.LabelField(m_OutputFeedback, TMP_UIStyleManager.label); EditorGUILayout.EndScrollView(); GUILayout.EndVertical(); // SAVE TEXTURE & CREATE and SAVE FONT XML FILE GUI.enabled = m_FontAtlasTexture != null && !m_IsProcessing; // Enable Save Button if font_Atlas is not Null. EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Save") && GUI.enabled) { if (m_SelectedFontAsset == null) { if (m_LegacyFontAsset != null) SaveNewFontAssetWithSameName(m_LegacyFontAsset); else SaveNewFontAsset(m_SourceFontFile); } else { // Save over exiting Font Asset string filePath = Path.GetFullPath(AssetDatabase.GetAssetPath(m_SelectedFontAsset)).Replace('\\', '/'); if (((GlyphRasterModes)m_GlyphRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP) Save_Bitmap_FontAsset(filePath); else Save_SDF_FontAsset(filePath); } } if (GUILayout.Button("Save as...") && GUI.enabled) { if (m_SelectedFontAsset == null) { SaveNewFontAsset(m_SourceFontFile); } else { SaveNewFontAssetWithSameName(m_SelectedFontAsset); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.EndVertical(); GUI.enabled = true; // Re-enable GUI if (position.height > position.width || position.width < k_TwoColumnControlsWidth) { DrawPreview(); GUILayout.Space(5); } EditorGUILayout.EndScrollView(); if (m_IsFontAtlasInvalid) ClearGeneratedData(); } /// /// Clear the previously generated data. /// void ClearGeneratedData() { m_IsFontAtlasInvalid = false; if (m_FontAtlasTexture != null && !EditorUtility.IsPersistent(m_FontAtlasTexture)) { DestroyImmediate(m_FontAtlasTexture); m_FontAtlasTexture = null; } m_AtlasGenerationProgressLabel = string.Empty; m_AtlasGenerationProgress = 0; m_SavedFontAtlas = null; m_OutputFeedback = string.Empty; m_WarningMessage = string.Empty; } /// /// Function to update the feedback window showing the results of the latest generation. /// void UpdateRenderFeedbackWindow() { m_PointSize = m_FaceInfo.pointSize; string missingGlyphReport = string.Empty; //string colorTag = m_FontCharacterTable.Count == m_CharacterCount ? "" : ""; string colorTag2 = ""; missingGlyphReport = "Font: " + colorTag2 + m_FaceInfo.familyName + " Style: " + colorTag2 + m_FaceInfo.styleName + ""; missingGlyphReport += "\nPoint Size: " + colorTag2 + m_FaceInfo.pointSize + " SP/PD Ratio: " + colorTag2 + ((float)m_Padding / m_FaceInfo.pointSize).ToString("0.0%" + ""); missingGlyphReport += "\n\nCharacters included: " + m_FontCharacterTable.Count + "/" + m_CharacterCount + ""; missingGlyphReport += "\nMissing characters: " + m_MissingCharacters.Count + ""; missingGlyphReport += "\nExcluded characters: " + m_ExcludedCharacters.Count + ""; // Report characters missing from font file missingGlyphReport += "\n\nCharacters missing from font file:"; missingGlyphReport += "\n----------------------------------------"; m_OutputFeedback = missingGlyphReport; for (int i = 0; i < m_MissingCharacters.Count; i++) { missingGlyphReport += "\nID: " + m_MissingCharacters[i] + "\tHex: " + m_MissingCharacters[i].ToString("X") + "\tChar [" + (char)m_MissingCharacters[i] + "]"; if (missingGlyphReport.Length < 16300) m_OutputFeedback = missingGlyphReport; } // Report characters that did not fit in the atlas texture missingGlyphReport += "\n\nCharacters excluded from packing:"; missingGlyphReport += "\n----------------------------------------"; for (int i = 0; i < m_ExcludedCharacters.Count; i++) { missingGlyphReport += "\nID: " + m_ExcludedCharacters[i] + "\tHex: " + m_ExcludedCharacters[i].ToString("X") + "\tChar [" + (char)m_ExcludedCharacters[i] + "]"; if (missingGlyphReport.Length < 16300) m_OutputFeedback = missingGlyphReport; } if (missingGlyphReport.Length > 16300) m_OutputFeedback += "\n\nReport truncated.\nSee \"TextMesh Pro\\Glyph Report.txt\""; // Save Missing Glyph Report file if (Directory.Exists("Assets/TextMesh Pro")) { missingGlyphReport = System.Text.RegularExpressions.Regex.Replace(missingGlyphReport, @"<[^>]*>", string.Empty); File.WriteAllText("Assets/TextMesh Pro/Glyph Report.txt", missingGlyphReport); AssetDatabase.Refresh(); } } void CreateFontAtlasTexture() { if (m_FontAtlasTexture != null) DestroyImmediate(m_FontAtlasTexture); m_FontAtlasTexture = new Texture2D(m_AtlasWidth, m_AtlasHeight, TextureFormat.Alpha8, false, true); Color32[] colors = new Color32[m_AtlasWidth * m_AtlasHeight]; for (int i = 0; i < colors.Length; i++) { byte c = m_AtlasTextureBuffer[i]; colors[i] = new Color32(c, c, c, c); } // Clear allocation of m_AtlasTextureBuffer = null; if ((m_GlyphRenderMode & GlyphRenderMode.RASTER) == GlyphRenderMode.RASTER || (m_GlyphRenderMode & GlyphRenderMode.RASTER_HINTED) == GlyphRenderMode.RASTER_HINTED) m_FontAtlasTexture.filterMode = FilterMode.Point; m_FontAtlasTexture.SetPixels32(colors, 0); m_FontAtlasTexture.Apply(false, false); // Saving File for Debug //var pngData = m_FontAtlasTexture.EncodeToPNG(); //File.WriteAllBytes("Assets/Textures/Debug Font Texture.png", pngData); } /// /// Open Save Dialog to provide the option save the font asset using the name of the source font file. This also appends SDF to the name if using any of the SDF Font Asset creation modes. /// /// void SaveNewFontAsset(Object sourceObject) { string filePath; // Save new Font Asset and open save file requester at Source Font File location. string saveDirectory = new FileInfo(AssetDatabase.GetAssetPath(sourceObject)).DirectoryName; if (((GlyphRasterModes)m_GlyphRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP) { filePath = EditorUtility.SaveFilePanel("Save TextMesh Pro! Font Asset File", saveDirectory, sourceObject.name, "asset"); if (filePath.Length == 0) return; Save_Bitmap_FontAsset(filePath); } else { filePath = EditorUtility.SaveFilePanel("Save TextMesh Pro! Font Asset File", saveDirectory, sourceObject.name + " SDF", "asset"); if (filePath.Length == 0) return; Save_SDF_FontAsset(filePath); } } /// /// Open Save Dialog to provide the option to save the font asset under the same name. /// /// void SaveNewFontAssetWithSameName(Object sourceObject) { string filePath; // Save new Font Asset and open save file requester at Source Font File location. string saveDirectory = new FileInfo(AssetDatabase.GetAssetPath(sourceObject)).DirectoryName; filePath = EditorUtility.SaveFilePanel("Save TextMesh Pro! Font Asset File", saveDirectory, sourceObject.name, "asset"); if (filePath.Length == 0) return; if (((GlyphRasterModes)m_GlyphRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP) { Save_Bitmap_FontAsset(filePath); } else { Save_SDF_FontAsset(filePath); } } void Save_Bitmap_FontAsset(string filePath) { filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath. string dataPath = Application.dataPath; if (filePath.IndexOf(dataPath, System.StringComparison.InvariantCultureIgnoreCase) == -1) { Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\""); return; } string relativeAssetPath = filePath.Substring(dataPath.Length - 6); string tex_DirName = Path.GetDirectoryName(relativeAssetPath); string tex_FileName = Path.GetFileNameWithoutExtension(relativeAssetPath); string tex_Path_NoExt = tex_DirName + "/" + tex_FileName; // Check if TextMeshPro font asset already exists. If not, create a new one. Otherwise update the existing one. TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath(tex_Path_NoExt + ".asset", typeof(TMP_FontAsset)) as TMP_FontAsset; if (fontAsset == null) { //Debug.Log("Creating TextMeshPro font asset!"); fontAsset = ScriptableObject.CreateInstance(); // Create new TextMeshPro Font Asset. AssetDatabase.CreateAsset(fontAsset, tex_Path_NoExt + ".asset"); // Set version number of font asset fontAsset.version = "1.1.0"; //Set Font Asset Type fontAsset.atlasRenderMode = m_GlyphRenderMode; // Reference to the source font file GUID. fontAsset.m_SourceFontFileGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_SourceFontFile)); // Add FaceInfo to Font Asset fontAsset.faceInfo = m_FaceInfo; // Add GlyphInfo[] to Font Asset fontAsset.glyphTable = m_FontGlyphTable; // Add CharacterTable[] to font asset. fontAsset.characterTable = m_FontCharacterTable; // Sort glyph and character tables. fontAsset.SortGlyphAndCharacterTables(); // Get and Add Kerning Pairs to Font Asset if (m_IncludeFontFeatures) fontAsset.fontFeatureTable = GetKerningTable(); // Add Font Atlas as Sub-Asset fontAsset.atlasTextures = new Texture2D[] { m_FontAtlasTexture }; m_FontAtlasTexture.name = tex_FileName + " Atlas"; fontAsset.atlasWidth = m_AtlasWidth; fontAsset.atlasHeight = m_AtlasHeight; fontAsset.atlasPadding = m_Padding; AssetDatabase.AddObjectToAsset(m_FontAtlasTexture, fontAsset); // Create new Material and Add it as Sub-Asset Shader default_Shader = Shader.Find("TextMeshPro/Bitmap"); // m_shaderSelection; Material tmp_material = new Material(default_Shader); tmp_material.name = tex_FileName + " Material"; tmp_material.SetTexture(ShaderUtilities.ID_MainTex, m_FontAtlasTexture); fontAsset.material = tmp_material; AssetDatabase.AddObjectToAsset(tmp_material, fontAsset); } else { // Find all Materials referencing this font atlas. Material[] material_references = TMP_EditorUtility.FindMaterialReferences(fontAsset); // Set version number of font asset fontAsset.version = "1.1.0"; // Special handling to remove legacy font asset data if (fontAsset.m_glyphInfoList != null && fontAsset.m_glyphInfoList.Count > 0) fontAsset.m_glyphInfoList = null; // Destroy Assets that will be replaced. if (fontAsset.atlasTextures != null && fontAsset.atlasTextures.Length > 0) DestroyImmediate(fontAsset.atlasTextures[0], true); //Set Font Asset Type fontAsset.atlasRenderMode = m_GlyphRenderMode; // Add FaceInfo to Font Asset fontAsset.faceInfo = m_FaceInfo; // Add GlyphInfo[] to Font Asset fontAsset.glyphTable = m_FontGlyphTable; // Add CharacterTable[] to font asset. fontAsset.characterTable = m_FontCharacterTable; // Sort glyph and character tables. fontAsset.SortGlyphAndCharacterTables(); // Get and Add Kerning Pairs to Font Asset if (m_IncludeFontFeatures) fontAsset.fontFeatureTable = GetKerningTable(); // Add Font Atlas as Sub-Asset fontAsset.atlasTextures = new Texture2D[] { m_FontAtlasTexture }; m_FontAtlasTexture.name = tex_FileName + " Atlas"; fontAsset.atlasWidth = m_AtlasWidth; fontAsset.atlasHeight = m_AtlasHeight; fontAsset.atlasPadding = m_Padding; // Special handling due to a bug in earlier versions of Unity. m_FontAtlasTexture.hideFlags = HideFlags.None; fontAsset.material.hideFlags = HideFlags.None; AssetDatabase.AddObjectToAsset(m_FontAtlasTexture, fontAsset); // Assign new font atlas texture to the existing material. fontAsset.material.SetTexture(ShaderUtilities.ID_MainTex, fontAsset.atlasTextures[0]); // Update the Texture reference on the Material for (int i = 0; i < material_references.Length; i++) { material_references[i].SetTexture(ShaderUtilities.ID_MainTex, m_FontAtlasTexture); } } // Add list of GlyphRects to font asset. fontAsset.freeGlyphRects = m_FreeGlyphRects; fontAsset.usedGlyphRects = m_UsedGlyphRects; // Save Font Asset creation settings m_SelectedFontAsset = fontAsset; m_LegacyFontAsset = null; fontAsset.creationSettings = SaveFontCreationSettings(); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(fontAsset)); // Re-import font asset to get the new updated version. //EditorUtility.SetDirty(font_asset); fontAsset.ReadFontAssetDefinition(); AssetDatabase.Refresh(); m_FontAtlasTexture = null; // NEED TO GENERATE AN EVENT TO FORCE A REDRAW OF ANY TEXTMESHPRO INSTANCES THAT MIGHT BE USING THIS FONT ASSET TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset); } void Save_SDF_FontAsset(string filePath) { filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath. string dataPath = Application.dataPath; if (filePath.IndexOf(dataPath, System.StringComparison.InvariantCultureIgnoreCase) == -1) { Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\""); return; } string relativeAssetPath = filePath.Substring(dataPath.Length - 6); string tex_DirName = Path.GetDirectoryName(relativeAssetPath); string tex_FileName = Path.GetFileNameWithoutExtension(relativeAssetPath); string tex_Path_NoExt = tex_DirName + "/" + tex_FileName; // Check if TextMeshPro font asset already exists. If not, create a new one. Otherwise update the existing one. TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath(tex_Path_NoExt + ".asset"); if (fontAsset == null) { //Debug.Log("Creating TextMeshPro font asset!"); fontAsset = ScriptableObject.CreateInstance(); // Create new TextMeshPro Font Asset. AssetDatabase.CreateAsset(fontAsset, tex_Path_NoExt + ".asset"); // Set version number of font asset fontAsset.version = "1.1.0"; // Reference to source font file GUID. fontAsset.m_SourceFontFileGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_SourceFontFile)); //Set Font Asset Type fontAsset.atlasRenderMode = m_GlyphRenderMode; // Add FaceInfo to Font Asset fontAsset.faceInfo = m_FaceInfo; // Add GlyphInfo[] to Font Asset fontAsset.glyphTable = m_FontGlyphTable; // Add CharacterTable[] to font asset. fontAsset.characterTable = m_FontCharacterTable; // Sort glyph and character tables. fontAsset.SortGlyphAndCharacterTables(); // Get and Add Kerning Pairs to Font Asset if (m_IncludeFontFeatures) fontAsset.fontFeatureTable = GetKerningTable(); // Add Font Atlas as Sub-Asset fontAsset.atlasTextures = new Texture2D[] { m_FontAtlasTexture }; m_FontAtlasTexture.name = tex_FileName + " Atlas"; fontAsset.atlasWidth = m_AtlasWidth; fontAsset.atlasHeight = m_AtlasHeight; fontAsset.atlasPadding = m_Padding; AssetDatabase.AddObjectToAsset(m_FontAtlasTexture, fontAsset); // Create new Material and Add it as Sub-Asset Shader default_Shader = Shader.Find("TextMeshPro/Distance Field"); Material tmp_material = new Material(default_Shader); tmp_material.name = tex_FileName + " Material"; tmp_material.SetTexture(ShaderUtilities.ID_MainTex, m_FontAtlasTexture); tmp_material.SetFloat(ShaderUtilities.ID_TextureWidth, m_FontAtlasTexture.width); tmp_material.SetFloat(ShaderUtilities.ID_TextureHeight, m_FontAtlasTexture.height); int spread = m_Padding + 1; tmp_material.SetFloat(ShaderUtilities.ID_GradientScale, spread); // Spread = Padding for Brute Force SDF. tmp_material.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle); tmp_material.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle); fontAsset.material = tmp_material; AssetDatabase.AddObjectToAsset(tmp_material, fontAsset); } else { // Find all Materials referencing this font atlas. Material[] material_references = TMP_EditorUtility.FindMaterialReferences(fontAsset); // Destroy Assets that will be replaced. if (fontAsset.atlasTextures != null && fontAsset.atlasTextures.Length > 0) DestroyImmediate(fontAsset.atlasTextures[0], true); // Set version number of font asset fontAsset.version = "1.1.0"; // Special handling to remove legacy font asset data if (fontAsset.m_glyphInfoList != null && fontAsset.m_glyphInfoList.Count > 0) fontAsset.m_glyphInfoList = null; //Set Font Asset Type fontAsset.atlasRenderMode = m_GlyphRenderMode; // Add FaceInfo to Font Asset fontAsset.faceInfo = m_FaceInfo; // Add GlyphInfo[] to Font Asset fontAsset.glyphTable = m_FontGlyphTable; // Add CharacterTable[] to font asset. fontAsset.characterTable = m_FontCharacterTable; // Sort glyph and character tables. fontAsset.SortGlyphAndCharacterTables(); // Get and Add Kerning Pairs to Font Asset // TODO: Check and preserve existing adjustment pairs. if (m_IncludeFontFeatures) fontAsset.fontFeatureTable = GetKerningTable(); // Add Font Atlas as Sub-Asset fontAsset.atlasTextures = new Texture2D[] { m_FontAtlasTexture }; m_FontAtlasTexture.name = tex_FileName + " Atlas"; fontAsset.atlasWidth = m_AtlasWidth; fontAsset.atlasHeight = m_AtlasHeight; fontAsset.atlasPadding = m_Padding; // Special handling due to a bug in earlier versions of Unity. m_FontAtlasTexture.hideFlags = HideFlags.None; fontAsset.material.hideFlags = HideFlags.None; AssetDatabase.AddObjectToAsset(m_FontAtlasTexture, fontAsset); // Assign new font atlas texture to the existing material. fontAsset.material.SetTexture(ShaderUtilities.ID_MainTex, fontAsset.atlasTextures[0]); // Update the Texture reference on the Material for (int i = 0; i < material_references.Length; i++) { material_references[i].SetTexture(ShaderUtilities.ID_MainTex, m_FontAtlasTexture); material_references[i].SetFloat(ShaderUtilities.ID_TextureWidth, m_FontAtlasTexture.width); material_references[i].SetFloat(ShaderUtilities.ID_TextureHeight, m_FontAtlasTexture.height); int spread = m_Padding + 1; material_references[i].SetFloat(ShaderUtilities.ID_GradientScale, spread); // Spread = Padding for Brute Force SDF. material_references[i].SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle); material_references[i].SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle); } } // Saving File for Debug //var pngData = destination_Atlas.EncodeToPNG(); //File.WriteAllBytes("Assets/Textures/Debug Distance Field.png", pngData); // Add list of GlyphRects to font asset. fontAsset.freeGlyphRects = m_FreeGlyphRects; fontAsset.usedGlyphRects = m_UsedGlyphRects; // Save Font Asset creation settings m_SelectedFontAsset = fontAsset; m_LegacyFontAsset = null; fontAsset.creationSettings = SaveFontCreationSettings(); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(fontAsset)); // Re-import font asset to get the new updated version. fontAsset.ReadFontAssetDefinition(); AssetDatabase.Refresh(); m_FontAtlasTexture = null; // NEED TO GENERATE AN EVENT TO FORCE A REDRAW OF ANY TEXTMESHPRO INSTANCES THAT MIGHT BE USING THIS FONT ASSET TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset); } /// /// Internal method to save the Font Asset Creation Settings /// /// FontAssetCreationSettings SaveFontCreationSettings() { FontAssetCreationSettings settings = new FontAssetCreationSettings(); //settings.sourceFontFileName = m_SourceFontFile.name; settings.sourceFontFileGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_SourceFontFile)); settings.pointSizeSamplingMode = m_PointSizeSamplingMode; settings.pointSize = m_PointSize; settings.padding = m_Padding; settings.packingMode = (int)m_PackingMode; settings.atlasWidth = m_AtlasWidth; settings.atlasHeight = m_AtlasHeight; settings.characterSetSelectionMode = m_CharacterSetSelectionMode; settings.characterSequence = m_CharacterSequence; settings.referencedFontAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_ReferencedFontAsset)); settings.referencedTextAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_CharactersFromFile)); //settings.fontStyle = (int)m_FontStyle; //settings.fontStyleModifier = m_FontStyleValue; settings.renderMode = (int)m_GlyphRenderMode; settings.includeFontFeatures = m_IncludeFontFeatures; return settings; } /// /// Internal method to load the Font Asset Creation Settings /// /// void LoadFontCreationSettings(FontAssetCreationSettings settings) { m_SourceFontFile = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(settings.sourceFontFileGUID)); m_PointSizeSamplingMode = settings.pointSizeSamplingMode; m_PointSize = settings.pointSize; m_Padding = settings.padding; m_PackingMode = (FontPackingModes)settings.packingMode; m_AtlasWidth = settings.atlasWidth; m_AtlasHeight = settings.atlasHeight; m_CharacterSetSelectionMode = settings.characterSetSelectionMode; m_CharacterSequence = settings.characterSequence; m_ReferencedFontAsset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(settings.referencedFontAssetGUID)); m_CharactersFromFile = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(settings.referencedTextAssetGUID)); //m_FontStyle = (FaceStyles)settings.fontStyle; //m_FontStyleValue = settings.fontStyleModifier; m_GlyphRenderMode = (GlyphRenderMode)settings.renderMode; m_IncludeFontFeatures = settings.includeFontFeatures; } /// /// Save the latest font asset creation settings to EditorPrefs. /// /// void SaveCreationSettingsToEditorPrefs(FontAssetCreationSettings settings) { // Create new list if one does not already exist if (m_FontAssetCreationSettingsContainer == null) { m_FontAssetCreationSettingsContainer = new FontAssetCreationSettingsContainer(); m_FontAssetCreationSettingsContainer.fontAssetCreationSettings = new List(); } // Add new creation settings to the list m_FontAssetCreationSettingsContainer.fontAssetCreationSettings.Add(settings); // Since list should only contain the most 4 recent settings, we remove the first element if list exceeds 4 elements. if (m_FontAssetCreationSettingsContainer.fontAssetCreationSettings.Count > 4) m_FontAssetCreationSettingsContainer.fontAssetCreationSettings.RemoveAt(0); m_FontAssetCreationSettingsCurrentIndex = m_FontAssetCreationSettingsContainer.fontAssetCreationSettings.Count - 1; // Serialize list to JSON string serializedSettings = JsonUtility.ToJson(m_FontAssetCreationSettingsContainer, true); EditorPrefs.SetString(k_FontAssetCreationSettingsContainerKey, serializedSettings); } void DrawPreview() { Rect pixelRect; if (position.width > position.height && position.width > k_TwoColumnControlsWidth) { float minSide = Mathf.Min(position.height - 15f, position.width - k_TwoColumnControlsWidth); EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.MaxWidth(minSide)); pixelRect = GUILayoutUtility.GetRect(minSide, minSide, GUILayout.ExpandHeight(false), GUILayout.ExpandWidth(false)); } else { EditorGUILayout.BeginVertical(EditorStyles.helpBox); pixelRect = GUILayoutUtility.GetAspectRect(1f); } if (m_FontAtlasTexture != null) { EditorGUI.DrawTextureAlpha(pixelRect, m_FontAtlasTexture, ScaleMode.StretchToFill); } else if (m_SavedFontAtlas != null) { EditorGUI.DrawTextureAlpha(pixelRect, m_SavedFontAtlas, ScaleMode.StretchToFill); } EditorGUILayout.EndVertical(); } void CheckForLegacyGlyphRenderMode() { // Special handling for legacy glyph render mode if ((int)m_GlyphRenderMode < 0x100) { switch ((int)m_GlyphRenderMode) { case 0: m_GlyphRenderMode = GlyphRenderMode.SMOOTH_HINTED; break; case 1: m_GlyphRenderMode = GlyphRenderMode.SMOOTH; break; case 2: m_GlyphRenderMode = GlyphRenderMode.RASTER_HINTED; break; case 3: m_GlyphRenderMode = GlyphRenderMode.RASTER; break; case 6: case 7: m_GlyphRenderMode = GlyphRenderMode.SDFAA; break; } } } // Get Kerning Pairs public TMP_FontFeatureTable GetKerningTable() { GlyphPairAdjustmentRecord[] adjustmentRecords = FontEngine.GetGlyphPairAdjustmentTable(m_AvailableGlyphsToAdd.ToArray()); if (adjustmentRecords == null) return null; TMP_FontFeatureTable fontFeatureTable = new TMP_FontFeatureTable(); for (int i = 0; i < adjustmentRecords.Length; i++) { fontFeatureTable.glyphPairAdjustmentRecords.Add(new TMP_GlyphPairAdjustmentRecord(adjustmentRecords[i])); } fontFeatureTable.SortGlyphPairAdjustmentRecords(); return fontFeatureTable; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_FontAssetCreatorWindow.cs.meta ================================================ fileFormatVersion: 2 guid: 383966e89d344865a36addd5d378ffd3 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_FontPlugin.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; using System; using System.Runtime.InteropServices; namespace TMPro.EditorUtilities { /* public class TMPro_FontPlugin { [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void DebugLog(string log); private static readonly DebugLog debugLog = DebugWrapper; private static readonly IntPtr functionPointer = Marshal.GetFunctionPointerForDelegate(debugLog); private static void DebugWrapper(string log) { Debug.Log(log); } public static void LinkDebugLog() { LinkDebug(functionPointer); } [DllImport("TMPro_Plugin")] private static extern void LinkDebug([MarshalAs(UnmanagedType.FunctionPtr)]IntPtr debugCall); [DllImport("TMPro_Plugin")] public static extern int Initialize_FontEngine(); [DllImport("TMPro_Plugin")] public static extern int Destroy_FontEngine(); [DllImport("TMPro_Plugin")] public static extern int Load_TrueType_Font(string fontPath); [DllImport("TMPro_Plugin")] public static extern int FT_Size_Font(int fontSize); [DllImport("TMPro_Plugin")] public static extern int Render_Character(byte[] buffer_fill, byte[] buffer_edge, int buffer_width, int buffer_height, int offset, int asc, FaceStyles style, float thickness, RenderModes rasterMode, ref FT_GlyphInfo glyphInfo); [DllImport("TMPro_Plugin")] public static extern int Render_Characters(byte[] buffer, int buffer_width, int buffer_height, int character_padding, int[] asc_set, int char_count, FaceStyles style, float style_mod, bool autoSize, RenderModes renderMode, int method, ref FT_FaceInfo fontData, FT_GlyphInfo[] Output); [DllImport("TMPro_Plugin")] public static extern int FT_GetKerningPairs(string fontPath, int[] characterSet, int setCount, FT_KerningPair[] kerningPairs); [DllImport("TMPro_Plugin")] public static extern float Check_RenderProgress(); [DllImport("TMPro_Plugin")] internal static extern void SendCancellationRequest(CancellationRequestType request); } public enum FaceStyles { Normal, Bold, Italic, Bold_Italic, Outline, Bold_Sim }; public enum RenderModes { HintedSmooth = 0, Smooth = 1, RasterHinted = 2, Raster = 3, DistanceField16 = 6, DistanceField32 = 7 }; // SignedDistanceField64 = 8 internal enum CancellationRequestType : byte { None = 0x0, CancelInProgess = 0x1, WindowClosed = 0x2 }; [StructLayout(LayoutKind.Sequential)] public struct FT_KerningPair { public int ascII_Left; public int ascII_Right; public float xAdvanceOffset; } [StructLayout(LayoutKind.Sequential)] public struct FT_GlyphInfo { public int id; public float x; public float y; public float width; public float height; public float xOffset; public float yOffset; public float xAdvance; } [StructLayout(LayoutKind.Sequential)] public struct FT_FaceInfo { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string name; public int pointSize; public int padding; public float lineHeight; public float baseline; public float ascender; public float descender; public float centerLine; public float underline; public float underlineThickness; public int characterCount; public int atlasWidth; public int atlasHeight; } */ } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_FontPlugin.cs.meta ================================================ fileFormatVersion: 2 guid: 9edc9283e7d6409fab242fe8fb6a822c MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_SortingLayerHelper.cs ================================================ /* * Copyright (c) 2014, Nick Gravelyn. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. */ using UnityEngine; using UnityEditor; using System; using System.Reflection; namespace TMPro { // Helpers used by the different sorting layer classes. public static class SortingLayerHelper { private static Type _utilityType; private static PropertyInfo _sortingLayerNamesProperty; private static MethodInfo _getSortingLayerUserIdMethod; static SortingLayerHelper() { _utilityType = Type.GetType("UnityEditorInternal.InternalEditorUtility, UnityEditor"); _sortingLayerNamesProperty = _utilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic); _getSortingLayerUserIdMethod = _utilityType.GetMethod("GetSortingLayerUniqueID", BindingFlags.Static | BindingFlags.NonPublic); } // Gets an array of sorting layer names. // Since this uses reflection, callers should check for 'null' which will be returned if the reflection fails. public static string[] sortingLayerNames { get { if (_sortingLayerNamesProperty == null) { return null; } return _sortingLayerNamesProperty.GetValue(null, null) as string[]; } } // Given the ID of a sorting layer, returns the sorting layer's name public static string GetSortingLayerNameFromID(int id) { string[] names = sortingLayerNames; if (names == null) { return null; } for (int i = 0; i < names.Length; i++) { if (GetSortingLayerIDForIndex(i) == id) { return names[i]; } } return null; } // Given the name of a sorting layer, returns the ID. public static int GetSortingLayerIDForName(string name) { string[] names = sortingLayerNames; if (names == null) { return 0; } return GetSortingLayerIDForIndex(Array.IndexOf(names, name)); } // Helper to convert from a sorting layer INDEX to a sorting layer ID. These are not the same thing. // IDs are based on the order in which layers were created and do not change when reordering the layers. // Thankfully there is a private helper we can call to get the ID for a layer given its index. public static int GetSortingLayerIDForIndex(int index) { if (_getSortingLayerUserIdMethod == null) { return 0; } return (int)_getSortingLayerUserIdMethod.Invoke(null, new object[] { index }); } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_SortingLayerHelper.cs.meta ================================================ fileFormatVersion: 2 guid: 88ed537c17c34f339121fe9a7d6d7a0e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_TextContainerEditor.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { [CustomEditor(typeof(TextContainer)), CanEditMultipleObjects] public class TMPro_TextContainerEditor : Editor { // Serialized Properties private SerializedProperty anchorPosition_prop; private SerializedProperty pivot_prop; private SerializedProperty rectangle_prop; private SerializedProperty margins_prop; private TextContainer m_textContainer; //private Transform m_transform; //private Vector3[] m_Rect_handlePoints = new Vector3[4]; //private Vector3[] m_Margin_handlePoints = new Vector3[4]; //private Vector2 m_anchorPosition; //private Vector3 m_mousePreviousPOS; //private Vector2 m_previousStartPOS; //private int m_mouseDragFlag = 0; //private static Transform m_visualHelper; void OnEnable() { // Serialized Properties anchorPosition_prop = serializedObject.FindProperty("m_anchorPosition"); pivot_prop = serializedObject.FindProperty("m_pivot"); rectangle_prop = serializedObject.FindProperty("m_rect"); margins_prop = serializedObject.FindProperty("m_margins"); m_textContainer = (TextContainer)target; //m_transform = m_textContainer.transform; /* if (m_visualHelper == null) { m_visualHelper = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform; m_visualHelper.localScale = new Vector3(0.25f, 0.25f, 0.25f); } */ } void OnDisable() { /* if (m_visualHelper != null) DestroyImmediate (m_visualHelper.gameObject); */ } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(anchorPosition_prop); if (anchorPosition_prop.enumValueIndex == 9) { EditorGUI.indentLevel += 1; EditorGUILayout.PropertyField(pivot_prop, new GUIContent("Pivot Position")); EditorGUI.indentLevel -= 1; } DrawDimensionProperty(rectangle_prop, "Dimensions"); DrawMaginProperty(margins_prop, "Margins"); if (EditorGUI.EndChangeCheck()) { // Re-compute pivot position when changes are made. if (anchorPosition_prop.enumValueIndex != 9) pivot_prop.vector2Value = GetAnchorPosition(anchorPosition_prop.enumValueIndex); m_textContainer.hasChanged = true; } serializedObject.ApplyModifiedProperties(); EditorGUILayout.Space(); } private void DrawDimensionProperty(SerializedProperty property, string label) { float old_LabelWidth = EditorGUIUtility.labelWidth; float old_FieldWidth = EditorGUIUtility.fieldWidth; Rect rect = EditorGUILayout.GetControlRect(false, 18); Rect pos0 = new Rect(rect.x, rect.y + 2, rect.width, 18); float width = rect.width + 3; pos0.width = old_LabelWidth; GUI.Label(pos0, label); Rect rectangle = property.rectValue; float width_B = width - old_LabelWidth; float fieldWidth = width_B / 4; pos0.width = fieldWidth - 5; pos0.x = old_LabelWidth + 15; GUI.Label(pos0, "Width"); pos0.x += fieldWidth; rectangle.width = EditorGUI.FloatField(pos0, GUIContent.none, rectangle.width); pos0.x += fieldWidth; GUI.Label(pos0, "Height"); pos0.x += fieldWidth; rectangle.height = EditorGUI.FloatField(pos0, GUIContent.none, rectangle.height); property.rectValue = rectangle; EditorGUIUtility.labelWidth = old_LabelWidth; EditorGUIUtility.fieldWidth = old_FieldWidth; } private void DrawMaginProperty(SerializedProperty property, string label) { float old_LabelWidth = EditorGUIUtility.labelWidth; float old_FieldWidth = EditorGUIUtility.fieldWidth; Rect rect = EditorGUILayout.GetControlRect(false, 2 * 18); Rect pos0 = new Rect(rect.x, rect.y + 2, rect.width, 18); float width = rect.width + 3; pos0.width = old_LabelWidth; GUI.Label(pos0, label); //Vector4 vec = property.vector4Value; Vector4 vec = Vector4.zero; vec.x = property.FindPropertyRelative("x").floatValue; vec.y = property.FindPropertyRelative("y").floatValue; vec.z = property.FindPropertyRelative("z").floatValue; vec.w = property.FindPropertyRelative("w").floatValue; float widthB = width - old_LabelWidth; float fieldWidth = widthB / 4; pos0.width = fieldWidth - 5; // Labels pos0.x = old_LabelWidth + 15; GUI.Label(pos0, "Left"); pos0.x += fieldWidth; GUI.Label(pos0, "Top"); pos0.x += fieldWidth; GUI.Label(pos0, "Right"); pos0.x += fieldWidth; GUI.Label(pos0, "Bottom"); pos0.y += 18; pos0.x = old_LabelWidth + 15; vec.x = EditorGUI.FloatField(pos0, GUIContent.none, vec.x); pos0.x += fieldWidth; vec.y = EditorGUI.FloatField(pos0, GUIContent.none, vec.y); pos0.x += fieldWidth; vec.z = EditorGUI.FloatField(pos0, GUIContent.none, vec.z); pos0.x += fieldWidth; vec.w = EditorGUI.FloatField(pos0, GUIContent.none, vec.w); //property.vector4Value = vec; property.FindPropertyRelative("x").floatValue = vec.x; property.FindPropertyRelative("y").floatValue = vec.y; property.FindPropertyRelative("z").floatValue = vec.z; property.FindPropertyRelative("w").floatValue = vec.w; EditorGUIUtility.labelWidth = old_LabelWidth; EditorGUIUtility.fieldWidth = old_FieldWidth; } Vector2 GetAnchorPosition(int index) { Vector2 anchorPosition = Vector2.zero; switch (index) { case 0: // TOP LEFT anchorPosition = new Vector2(0, 1); break; case 1: // TOP anchorPosition = new Vector2(0.5f, 1); break; case 2: // TOP RIGHT anchorPosition = new Vector2(1, 1); break; case 3: // LEFT anchorPosition = new Vector2(0, 0.5f); break; case 4: // MIDDLE anchorPosition = new Vector2(0.5f, 0.5f); break; case 5: // RIGHT anchorPosition = new Vector2(1, 0.5f); break; case 6: // BOTTOM LEFT anchorPosition = new Vector2(0, 0); break; case 7: // BOTTOM anchorPosition = new Vector2(0.5f, 0); break; case 8: // BOTTOM RIGHT anchorPosition = new Vector2(1, 0); break; } return anchorPosition; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_TextContainerEditor.cs.meta ================================================ fileFormatVersion: 2 guid: 02893ffb522b490a9fa28eedd2584309 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_TexturePostProcessor.cs ================================================ using UnityEngine; using UnityEditor; using System.Collections; namespace TMPro.EditorUtilities { public class TMPro_TexturePostProcessor : AssetPostprocessor { void OnPostprocessTexture(Texture2D texture) { //var importer = assetImporter as TextureImporter; Texture2D tex = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D)) as Texture2D; // Send Event Sub Objects if (tex != null) TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, tex); } } //public class TMPro_PackageImportPostProcessor : AssetPostprocessor //{ // static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) // { // for (int i = 0; i < importedAssets.Length; i++) // { // if (importedAssets[i].Contains("TextMesh Pro/Resources/TMP Settings.asset")) // { // Debug.Log("New TMP Settings file was just imported."); // // TMP Settings file was just re-imported. // // Check if project already contains // } // if (importedAssets[i].Contains("com.unity.TextMeshPro/Examples")) // { // //Debug.Log("New TMP Examples folder was just imported."); // } // //Debug.Log("[" + importedAssets[i] + "] was just imported."); // } // //for (int i = 0; i < deletedAssets.Length; i++) // //{ // // if (deletedAssets[i] == "Assets/TextMesh Pro") // // { // // //Debug.Log("Asset [" + deletedAssets[i] + "] has been deleted."); // // string currentBuildSettings = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup); // // //Check for and inject TMP_PRESENT // // if (currentBuildSettings.Contains("TMP_PRESENT;")) // // { // // currentBuildSettings = currentBuildSettings.Replace("TMP_PRESENT;", ""); // // PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, currentBuildSettings); // // } // // else if (currentBuildSettings.Contains("TMP_PRESENT")) // // { // // currentBuildSettings = currentBuildSettings.Replace("TMP_PRESENT", ""); // // PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, currentBuildSettings); // // } // // } // //} // } //} } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/TMPro_TexturePostProcessor.cs.meta ================================================ fileFormatVersion: 2 guid: f4935fb862d54980b1bcbca942962642 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/Unity.TextMeshPro.Editor.asmdef ================================================ { "name": "Unity.TextMeshPro.Editor", "references": [ "Unity.TextMeshPro", "Unity.ugui", "Unity.ugui.Editor" ], "optionalUnityReferences": [], "includePlatforms": [ "Editor" ], "excludePlatforms": [] } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor/Unity.TextMeshPro.Editor.asmdef.meta ================================================ fileFormatVersion: 2 guid: 6546d7765b4165b40850b3667f981c26 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Editor.meta ================================================ fileFormatVersion: 2 guid: b5d6c28ed7b94775be9e2560f300247c folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/AssemblyInfo.cs.cs ================================================ using System.Runtime.CompilerServices; // Allow internal visibility for testing purposes. [assembly: InternalsVisibleTo("Unity.TextCore")] [assembly: InternalsVisibleTo("Unity.FontEngine.Tests")] #if UNITY_EDITOR [assembly: InternalsVisibleTo("Unity.TextCore.Editor")] [assembly: InternalsVisibleTo("Unity.TextMeshPro.Editor")] #endif ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/AssemblyInfo.cs.cs.meta ================================================ fileFormatVersion: 2 guid: 1c147d10db452eb4b854a35f84472017 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/FastAction.cs ================================================ using UnityEngine; using System.Collections; using System.Collections.Generic; namespace TMPro { public class FastAction { LinkedList delegates = new LinkedList(); Dictionary> lookup = new Dictionary>(); public void Add(System.Action rhs) { if (lookup.ContainsKey(rhs)) return; lookup[rhs] = delegates.AddLast(rhs); } public void Remove(System.Action rhs) { if (lookup.TryGetValue(rhs, out LinkedListNode node)) { lookup.Remove(rhs); delegates.Remove(node); } } public void Call() { var node = delegates.First; while (node != null) { node.Value(); node = node.Next; } } } public class FastAction { LinkedList> delegates = new LinkedList>(); Dictionary, LinkedListNode>> lookup = new Dictionary, LinkedListNode>>(); public void Add(System.Action rhs) { if (lookup.ContainsKey(rhs)) return; lookup[rhs] = delegates.AddLast(rhs); } public void Remove(System.Action rhs) { if (lookup.TryGetValue(rhs, out LinkedListNode> node)) { lookup.Remove(rhs); delegates.Remove(node); } } public void Call(A a) { var node = delegates.First; while (node != null) { node.Value(a); node = node.Next; } } } public class FastAction { LinkedList> delegates = new LinkedList>(); Dictionary, LinkedListNode>> lookup = new Dictionary, LinkedListNode>>(); public void Add(System.Action rhs) { if (lookup.ContainsKey(rhs)) return; lookup[rhs] = delegates.AddLast(rhs); } public void Remove(System.Action rhs) { if (lookup.TryGetValue(rhs, out LinkedListNode> node)) { lookup.Remove(rhs); delegates.Remove(node); } } public void Call(A a, B b) { var node = delegates.First; while (node != null) { node.Value(a, b); node = node.Next; } } } public class FastAction { LinkedList> delegates = new LinkedList>(); Dictionary, LinkedListNode>> lookup = new Dictionary, LinkedListNode>>(); public void Add(System.Action rhs) { if (lookup.ContainsKey(rhs)) return; lookup[rhs] = delegates.AddLast(rhs); } public void Remove(System.Action rhs) { if (lookup.TryGetValue(rhs, out LinkedListNode> node)) { lookup.Remove(rhs); delegates.Remove(node); } } public void Call(A a, B b, C c) { var node = delegates.First; while (node != null) { node.Value(a, b, c); node = node.Next; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/FastAction.cs.meta ================================================ fileFormatVersion: 2 guid: 871f8edd56e84b8fb295b10cc3c78f36 timeCreated: 1435956061 licenseType: Store MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/MaterialReferenceManager.cs ================================================ using UnityEngine; using System.Collections; using System.Collections.Generic; namespace TMPro { public class MaterialReferenceManager { private static MaterialReferenceManager s_Instance; // Dictionaries used to track Asset references. private Dictionary m_FontMaterialReferenceLookup = new Dictionary(); private Dictionary m_FontAssetReferenceLookup = new Dictionary(); private Dictionary m_SpriteAssetReferenceLookup = new Dictionary(); private Dictionary m_ColorGradientReferenceLookup = new Dictionary(); /// /// Get a singleton instance of the registry /// public static MaterialReferenceManager instance { get { if (MaterialReferenceManager.s_Instance == null) MaterialReferenceManager.s_Instance = new MaterialReferenceManager(); return MaterialReferenceManager.s_Instance; } } /// /// Add new font asset reference to dictionary. /// /// public static void AddFontAsset(TMP_FontAsset fontAsset) { MaterialReferenceManager.instance.AddFontAssetInternal(fontAsset); } /// /// Add new Font Asset reference to dictionary. /// /// private void AddFontAssetInternal(TMP_FontAsset fontAsset) { if (m_FontAssetReferenceLookup.ContainsKey(fontAsset.hashCode)) return; // Add reference to the font asset. m_FontAssetReferenceLookup.Add(fontAsset.hashCode, fontAsset); // Add reference to the font material. m_FontMaterialReferenceLookup.Add(fontAsset.materialHashCode, fontAsset.material); } /// /// Add new Sprite Asset to dictionary. /// /// /// public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset) { MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset); } /// /// Internal method to add a new sprite asset to the dictionary. /// /// /// private void AddSpriteAssetInternal(TMP_SpriteAsset spriteAsset) { if (m_SpriteAssetReferenceLookup.ContainsKey(spriteAsset.hashCode)) return; // Add reference to sprite asset. m_SpriteAssetReferenceLookup.Add(spriteAsset.hashCode, spriteAsset); // Adding reference to the sprite asset material as well m_FontMaterialReferenceLookup.Add(spriteAsset.hashCode, spriteAsset.material); } /// /// Add new Sprite Asset to dictionary. /// /// /// public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset) { MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset); } /// /// Internal method to add a new sprite asset to the dictionary. /// /// /// private void AddSpriteAssetInternal(int hashCode, TMP_SpriteAsset spriteAsset) { if (m_SpriteAssetReferenceLookup.ContainsKey(hashCode)) return; // Add reference to Sprite Asset. m_SpriteAssetReferenceLookup.Add(hashCode, spriteAsset); // Add reference to Sprite Asset using the asset hashcode. m_FontMaterialReferenceLookup.Add(hashCode, spriteAsset.material); // Compatibility check if (spriteAsset.hashCode == 0) spriteAsset.hashCode = hashCode; } /// /// Add new Material reference to dictionary. /// /// /// public static void AddFontMaterial(int hashCode, Material material) { MaterialReferenceManager.instance.AddFontMaterialInternal(hashCode, material); } /// /// Add new material reference to dictionary. /// /// /// private void AddFontMaterialInternal(int hashCode, Material material) { // Since this function is called after checking if the material is // contained in the dictionary, there is no need to check again. m_FontMaterialReferenceLookup.Add(hashCode, material); } /// /// Add new Color Gradient Preset to dictionary. /// /// /// public static void AddColorGradientPreset(int hashCode, TMP_ColorGradient spriteAsset) { MaterialReferenceManager.instance.AddColorGradientPreset_Internal(hashCode, spriteAsset); } /// /// Internal method to add a new Color Gradient Preset to the dictionary. /// /// /// private void AddColorGradientPreset_Internal(int hashCode, TMP_ColorGradient spriteAsset) { if (m_ColorGradientReferenceLookup.ContainsKey(hashCode)) return; // Add reference to Color Gradient Preset Asset. m_ColorGradientReferenceLookup.Add(hashCode, spriteAsset); } /// /// Add new material reference and return the index of this new reference in the materialReferences array. /// /// /// /// //public int AddMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset) //{ // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode)) // { // int index = m_MaterialReferenceLookup.Count; // materialReferences[index].fontAsset = fontAsset; // materialReferences[index].material = material; // materialReferences[index].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false; // materialReferences[index].index = index; // materialReferences[index].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = index; // // Compute Padding value and store it // // TODO // int fontAssetHashCode = fontAsset.hashCode; // if (!m_FontAssetReferenceLookup.ContainsKey(fontAssetHashCode)) // m_FontAssetReferenceLookup.Add(fontAssetHashCode, fontAsset); // m_countInternal += 1; // return index; // } // else // { // return m_MaterialReferenceLookup[materialHashCode]; // } //} /// /// Add new material reference and return the index of this new reference in the materialReferences array. /// /// /// /// /// //public int AddMaterial(Material material, int materialHashCode, TMP_SpriteAsset spriteAsset) //{ // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode)) // { // int index = m_MaterialReferenceLookup.Count; // materialReferences[index].fontAsset = materialReferences[0].fontAsset; // materialReferences[index].spriteAsset = spriteAsset; // materialReferences[index].material = material; // materialReferences[index].isDefaultMaterial = true; // materialReferences[index].index = index; // materialReferences[index].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = index; // int spriteAssetHashCode = spriteAsset.hashCode; // if (!m_SpriteAssetReferenceLookup.ContainsKey(spriteAssetHashCode)) // m_SpriteAssetReferenceLookup.Add(spriteAssetHashCode, spriteAsset); // m_countInternal += 1; // return index; // } // else // { // return m_MaterialReferenceLookup[materialHashCode]; // } //} /// /// Function to check if the font asset is already referenced. /// /// /// public bool Contains(TMP_FontAsset font) { if (m_FontAssetReferenceLookup.ContainsKey(font.hashCode)) return true; return false; } /// /// Function to check if the sprite asset is already referenced. /// /// /// public bool Contains(TMP_SpriteAsset sprite) { if (m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode)) return true; return false; } /// /// Function returning the Font Asset corresponding to the provided hash code. /// /// /// /// public static bool TryGetFontAsset(int hashCode, out TMP_FontAsset fontAsset) { return MaterialReferenceManager.instance.TryGetFontAssetInternal(hashCode, out fontAsset); } /// /// Internal Function returning the Font Asset corresponding to the provided hash code. /// /// /// /// private bool TryGetFontAssetInternal(int hashCode, out TMP_FontAsset fontAsset) { fontAsset = null; if (m_FontAssetReferenceLookup.TryGetValue(hashCode, out fontAsset)) { return true; } return false; } /// /// Function returning the Sprite Asset corresponding to the provided hash code. /// /// /// /// public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset) { return MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset); } /// /// Internal function returning the Sprite Asset corresponding to the provided hash code. /// /// /// /// private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset) { spriteAsset = null; if (m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset)) { return true; } return false; } /// /// Function returning the Color Gradient Preset corresponding to the provided hash code. /// /// /// /// public static bool TryGetColorGradientPreset(int hashCode, out TMP_ColorGradient gradientPreset) { return MaterialReferenceManager.instance.TryGetColorGradientPresetInternal(hashCode, out gradientPreset); } /// /// Internal function returning the Color Gradient Preset corresponding to the provided hash code. /// /// /// /// private bool TryGetColorGradientPresetInternal(int hashCode, out TMP_ColorGradient gradientPreset) { gradientPreset = null; if (m_ColorGradientReferenceLookup.TryGetValue(hashCode, out gradientPreset)) { return true; } return false; } /// /// Function returning the Font Material corresponding to the provided hash code. /// /// /// /// public static bool TryGetMaterial(int hashCode, out Material material) { return MaterialReferenceManager.instance.TryGetMaterialInternal(hashCode, out material); } /// /// Internal function returning the Font Material corresponding to the provided hash code. /// /// /// /// private bool TryGetMaterialInternal(int hashCode, out Material material) { material = null; if (m_FontMaterialReferenceLookup.TryGetValue(hashCode, out material)) { return true; } return false; } /// /// Function to lookup a material based on hash code and returning the MaterialReference containing this material. /// /// /// /// //public bool TryGetMaterial(int hashCode, out MaterialReference materialReference) //{ // int materialIndex = -1; // if (m_MaterialReferenceLookup.TryGetValue(hashCode, out materialIndex)) // { // materialReference = materialReferences[materialIndex]; // return true; // } // materialReference = new MaterialReference(); // return false; //} /// /// /// /// /// //public int GetMaterialIndex(TMP_FontAsset fontAsset) //{ // if (m_MaterialReferenceLookup.ContainsKey(fontAsset.materialHashCode)) // return m_MaterialReferenceLookup[fontAsset.materialHashCode]; // return -1; //} /// /// /// /// /// //public TMP_FontAsset GetFontAsset(int index) //{ // if (index >= 0 && index < materialReferences.Length) // return materialReferences[index].fontAsset; // return null; //} /// /// /// /// /// /// //public void SetDefaultMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset) //{ // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode)) // { // materialReferences[0].fontAsset = fontAsset; // materialReferences[0].material = material; // materialReferences[0].index = 0; // materialReferences[0].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false; // materialReferences[0].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = 0; // // Compute Padding value and store it // // TODO // int fontHashCode = fontAsset.hashCode; // if (!m_FontAssetReferenceLookup.ContainsKey(fontHashCode)) // m_FontAssetReferenceLookup.Add(fontHashCode, fontAsset); // } // else // { // materialReferences[0].fontAsset = fontAsset; // materialReferences[0].material = material; // materialReferences[0].index = 0; // materialReferences[0].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = 0; // } // // Compute padding // // TODO // m_countInternal = 1; //} /// /// /// //public void Clear() //{ // //m_currentIndex = 0; // m_MaterialReferenceLookup.Clear(); // m_SpriteAssetReferenceLookup.Clear(); // m_FontAssetReferenceLookup.Clear(); //} /// /// Function to clear the reference count for each of the material references. /// //public void ClearReferenceCount() //{ // m_countInternal = 0; // for (int i = 0; i < materialReferences.Length; i++) // { // if (materialReferences[i].fontAsset == null) // return; // materialReferences[i].referenceCount = 0; // } //} } public struct MaterialReference { public int index; public TMP_FontAsset fontAsset; public TMP_SpriteAsset spriteAsset; public Material material; public bool isDefaultMaterial; public bool isFallbackMaterial; public Material fallbackMaterial; public float padding; public int referenceCount; /// /// Constructor for new Material Reference. /// /// /// /// /// /// public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding) { this.index = index; this.fontAsset = fontAsset; this.spriteAsset = spriteAsset; this.material = material; this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false; this.isFallbackMaterial = false; this.fallbackMaterial = null; this.padding = padding; this.referenceCount = 0; } /// /// Function to check if a certain font asset is contained in the material reference array. /// /// /// /// public static bool Contains(MaterialReference[] materialReferences, TMP_FontAsset fontAsset) { int id = fontAsset.GetInstanceID(); for (int i = 0; i < materialReferences.Length && materialReferences[i].fontAsset != null; i++) { if (materialReferences[i].fontAsset.GetInstanceID() == id) return true; } return false; } /// /// Function to add a new material reference and returning its index in the material reference array. /// /// /// /// /// /// public static int AddMaterialReference(Material material, TMP_FontAsset fontAsset, MaterialReference[] materialReferences, Dictionary materialReferenceIndexLookup) { int materialID = material.GetInstanceID(); if (materialReferenceIndexLookup.TryGetValue(materialID, out int index)) { return index; } else { index = materialReferenceIndexLookup.Count; // Add new reference index materialReferenceIndexLookup[materialID] = index; materialReferences[index].index = index; materialReferences[index].fontAsset = fontAsset; materialReferences[index].spriteAsset = null; materialReferences[index].material = material; materialReferences[index].isDefaultMaterial = materialID == fontAsset.material.GetInstanceID() ? true : false; //materialReferences[index].padding = 0; materialReferences[index].referenceCount = 0; return index; } } /// /// /// /// /// /// /// /// public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, MaterialReference[] materialReferences, Dictionary materialReferenceIndexLookup) { int materialID = material.GetInstanceID(); if (materialReferenceIndexLookup.TryGetValue(materialID, out int index)) { return index; } else { index = materialReferenceIndexLookup.Count; // Add new reference index materialReferenceIndexLookup[materialID] = index; materialReferences[index].index = index; materialReferences[index].fontAsset = materialReferences[0].fontAsset; materialReferences[index].spriteAsset = spriteAsset; materialReferences[index].material = material; materialReferences[index].isDefaultMaterial = true; //materialReferences[index].padding = 0; materialReferences[index].referenceCount = 0; return index; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/MaterialReferenceManager.cs.meta ================================================ fileFormatVersion: 2 guid: 11a6a034ab84493cbed6af5ae7aae78b timeCreated: 1449743129 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_Asset.cs ================================================ using UnityEngine; namespace TMPro { // Base class inherited by the various TextMeshPro Assets. [System.Serializable] public class TMP_Asset : ScriptableObject { /// /// HashCode based on the name of the asset. /// public int hashCode; /// /// The material used by this asset. /// public Material material; /// /// HashCode based on the name of the material assigned to this asset. /// public int materialHashCode; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_Asset.cs.meta ================================================ fileFormatVersion: 2 guid: 3bda1886f58f4e0ab1139400b160c3ee timeCreated: 1459318952 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_Character.cs ================================================ using System; using UnityEngine.TextCore; namespace TMPro { /// /// A basic element of text. /// [Serializable] public class TMP_Character : TMP_TextElement { /// /// Default constructor. /// public TMP_Character() { m_ElementType = TextElementType.Character; this.scale = 1.0f; } /// /// Constructor for new character /// /// Unicode value. /// Glyph public TMP_Character(uint unicode, Glyph glyph) { m_ElementType = TextElementType.Character; this.unicode = unicode; this.glyph = glyph; this.glyphIndex = glyph.index; this.scale = 1.0f; } /// /// Constructor for new character /// /// Unicode value. /// Glyph index. internal TMP_Character(uint unicode, uint glyphIndex) { m_ElementType = TextElementType.Character; this.unicode = unicode; this.glyph = null; this.glyphIndex = glyphIndex; this.scale = 1.0f; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_Character.cs.meta ================================================ fileFormatVersion: 2 guid: 4ac5b6a65aaeb59478e3b78660e9f134 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_CharacterInfo.cs ================================================ using UnityEngine; using UnityEngine.TextCore; namespace TMPro { public struct TMP_Vertex { public Vector3 position; public Vector2 uv; public Vector2 uv2; public Vector2 uv4; public Color32 color; //public Vector3 normal; //public Vector4 tangent; } /// /// Structure containing information about individual text elements (character or sprites). /// public struct TMP_CharacterInfo { public char character; // Should be changed to an int to handle UTF 32 /// /// Index of the character in the raw string. /// public int index; // Index of the character in the input string. public int stringLength; public TMP_TextElementType elementType; public TMP_TextElement textElement; public TMP_FontAsset fontAsset; public TMP_SpriteAsset spriteAsset; public int spriteIndex; public Material material; public int materialReferenceIndex; public bool isUsingAlternateTypeface; public float pointSize; //public short wordNumber; public int lineNumber; //public short charNumber; public int pageNumber; public int vertexIndex; public TMP_Vertex vertex_BL; public TMP_Vertex vertex_TL; public TMP_Vertex vertex_TR; public TMP_Vertex vertex_BR; public Vector3 topLeft; public Vector3 bottomLeft; public Vector3 topRight; public Vector3 bottomRight; public float origin; public float ascender; public float baseLine; public float descender; public float xAdvance; public float aspectRatio; public float scale; public Color32 color; public Color32 underlineColor; public Color32 strikethroughColor; public Color32 highlightColor; public FontStyles style; public bool isVisible; //public bool isIgnoringAlignment; } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_CharacterInfo.cs.meta ================================================ fileFormatVersion: 2 guid: 90fe1c65e6bb3bc4e90862df7297719e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_ColorGradient.cs ================================================ using UnityEngine; using System.Collections; namespace TMPro { public enum ColorMode { Single, HorizontalGradient, VerticalGradient, FourCornersGradient } [System.Serializable] public class TMP_ColorGradient : ScriptableObject { public ColorMode colorMode = ColorMode.FourCornersGradient; public Color topLeft; public Color topRight; public Color bottomLeft; public Color bottomRight; const ColorMode k_DefaultColorMode = ColorMode.FourCornersGradient; static readonly Color k_DefaultColor = Color.white; /// /// Default Constructor which sets each of the colors as white. /// public TMP_ColorGradient() { colorMode = k_DefaultColorMode; topLeft = k_DefaultColor; topRight = k_DefaultColor; bottomLeft = k_DefaultColor; bottomRight = k_DefaultColor; } /// /// Constructor allowing to set the default color of the Color Gradient. /// /// public TMP_ColorGradient(Color color) { colorMode = k_DefaultColorMode; topLeft = color; topRight = color; bottomLeft = color; bottomRight = color; } /// /// The vertex colors at the corners of the characters. /// /// Top left color. /// Top right color. /// Bottom left color. /// Bottom right color. public TMP_ColorGradient(Color color0, Color color1, Color color2, Color color3) { colorMode = k_DefaultColorMode; this.topLeft = color0; this.topRight = color1; this.bottomLeft = color2; this.bottomRight = color3; } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_ColorGradient.cs.meta ================================================ fileFormatVersion: 2 guid: 54d21f6ece3b46479f0c328f8c6007e0 timeCreated: 1468187202 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_CoroutineTween.cs ================================================ using UnityEngine; using UnityEngine.Events; using System.Collections; namespace TMPro { // Base interface for tweeners, // using an interface instead of // an abstract class as we want the // tweens to be structs. internal interface ITweenValue { void TweenValue(float floatPercentage); bool ignoreTimeScale { get; } float duration { get; } bool ValidTarget(); } // Color tween class, receives the // TweenValue callback and then sets // the value on the target. internal struct ColorTween : ITweenValue { public enum ColorTweenMode { All, RGB, Alpha } public class ColorTweenCallback : UnityEvent { } private ColorTweenCallback m_Target; private Color m_StartColor; private Color m_TargetColor; private ColorTweenMode m_TweenMode; private float m_Duration; private bool m_IgnoreTimeScale; public Color startColor { get { return m_StartColor; } set { m_StartColor = value; } } public Color targetColor { get { return m_TargetColor; } set { m_TargetColor = value; } } public ColorTweenMode tweenMode { get { return m_TweenMode; } set { m_TweenMode = value; } } public float duration { get { return m_Duration; } set { m_Duration = value; } } public bool ignoreTimeScale { get { return m_IgnoreTimeScale; } set { m_IgnoreTimeScale = value; } } public void TweenValue(float floatPercentage) { if (!ValidTarget()) return; var newColor = Color.Lerp(m_StartColor, m_TargetColor, floatPercentage); if (m_TweenMode == ColorTweenMode.Alpha) { newColor.r = m_StartColor.r; newColor.g = m_StartColor.g; newColor.b = m_StartColor.b; } else if (m_TweenMode == ColorTweenMode.RGB) { newColor.a = m_StartColor.a; } m_Target.Invoke(newColor); } public void AddOnChangedCallback(UnityAction callback) { if (m_Target == null) m_Target = new ColorTweenCallback(); m_Target.AddListener(callback); } public bool GetIgnoreTimescale() { return m_IgnoreTimeScale; } public float GetDuration() { return m_Duration; } public bool ValidTarget() { return m_Target != null; } } // Float tween class, receives the // TweenValue callback and then sets // the value on the target. internal struct FloatTween : ITweenValue { public class FloatTweenCallback : UnityEvent { } private FloatTweenCallback m_Target; private float m_StartValue; private float m_TargetValue; private float m_Duration; private bool m_IgnoreTimeScale; public float startValue { get { return m_StartValue; } set { m_StartValue = value; } } public float targetValue { get { return m_TargetValue; } set { m_TargetValue = value; } } public float duration { get { return m_Duration; } set { m_Duration = value; } } public bool ignoreTimeScale { get { return m_IgnoreTimeScale; } set { m_IgnoreTimeScale = value; } } public void TweenValue(float floatPercentage) { if (!ValidTarget()) return; var newValue = Mathf.Lerp(m_StartValue, m_TargetValue, floatPercentage); m_Target.Invoke(newValue); } public void AddOnChangedCallback(UnityAction callback) { if (m_Target == null) m_Target = new FloatTweenCallback(); m_Target.AddListener(callback); } public bool GetIgnoreTimescale() { return m_IgnoreTimeScale; } public float GetDuration() { return m_Duration; } public bool ValidTarget() { return m_Target != null; } } // Tween runner, executes the given tween. // The coroutine will live within the given // behaviour container. internal class TweenRunner where T : struct, ITweenValue { protected MonoBehaviour m_CoroutineContainer; protected IEnumerator m_Tween; // utility function for starting the tween private static IEnumerator Start(T tweenInfo) { if (!tweenInfo.ValidTarget()) yield break; var elapsedTime = 0.0f; while (elapsedTime < tweenInfo.duration) { elapsedTime += tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime; var percentage = Mathf.Clamp01(elapsedTime / tweenInfo.duration); tweenInfo.TweenValue(percentage); yield return null; } tweenInfo.TweenValue(1.0f); } public void Init(MonoBehaviour coroutineContainer) { m_CoroutineContainer = coroutineContainer; } public void StartTween(T info) { if (m_CoroutineContainer == null) { Debug.LogWarning("Coroutine container not configured... did you forget to call Init?"); return; } StopTween(); if (!m_CoroutineContainer.gameObject.activeInHierarchy) { info.TweenValue(1.0f); return; } m_Tween = Start(info); m_CoroutineContainer.StartCoroutine(m_Tween); } public void StopTween() { if (m_Tween != null) { m_CoroutineContainer.StopCoroutine(m_Tween); m_Tween = null; } } } } ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_CoroutineTween.cs.meta ================================================ fileFormatVersion: 2 guid: 658c1fb149e7498aa072b0c0f3bf13f0 timeCreated: 1464850953 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.textmeshpro@2.0.1/Scripts/Runtime/TMP_DefaultControls.cs ================================================ using UnityEngine; using System.Collections; using UnityEngine.UI; namespace TMPro { public static class TMP_DefaultControls { public struct Resources { public Sprite standard; public Sprite background; public Sprite inputField; public Sprite knob; public Sprite checkmark; public Sprite dropdown; public Sprite mask; } private const float kWidth = 160f; private const float kThickHeight = 30f; private const float kThinHeight = 20f; private static Vector2 s_ThickElementSize = new Vector2(kWidth, kThickHeight); private static Vector2 s_ThinElementSize = new Vector2(kWidth, kThinHeight); //private static Vector2 s_ImageElementSize = new Vector2(100f, 100f); private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f); //private static Color s_PanelColor = new Color(1f, 1f, 1f, 0.392f); private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f); private static GameObject CreateUIElementRoot(string name, Vector2 size) { GameObject child = new GameObject(name); RectTransform rectTransform = child.AddComponent(); rectTransform.sizeDelta = size; return child; } static GameObject CreateUIObject(string name, GameObject parent) { GameObject go = new GameObject(name); go.AddComponent(); SetParentAndAlign(go, parent); return go; } private static void SetDefaultTextValues(TMP_Text lbl) { // Set text values we want across UI elements in default controls. // Don't set values which are the same as the default values for the Text component, // since there's no point in that, and it's good to keep them as consistent as possible. lbl.color = s_TextColor; lbl.fontSize = 14; } private static void SetDefaultColorTransitionValues(Selectable slider) { ColorBlock colors = slider.colors; colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f); colors.pressedColor = new Color(0.698f, 0.698f, 0.698f); colors.disabledColor = new Color(0.521f, 0.521f, 0.521f); } private static void SetParentAndAlign(GameObject child, GameObject parent) { if (parent == null) return; child.transform.SetParent(parent.transform, false); SetLayerRecursively(child, parent.layer); } private static void SetLayerRecursively(GameObject go, int layer) { go.layer = layer; Transform t = go.transform; for (int i = 0; i < t.childCount; i++) SetLayerRecursively(t.GetChild(i).gameObject, layer); } // Actual controls public static GameObject CreateScrollbar(Resources resources) { // Create GOs Hierarchy GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", s_ThinElementSize); GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot); GameObject handle = CreateUIObject("Handle", sliderArea); Image bgImage = scrollbarRoot.AddComponent(); bgImage.sprite = resources.background; bgImage.type = Image.Type.Sliced; bgImage.color = s_DefaultSelectableColor; Image handleImage = handle.AddComponent(); handleImage.sprite = resources.standard; handleImage.type = Image.Type.Sliced; handleImage.color = s_DefaultSelectableColor; RectTransform sliderAreaRect = sliderArea.GetComponent(); sliderAreaRect.sizeDelta = new Vector2(-20, -20); sliderAreaRect.anchorMin = Vector2.zero; sliderAreaRect.anchorMax = Vector2.one; RectTransform handleRect = handle.GetComponent(); handleRect.sizeDelta = new Vector2(20, 20); Scrollbar scrollbar = scrollbarRoot.AddComponent(); scrollbar.handleRect = handleRect; scrollbar.targetGraphic = handleImage; SetDefaultColorTransitionValues(scrollbar); return scrollbarRoot; } public static GameObject CreateButton(Resources resources) { GameObject buttonRoot = CreateUIElementRoot("Button", s_ThickElementSize); GameObject childText = new GameObject("Text (TMP)"); childText.AddComponent(); SetParentAndAlign(childText, buttonRoot); Image image = buttonRoot.AddComponent(); image.sprite = resources.standard; image.type = Image.Type.Sliced; image.color = s_DefaultSelectableColor; Button bt = buttonRoot.AddComponent