82 changed files with 1184 additions and 286 deletions
-
1Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs
-
2Packages/com.unity.render-pipelines.core/Editor/LookDev/DisplayWindow.EnvironmentLibrarySidePanel.cs
-
1Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs
-
14Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs
-
16Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs
-
5Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs
-
31Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs
-
173Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs
-
2Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs.meta
-
4Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs
-
184Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs
-
2Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs.meta
-
2Packages/com.unity.render-pipelines.core/package.json
-
5Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs
-
6Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/ShaderStrippers/HDRPComputeShaderVariantStripper.cs
-
2Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs
-
51Packages/com.unity.render-pipelines.high-definition/Editor/PropertyDrawers/LookDevVolumeProfileSettingsPropertyDrawer.cs
-
60Packages/com.unity.render-pipelines.high-definition/Editor/SceneTemplates/Indoors/IndoorsScene.unity
-
27Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.Configuration.cs
-
3Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.cs
-
3Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/NVIDIADebugView.cs
-
2Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs
-
34Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/lightlistbuild-clustered.compute
-
31Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/lightlistbuild.compute
-
4Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDRenderPipeline.ScreenSpaceShadows.cs
-
5Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs
-
1Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader
-
1Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader
-
1Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader
-
1Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader
-
6Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/CompositeWithUIAndOETF.shader
-
4Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FinalPass.shader
-
4Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs
-
8Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LookDev.cs
-
10Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs
-
99Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs
-
49Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs
-
8Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineGlobalSettings.cs
-
1Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs
-
2Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/FSR2Pass.cs
-
2Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXDefines.hlsl
-
2Packages/com.unity.render-pipelines.high-definition/package.json
-
10Packages/com.unity.shadergraph/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs
-
2Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs
-
13Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector1MaterialSlot.cs
-
10Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector2MaterialSlot.cs
-
10Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector3MaterialSlot.cs
-
10Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector4MaterialSlot.cs
-
63Packages/com.unity.shadergraph/Editor/Data/Nodes/Channel/SwizzleNode.cs
-
10Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs
-
2Packages/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphAsset.cs
-
8Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs
-
16Packages/com.unity.shadergraph/Editor/ShaderGraphPreferences.cs
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8Billboard.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8CameraFacingLeafEffect.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8ColorAlpha.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8InterpolatedNormals.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8LODTransition.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8Wind.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree9CameraFacingLeafEffect.shadersubgraph.meta
-
1Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree9Wind.shadersubgraph.meta
-
2Packages/com.unity.shadergraph/package.json
-
6Packages/com.unity.ugui/Runtime/TMP/TMP_InputField.cs
-
61Packages/com.unity.ugui/Runtime/UGUI/UI/Core/Graphic.cs
-
6Packages/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs
-
5Packages/com.unity.ugui/Runtime/UGUI/UnityEngine.UI.asmdef
-
114Packages/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs
-
2Packages/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs.meta
-
137Packages/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs
-
2Packages/com.unity.ugui/package.json
-
1Packages/com.unity.visualeffectgraph/Editor/SamplesLinkPackageManagerExtension.cs
-
10Packages/com.unity.visualeffectgraph/Editor/ShaderGraph/Templates/VFXConfig.template.hlsl
-
2Packages/com.unity.visualeffectgraph/Editor/Utilities/pCache/BakeTool/PointCacheBakeTool.cs
-
6Packages/com.unity.visualeffectgraph/Shaders/ParticleLines/PassForwardCommon.template
-
6Packages/com.unity.visualeffectgraph/Shaders/ParticleLinesSW/PassForwardCommon.template
-
7Packages/com.unity.visualeffectgraph/Shaders/ParticleMeshes/PassForwardCommon.template
-
6Packages/com.unity.visualeffectgraph/Shaders/ParticlePlanarPrimitives/PassForwardCommon.template
-
6Packages/com.unity.visualeffectgraph/Shaders/ParticlePoints/PassForwardCommon.template
-
6Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl
-
8Packages/com.unity.visualeffectgraph/Shaders/VFXPassDepthCommonFragmentUnlit.template
-
2Packages/com.unity.visualeffectgraph/package.json
@ -0,0 +1,173 @@ |
|||||
|
using System.Buffers; |
||||
|
using System.Collections.Generic; |
||||
|
using Unity.Collections; |
||||
|
|
||||
|
namespace UnityEngine.Rendering |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Utility class that computes the total rect area via a sweep-line.
|
||||
|
/// </summary>
|
||||
|
public static class SweepLineRectUtils |
||||
|
{ |
||||
|
struct EventComparer : IComparer<Vector4> |
||||
|
{ |
||||
|
public int Compare(Vector4 a, Vector4 b) |
||||
|
{ |
||||
|
int cx = a.x.CompareTo(b.x); |
||||
|
if (cx != 0) return cx; |
||||
|
// tie on x: larger y first (+1 before -1)
|
||||
|
return b.y.CompareTo(a.y); |
||||
|
} |
||||
|
} |
||||
|
struct ActiveComparer : IComparer<Vector2> |
||||
|
{ |
||||
|
public int Compare(Vector2 a, Vector2 b) |
||||
|
{ |
||||
|
return a.x.CompareTo(b.x); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the total covered area (union) of a set of axis-aligned rectangles, counting overlaps only once.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rects">List of rects to compute.</param>
|
||||
|
/// <returns>The normalized union area in [0,1], with overlaps counted once.</returns>
|
||||
|
public static float CalculateRectUnionArea(List<Rect> rects) |
||||
|
{ |
||||
|
int rectsCount = rects.Count; |
||||
|
var eventsBuffer = ArrayPool<Vector4>.Shared.Rent(rectsCount * 2); |
||||
|
var activeBuffer = ArrayPool<Vector2>.Shared.Rent(rectsCount); |
||||
|
|
||||
|
int eventCount = 0; |
||||
|
foreach (var rect in rects) |
||||
|
InsertEvents(rect, eventsBuffer, ref eventCount); |
||||
|
|
||||
|
float area = CalculateRectUnionArea(eventsBuffer, activeBuffer, eventCount); |
||||
|
ArrayPool<Vector4>.Shared.Return(eventsBuffer); |
||||
|
ArrayPool<Vector2>.Shared.Return(activeBuffer); |
||||
|
|
||||
|
return area; |
||||
|
} |
||||
|
|
||||
|
// Merge overlapping intervals and return total covered Y length
|
||||
|
static float MergeLengthY(Vector2[] activeBuffer, int count) |
||||
|
{ |
||||
|
if (count <= 0) |
||||
|
return 0f; |
||||
|
|
||||
|
// ActiveBuffer stores (yMin, yMax)
|
||||
|
float total = 0f; |
||||
|
float cy0 = activeBuffer[0].x; |
||||
|
float cy1 = activeBuffer[0].y; |
||||
|
|
||||
|
for (int i = 1; i < count; i++) |
||||
|
{ |
||||
|
float y0 = activeBuffer[i].x; |
||||
|
float y1 = activeBuffer[i].y; |
||||
|
if (y0 <= cy1) |
||||
|
{ |
||||
|
if (y1 > cy1) cy1 = y1; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
total += (cy1 - cy0); |
||||
|
cy0 = y0; cy1 = y1; |
||||
|
} |
||||
|
} |
||||
|
total += (cy1 - cy0); |
||||
|
return Mathf.Clamp01(total); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the total covered area (union) of a set of axis-aligned rectangles using a sweep-line.
|
||||
|
/// </summary>
|
||||
|
static unsafe float CalculateRectUnionArea(Vector4[] eventsBuffer, Vector2[] activeBuffer, int eventCount) |
||||
|
{ |
||||
|
if (eventCount == 0) |
||||
|
return 0f; |
||||
|
|
||||
|
// Sort events by (x asc, enter first)
|
||||
|
fixed (Vector4* ptr = eventsBuffer) |
||||
|
{ |
||||
|
NativeSortExtension.Sort(ptr, eventCount, new EventComparer()); |
||||
|
} |
||||
|
|
||||
|
int activeCount = 0; |
||||
|
float area = 0f; |
||||
|
float lastX = eventsBuffer[0].x; |
||||
|
bool needLastXUpdate = false; |
||||
|
int i = 0; |
||||
|
|
||||
|
while (i < eventCount) |
||||
|
{ |
||||
|
float x = eventsBuffer[i].x; |
||||
|
|
||||
|
if (needLastXUpdate) |
||||
|
{ |
||||
|
lastX = x; |
||||
|
needLastXUpdate = false; |
||||
|
} |
||||
|
|
||||
|
// Accumulate area over [lastX, x)
|
||||
|
float dx = x - lastX; |
||||
|
if (dx > 0f && activeCount > 0) |
||||
|
{ |
||||
|
fixed (Vector2* ptr = activeBuffer) |
||||
|
{ |
||||
|
NativeSortExtension.Sort(ptr, activeCount, new ActiveComparer()); |
||||
|
} |
||||
|
area += MergeLengthY(activeBuffer, activeCount) * dx; |
||||
|
lastX = x; |
||||
|
} |
||||
|
|
||||
|
// Consume all events at this x (group approx-equal x's)
|
||||
|
do |
||||
|
{ |
||||
|
Vector4 ev = eventsBuffer[i]; |
||||
|
float y0 = ev.z; |
||||
|
float y1 = ev.w; |
||||
|
|
||||
|
if (ev.y > 0f) // Enter
|
||||
|
{ |
||||
|
activeBuffer[activeCount++] = new Vector2(y0, y1); |
||||
|
} |
||||
|
else // Leave
|
||||
|
{ |
||||
|
// Remove once (swap with last)
|
||||
|
for (int k = 0; k < activeCount; k++) |
||||
|
{ |
||||
|
Vector2 v = activeBuffer[k]; |
||||
|
if (Mathf.Approximately(v.x, y0) && Mathf.Approximately(v.y, y1)) |
||||
|
{ |
||||
|
int last = activeCount - 1; |
||||
|
activeBuffer[k] = activeBuffer[last]; |
||||
|
activeCount = last; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (activeCount == 0) |
||||
|
needLastXUpdate = true; |
||||
|
} |
||||
|
|
||||
|
i++; |
||||
|
} |
||||
|
while (i < eventCount && Mathf.Approximately(eventsBuffer[i].x, x)); |
||||
|
} |
||||
|
|
||||
|
return area; |
||||
|
} |
||||
|
|
||||
|
// Insert events with clamped rects
|
||||
|
static void InsertEvents(in Rect rect, Vector4[] eventsBuffer, ref int eventCount) |
||||
|
{ |
||||
|
if (rect.width > 0f && rect.height > 0f) |
||||
|
{ |
||||
|
var y0 = Mathf.Clamp01(rect.yMin); |
||||
|
var y1 = Mathf.Clamp01(rect.yMax); |
||||
|
eventsBuffer[eventCount++] = new Vector4(Mathf.Clamp01(rect.xMin), +1f, y0, y1); // enter
|
||||
|
eventsBuffer[eventCount++] = new Vector4(Mathf.Clamp01(rect.xMax), -1f, y0, y1); // leave
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: ff1aad7bfc102a847b1979aebf787494 |
||||
@ -0,0 +1,184 @@ |
|||||
|
using NUnit.Framework; |
||||
|
using System.Collections.Generic; |
||||
|
using UnityEngine; |
||||
|
using UnityEngine.Rendering; |
||||
|
|
||||
|
namespace UnityEditor.Rendering.Tests |
||||
|
{ |
||||
|
class SweepLineRectUtilsTests |
||||
|
{ |
||||
|
const float Epsilon = 1e-5f; |
||||
|
|
||||
|
static object[][] s_Empty = new object[][] |
||||
|
{ |
||||
|
new object[] { new List<Rect>() } |
||||
|
}; |
||||
|
|
||||
|
[Test] |
||||
|
[TestCaseSource("s_Empty")] |
||||
|
public void TestEmpty(List<Rect> rects) |
||||
|
{ |
||||
|
var area = SweepLineRectUtils.CalculateRectUnionArea(rects); |
||||
|
Assert.That(area, Is.EqualTo(0f).Within(Epsilon)); |
||||
|
} |
||||
|
|
||||
|
static object[][] s_SingleRect = new object[][] |
||||
|
{ |
||||
|
new object[] { new Rect(0.1f, 0.2f, 0.3f, 0.4f), 0.12f }, |
||||
|
new object[] { new Rect(0f, 0f, 1f, 1f), 1f }, |
||||
|
}; |
||||
|
|
||||
|
[Test] |
||||
|
[TestCaseSource("s_SingleRect")] |
||||
|
public void SingleRect(Rect r, float expected) |
||||
|
{ |
||||
|
var area = SweepLineRectUtils.CalculateRectUnionArea(new List<Rect> { r }); |
||||
|
Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); |
||||
|
} |
||||
|
|
||||
|
static object[][] s_NonOverlapping = new object[][] |
||||
|
{ |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> { new Rect(0f, 0f, 0.5f, 0.5f), new Rect(0.5f, 0.5f, 0.5f, 0.5f) }, 0.5f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0f, 0f, 0.2f, 0.2f), // 0.04
|
||||
|
new Rect(0.2f, 0f, 0.3f, 0.2f), // 0.06
|
||||
|
new Rect(0.5f, 0.5f, 0.25f, 0.25f) // 0.0625
|
||||
|
}, |
||||
|
0.1625f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> { new Rect(0f, 0f, 0.5f, 1f), new Rect(0.5f, 0f, 0.5f, 1f) }, 1f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> { new Rect(0.2f, 0.2f, 0f, 0.5f), new Rect(0.2f, 0.2f, 0.5f, 0f) }, 0f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> { new Rect(0f, 0f, 0f, 0f), new Rect(0.1f, 0.1f, 0.2f, 0.3f) }, 0.06f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0f, 0.3f, 0.3f, 0.3f), |
||||
|
new Rect(0.6f, 0.3f, 0.3f, 0.3f), |
||||
|
new Rect(0.3f, 0.3f, 0.3f, 0.3f), |
||||
|
new Rect(0f, 0.6f, 0.3f, 0.3f), |
||||
|
new Rect(0.7f, 0.7f, 0.3f, 0.3f), |
||||
|
}, |
||||
|
0.45f |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
[Test] |
||||
|
[TestCaseSource("s_NonOverlapping")] |
||||
|
public void NonOverlappingRects(List<Rect> rects, float expected) |
||||
|
{ |
||||
|
var area = SweepLineRectUtils.CalculateRectUnionArea(rects); |
||||
|
Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); |
||||
|
} |
||||
|
|
||||
|
static object[][] s_Overlapping = new object[][] |
||||
|
{ |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0.2f, 0.2f, 0.4f, 0.3f), |
||||
|
new Rect(0.2f, 0.2f, 0.4f, 0.3f) |
||||
|
}, |
||||
|
0.4f * 0.3f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0f, 0f, 0.6f, 0.5f), |
||||
|
new Rect(0.3f, 0f, 0.6f, 0.5f) |
||||
|
}, |
||||
|
0.9f * 0.5f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0f, 0.3f, 0.4f, 0.4f), |
||||
|
new Rect(0.6f, 0.3f, 0.4f, 0.4f), |
||||
|
new Rect(0.3f, 0f, 0.4f, 0.4f), |
||||
|
new Rect(0.3f, 0.6f, 0.4f, 0.4f) |
||||
|
}, |
||||
|
0.64f - 0.04f |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
[Test] |
||||
|
[TestCaseSource("s_Overlapping")] |
||||
|
public void OverlappingRects(List<Rect> rects, float expected) |
||||
|
{ |
||||
|
var area = SweepLineRectUtils.CalculateRectUnionArea(rects); |
||||
|
Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); |
||||
|
} |
||||
|
|
||||
|
static object[][] s_ClampingOutside = new object[][] |
||||
|
{ |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(-0.2f, -0.2f, 0.3f, 0.3f), // clamps to [0,0,0.1,0.1] area 0.01
|
||||
|
new Rect(0.9f, 0.9f, 0.5f, 0.5f), // clamps to [0.9,0.9,0.1,0.1] area 0.01
|
||||
|
}, |
||||
|
0.02f |
||||
|
}, |
||||
|
new object[] { new List<Rect> { new Rect(-10f, -10f, 20f, 20f) }, 1f } |
||||
|
}; |
||||
|
|
||||
|
[Test] |
||||
|
[TestCaseSource("s_ClampingOutside")] |
||||
|
public void ClampingOutside(List<Rect> rects, float expected) |
||||
|
{ |
||||
|
var area = SweepLineRectUtils.CalculateRectUnionArea(rects); |
||||
|
Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); |
||||
|
} |
||||
|
|
||||
|
static object[][] s_IntervalsSorting = new object[][] |
||||
|
{ |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0.0f, 0.2f, 0.2f, 0.2f), |
||||
|
new Rect(0.0f, 0.0f, 0.2f, 0.1f), |
||||
|
new Rect(0.0f, 0.3f, 0.2f, 0.2f), |
||||
|
}, |
||||
|
0.2f * 0.4f |
||||
|
}, |
||||
|
new object[] |
||||
|
{ |
||||
|
new List<Rect> |
||||
|
{ |
||||
|
new Rect(0.0f, 0.0f, 0.2f, 0.1f), |
||||
|
new Rect(0.3f, 0.0f, 0.3f, 0.1f), |
||||
|
new Rect(0.5f, 0.0f, 0.2f, 0.1f), |
||||
|
}, |
||||
|
0.6f * 0.1f |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
[Test] |
||||
|
[TestCaseSource("s_IntervalsSorting")] |
||||
|
public void IntervalsSorting(List<Rect> rects, float expected) |
||||
|
{ |
||||
|
var area = SweepLineRectUtils.CalculateRectUnionArea(rects); |
||||
|
Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: bfba7561301ac2a44b010c12825cd189 |
||||
@ -0,0 +1,114 @@ |
|||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
using NUnit.Framework; |
||||
|
using UnityEngine; |
||||
|
using UnityEngine.EventSystems; |
||||
|
using UnityEngine.TestTools; |
||||
|
using UnityEngine.UI; |
||||
|
|
||||
|
internal class GraphicRaycasterButtonTests |
||||
|
{ |
||||
|
Camera m_Camera; |
||||
|
EventSystem m_EventSystem; |
||||
|
Canvas m_Canvas; |
||||
|
Button m_ParentButton; |
||||
|
Button m_ChildButton; |
||||
|
Sprite m_Sprite; |
||||
|
|
||||
|
const int TextureSize = 64; |
||||
|
readonly Texture2D texture = new Texture2D(TextureSize, TextureSize); |
||||
|
|
||||
|
[UnitySetUp] |
||||
|
public IEnumerator TestSetup() |
||||
|
{ |
||||
|
m_Camera = new GameObject("Camera").AddComponent<Camera>(); |
||||
|
m_Camera.transform.position = new Vector3(0, 0, -10); |
||||
|
|
||||
|
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>(); |
||||
|
m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay; |
||||
|
m_Canvas.gameObject.AddComponent<GraphicRaycaster>(); |
||||
|
|
||||
|
m_EventSystem = new GameObject("Event System").AddComponent<EventSystem>(); |
||||
|
|
||||
|
Color[] colors = new Color[TextureSize * TextureSize]; |
||||
|
for (int y = 24; y < 40; y++) |
||||
|
for (int x = 0; x < TextureSize; x++) |
||||
|
colors[y + TextureSize * x] = colors[x + TextureSize * y] = Color.red; |
||||
|
texture.SetPixels(colors); |
||||
|
texture.Apply(); |
||||
|
|
||||
|
m_Sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100); |
||||
|
|
||||
|
var parentImage = new GameObject("ParentButton", typeof(RectTransform)).AddComponent<Image>(); |
||||
|
parentImage.transform.SetParent(m_Canvas.transform); |
||||
|
parentImage.rectTransform.anchoredPosition = new Vector2(0, 0); |
||||
|
parentImage.sprite = m_Sprite; |
||||
|
parentImage.SetNativeSize(); |
||||
|
m_ParentButton = parentImage.gameObject.AddComponent<Button>(); |
||||
|
|
||||
|
// Duplicate Button as a child GO
|
||||
|
m_ChildButton = Object.Instantiate(m_ParentButton, m_ParentButton.transform); |
||||
|
m_ChildButton.name = "ChildButton"; |
||||
|
var childImage = m_ChildButton.GetComponent<Image>(); |
||||
|
childImage.rectTransform.anchoredPosition = new Vector2(8, 50); |
||||
|
|
||||
|
parentImage.alphaHitTestMinimumThreshold = 0.5f; |
||||
|
childImage.alphaHitTestMinimumThreshold = 0.5f; |
||||
|
|
||||
|
// Yield one frame so that all tests below work.
|
||||
|
yield return null; |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[TestCase( 0f, -40f, false, false, TestName = "Should not hit either button (outside of both boundaries)")] |
||||
|
[TestCase( 0f, 0f, true, false, TestName = "Should hit the parent (opaque pixel), but not the child (outside)")] |
||||
|
[TestCase(-30f, -30f, false, false, TestName = "Should not hit the parent (transparent pixel), nor the child (outside)")] |
||||
|
[TestCase( 10f, 30f, false, true, TestName = "Should not hit the parent (transparent pixel), but hit the child (opaque pixel),")] |
||||
|
[TestCase( 5f, 30f, true, true, TestName = "Should hit the parent (opaque pixel), and the child (opaque pixel)")] |
||||
|
[TestCase( -5f, 30f, true, false, TestName = "Should hit the parent (opaque pixel), but not the child (transparent pixel)")] |
||||
|
[TestCase(-10f, 30f, false, false, TestName = "Should not hit the parent (transparent pixel), nor the child (transparent pixel)")] |
||||
|
[TestCase( 8f, 50f, false, true, TestName = "Should not hit the parent (outside), but hit the child (opaque pixel)")] |
||||
|
[TestCase(-10f, 30f, false, false, TestName = "Should not hit the parent (outside), nor the child (transparent pixel)")] |
||||
|
public void GraphicRaycaster_ChildButtonOutsideOfParentButton(float x, float y, bool hitParent, bool hitChild) |
||||
|
{ |
||||
|
var results = new List<RaycastResult>(); |
||||
|
var pointerEvent = new PointerEventData(m_EventSystem) |
||||
|
{ |
||||
|
position = new Vector2(Screen.width / 2f + x, Screen.height / 2f + y) |
||||
|
}; |
||||
|
|
||||
|
m_EventSystem.RaycastAll(pointerEvent, results); |
||||
|
|
||||
|
|
||||
|
if (hitParent == false && hitChild == false) |
||||
|
{ |
||||
|
Assert.IsEmpty(results, "Expected no results from a raycast."); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (hitParent && hitChild) |
||||
|
Assert.AreEqual(2, results.Count, "Expected 2 results from a raycast."); |
||||
|
else |
||||
|
Assert.AreEqual(1, results.Count, "Expected 1 result from a raycast."); |
||||
|
|
||||
|
int hitIndex = 0; |
||||
|
if (hitChild) |
||||
|
{ |
||||
|
Assert.AreSame(m_ChildButton.gameObject, results[hitIndex].gameObject); |
||||
|
hitIndex++; |
||||
|
} |
||||
|
if (hitParent) |
||||
|
{ |
||||
|
Assert.AreSame(m_ParentButton.gameObject, results[hitIndex].gameObject); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[TearDown] |
||||
|
public void TearDown() |
||||
|
{ |
||||
|
Object.DestroyImmediate(m_Camera.gameObject); |
||||
|
Object.DestroyImmediate(m_EventSystem.gameObject); |
||||
|
Object.DestroyImmediate(m_Canvas.gameObject); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 53ee1d135588bf447a7af7ba2e8709d7 |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue