using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Rendering; namespace ProBuilder2.Common { // Token: 0x0200003C RID: 60 public static class pb_SelectionPicker { // Token: 0x17000034 RID: 52 // (get) Token: 0x060001EC RID: 492 RVA: 0x00018520 File Offset: 0x00016920 private static RenderTextureFormat renderTextureFormat { get { if (pb_SelectionPicker.m_Initialized) { return pb_SelectionPicker.m_RenderTextureFormat; } pb_SelectionPicker.m_Initialized = true; for (int i = 0; i < pb_SelectionPicker.m_PreferredFormats.Length; i++) { if (SystemInfo.SupportsRenderTextureFormat(pb_SelectionPicker.m_PreferredFormats[i])) { pb_SelectionPicker.m_RenderTextureFormat = pb_SelectionPicker.m_PreferredFormats[i]; break; } } return pb_SelectionPicker.m_RenderTextureFormat; } } // Token: 0x17000035 RID: 53 // (get) Token: 0x060001ED RID: 493 RVA: 0x00018582 File Offset: 0x00016982 private static TextureFormat textureFormat { get { return TextureFormat.ARGB32; } } // Token: 0x060001EE RID: 494 RVA: 0x00018588 File Offset: 0x00016988 public static Dictionary> PickFacesInRect(Camera camera, Rect pickerRect, IEnumerable selection, int renderTextureWidth = -1, int renderTextureHeight = -1) { Dictionary> dictionary; Texture2D texture2D = pb_SelectionPicker.RenderSelectionPickerTexture(camera, selection, out dictionary, renderTextureWidth, renderTextureHeight); Color32[] pixels = texture2D.GetPixels32(); int num = Math.Max(0, Mathf.FloorToInt(pickerRect.x)); int num2 = Math.Max(0, Mathf.FloorToInt((float)texture2D.height - pickerRect.y - pickerRect.height)); int width = texture2D.width; int height = texture2D.height; int num3 = Mathf.FloorToInt(pickerRect.width); int num4 = Mathf.FloorToInt(pickerRect.height); global::UnityEngine.Object.DestroyImmediate(texture2D); Dictionary> dictionary2 = new Dictionary>(); HashSet hashSet = null; HashSet hashSet2 = new HashSet(); for (int i = num2; i < Math.Min(num2 + num4, height); i++) { for (int j = num; j < Math.Min(num + num3, width); j++) { uint num5 = pb_SelectionPicker.DecodeRGBA(pixels[i * width + j]); pb_Tuple pb_Tuple; if (hashSet2.Add(num5) && dictionary.TryGetValue(num5, out pb_Tuple)) { if (dictionary2.TryGetValue(pb_Tuple.Item1, out hashSet)) { hashSet.Add(pb_Tuple.Item2); } else { dictionary2.Add(pb_Tuple.Item1, new HashSet { pb_Tuple.Item2 }); } } } } return dictionary2; } // Token: 0x060001EF RID: 495 RVA: 0x000186F0 File Offset: 0x00016AF0 public static Dictionary> PickVerticesInRect(Camera camera, Rect pickerRect, IEnumerable selection, int renderTextureWidth = -1, int renderTextureHeight = -1) { Dictionary> dictionary = new Dictionary>(); Dictionary> dictionary2; Texture2D texture2D = pb_SelectionPicker.RenderSelectionPickerTexture(camera, selection, out dictionary2, renderTextureWidth, renderTextureHeight); Color32[] pixels = texture2D.GetPixels32(); int num = Math.Max(0, Mathf.FloorToInt(pickerRect.x)); int num2 = Math.Max(0, Mathf.FloorToInt((float)texture2D.height - pickerRect.y - pickerRect.height)); int width = texture2D.width; int height = texture2D.height; int num3 = Mathf.FloorToInt(pickerRect.width); int num4 = Mathf.FloorToInt(pickerRect.height); global::UnityEngine.Object.DestroyImmediate(texture2D); HashSet hashSet = null; HashSet hashSet2 = new HashSet(); for (int i = num2; i < Math.Min(num2 + num4, height); i++) { for (int j = num; j < Math.Min(num + num3, width); j++) { uint num5 = pb_SelectionPicker.DecodeRGBA(pixels[i * width + j]); pb_Tuple pb_Tuple; if (hashSet2.Add(num5) && dictionary2.TryGetValue(num5, out pb_Tuple)) { if (dictionary.TryGetValue(pb_Tuple.Item1, out hashSet)) { hashSet.Add(pb_Tuple.Item2); } else { dictionary.Add(pb_Tuple.Item1, new HashSet { pb_Tuple.Item2 }); } } } } return dictionary; } // Token: 0x060001F0 RID: 496 RVA: 0x00018854 File Offset: 0x00016C54 public static Texture2D RenderSelectionPickerTexture(Camera camera, IEnumerable selection, out Dictionary> map, int width = -1, int height = -1) { List list = pb_SelectionPicker.GenerateFaceDepthTestMeshes(selection, out map); Texture2D texture2D = pb_SelectionPicker.RenderWithReplacementShader(camera, pb_Constant.SelectionPickerShader, "ProBuilderPicker", width, height); foreach (GameObject gameObject in list) { global::UnityEngine.Object.DestroyImmediate(gameObject.GetComponent().sharedMesh); global::UnityEngine.Object.DestroyImmediate(gameObject); } return texture2D; } // Token: 0x060001F1 RID: 497 RVA: 0x000188D8 File Offset: 0x00016CD8 public static Texture2D RenderSelectionPickerTexture(Camera camera, IEnumerable selection, out Dictionary> map, int width = -1, int height = -1) { List list = pb_SelectionPicker.GenerateVertexDepthTestMeshes(selection, out map); Texture2D texture2D = pb_SelectionPicker.RenderWithReplacementShader(camera, pb_Constant.SelectionPickerShader, "ProBuilderPicker", width, height); foreach (GameObject gameObject in list) { global::UnityEngine.Object.DestroyImmediate(gameObject.GetComponent().sharedMesh); global::UnityEngine.Object.DestroyImmediate(gameObject); } return texture2D; } // Token: 0x060001F2 RID: 498 RVA: 0x0001895C File Offset: 0x00016D5C public static List GenerateFaceDepthTestMeshes(IEnumerable selection, out Dictionary> map) { List list = new List(); map = new Dictionary>(); uint num = 0U; foreach (pb_Object pb_Object in selection) { GameObject gameObject = new GameObject(); gameObject.name = pb_Object.name + " (Face Depth Test)"; gameObject.transform.position = pb_Object.transform.position; gameObject.transform.localRotation = pb_Object.transform.localRotation; gameObject.transform.localScale = pb_Object.transform.localScale; Mesh mesh = new Mesh(); mesh.vertices = pb_Object.vertices; mesh.triangles = pb_Object.faces.SelectMany((pb_Face x) => x.indices).ToArray(); Color32[] array = new Color32[mesh.vertexCount]; foreach (pb_Face pb_Face in pb_Object.faces) { Color32 color = pb_SelectionPicker.EncodeRGBA(num++); map.Add(pb_SelectionPicker.DecodeRGBA(color), new pb_Tuple(pb_Object, pb_Face)); for (int j = 0; j < pb_Face.distinctIndices.Length; j++) { array[pb_Face.distinctIndices[j]] = color; } } mesh.colors32 = array; try { gameObject.AddComponent().sharedMesh = mesh; gameObject.AddComponent().sharedMaterial = pb_Constant.FacePickerMaterial; } catch { Debug.LogWarning("Could not find shader `pb_FacePicker.shader`. Please re-import ProBuilder to fix!"); } list.Add(gameObject); } return list; } // Token: 0x060001F3 RID: 499 RVA: 0x00018B5C File Offset: 0x00016F5C private static List GenerateVertexDepthTestMeshes(IEnumerable selection, out Dictionary> map) { List list = new List(); map = new Dictionary>(); Color32 color = new Color32(0, 0, 0, byte.MaxValue); uint num = 2U; foreach (pb_Object pb_Object in selection) { GameObject gameObject = pbUtil.EmptyGameObjectWithTransform(pb_Object.transform); gameObject.name = pb_Object.name + " (Depth Mask)"; Mesh mesh = new Mesh(); mesh.vertices = pb_Object.vertices; mesh.triangles = pb_Object.faces.SelectMany((pb_Face x) => x.indices).ToArray(); mesh.colors32 = pbUtil.Fill(color, pb_Object.vertexCount); gameObject.AddComponent().sharedMesh = mesh; gameObject.AddComponent().sharedMaterial = pb_Constant.FacePickerMaterial; list.Add(gameObject); GameObject gameObject2 = pbUtil.EmptyGameObjectWithTransform(pb_Object.transform); gameObject2.name = pb_Object.name + " (Vertex Billboards)"; gameObject2.AddComponent().sharedMesh = pb_SelectionPicker.BuildVertexMesh(pb_Object, map, ref num); gameObject2.AddComponent().sharedMaterial = pb_Constant.VertexPickerMaterial; list.Add(gameObject2); } return list; } // Token: 0x060001F4 RID: 500 RVA: 0x00018CD4 File Offset: 0x000170D4 private static Mesh BuildVertexMesh(pb_Object pb, Dictionary> map, ref uint index) { int num = Math.Min(pb.sharedIndices.Length, 16382); Vector3[] array = new Vector3[num * 4]; Vector2[] array2 = new Vector2[num * 4]; Vector2[] array3 = new Vector2[num * 4]; Color[] array4 = new Color[num * 4]; int[] array5 = new int[num * 6]; int num2 = 0; int num3 = 0; Vector3 up = Vector3.up; Vector3 right = Vector3.right; for (int i = 0; i < num; i++) { Vector3 vector = pb.vertices[pb.sharedIndices[i][0]]; array[num3] = vector; array[num3 + 1] = vector; array[num3 + 2] = vector; array[num3 + 3] = vector; array2[num3] = Vector3.zero; array2[num3 + 1] = Vector3.right; array2[num3 + 2] = Vector3.up; array2[num3 + 3] = Vector3.one; array3[num3] = -up - right; array3[num3 + 1] = -up + right; array3[num3 + 2] = up - right; array3[num3 + 3] = up + right; array5[num2] = num3; array5[num2 + 1] = num3 + 1; array5[num2 + 2] = num3 + 2; array5[num2 + 3] = num3 + 1; array5[num2 + 4] = num3 + 3; array5[num2 + 5] = num3 + 2; Color32 color = pb_SelectionPicker.EncodeRGBA(index); uint num4; index = (num4 = index) + 1U; map.Add(num4, new pb_Tuple(pb, i)); array4[num3] = color; array4[num3 + 1] = color; array4[num3 + 2] = color; array4[num3 + 3] = color; num3 += 4; num2 += 6; } return new Mesh { name = "Vertex Billboard", vertices = array, uv = array2, uv2 = array3, colors = array4, triangles = array5 }; } // Token: 0x060001F5 RID: 501 RVA: 0x00018F94 File Offset: 0x00017394 public static uint DecodeRGBA(Color32 color) { uint r = (uint)color.r; uint g = (uint)color.g; uint b = (uint)color.b; if (BitConverter.IsLittleEndian) { return (r << 16) | (g << 8) | b; } return (r << 24) | (g << 16) | (b << 8); } // Token: 0x060001F6 RID: 502 RVA: 0x00018FDC File Offset: 0x000173DC public static Color32 EncodeRGBA(uint hash) { if (BitConverter.IsLittleEndian) { return new Color32((byte)((hash >> 16) & 255U), (byte)((hash >> 8) & 255U), (byte)(hash & 255U), byte.MaxValue); } return new Color32((byte)((hash >> 24) & 255U), (byte)((hash >> 16) & 255U), (byte)((hash >> 8) & 255U), byte.MaxValue); } // Token: 0x060001F7 RID: 503 RVA: 0x00019048 File Offset: 0x00017448 private static Texture2D RenderWithReplacementShader(Camera camera, Shader shader, string tag, int width = -1, int height = -1) { bool flag = width < 0 || height < 0; int num = ((!flag) ? width : ((int)camera.pixelRect.width)); int num2 = ((!flag) ? height : ((int)camera.pixelRect.height)); GameObject gameObject = new GameObject(); Camera camera2 = gameObject.AddComponent(); camera2.CopyFrom(camera); camera2.renderingPath = RenderingPath.Forward; camera2.enabled = false; camera2.clearFlags = CameraClearFlags.Color; camera2.backgroundColor = Color.white; camera2.allowHDR = false; camera2.allowMSAA = false; camera2.forceIntoRenderTexture = true; RenderTextureDescriptor renderTextureDescriptor = new RenderTextureDescriptor { width = num, height = num2, colorFormat = pb_SelectionPicker.renderTextureFormat, autoGenerateMips = false, depthBufferBits = 16, dimension = TextureDimension.Tex2D, enableRandomWrite = false, memoryless = RenderTextureMemoryless.None, sRGB = false, useMipMap = false, volumeDepth = 1, msaaSamples = 1 }; RenderTexture temporary = RenderTexture.GetTemporary(renderTextureDescriptor); RenderTexture active = RenderTexture.active; camera2.targetTexture = temporary; RenderTexture.active = temporary; camera2.RenderWithShader(shader, tag); Texture2D texture2D = new Texture2D(num, num2, pb_SelectionPicker.textureFormat, false, false); texture2D.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0); texture2D.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); global::UnityEngine.Object.DestroyImmediate(gameObject); return texture2D; } // Token: 0x0400016F RID: 367 private static bool m_Initialized = false; // Token: 0x04000170 RID: 368 private static RenderTextureFormat m_RenderTextureFormat = RenderTextureFormat.Default; // Token: 0x04000171 RID: 369 private static RenderTextureFormat[] m_PreferredFormats = new RenderTextureFormat[] { RenderTextureFormat.ARGB32, RenderTextureFormat.ARGBFloat }; } }