private void OnEnable()
        {
            titleContent.image = Icons.quicksearch;
            titleContent.text  = "Quick Search Setup";

            rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(Utils.GetPackagePath("Editor/StyleSheets/OnBoarding.uss")));
            if (EditorGUIUtility.isProSkin)
            {
                rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(Utils.GetPackagePath("Editor/StyleSheets/OnBoarding_Dark.uss")));
            }
            else
            {
                rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(Utils.GetPackagePath("Editor/StyleSheets/OnBoarding_Light.uss")));
            }
            rootVisualElement.AddToClassList("index-manager-variables");

            var container = new VisualElement()
            {
                name = "Container"
            };

            rootVisualElement.Add(container);
            container.Add(new Label("Choose the size of your project. This will help select the most suited settings for your project."));

            var containerSizeProject = new VisualElement()
            {
                name = "ContainerSizeProject"
            };

            containerSizeProject.style.flexDirection = FlexDirection.Row;

            var toggleGroupIndex    = new List <IndexToggle>();
            var extendedIndexToggle = new IndexToggle("Extended", toggleGroupIndex, new IndexCreationInfo(IndexToCreateType.Extended));

            toggleGroupIndex.Add(new IndexToggle("Minimal", toggleGroupIndex, new IndexCreationInfo(IndexToCreateType.Minimal)));
            toggleGroupIndex.Add(new IndexToggle("Default", toggleGroupIndex, new IndexCreationInfo(IndexToCreateType.Default))
            {
                value = true
            });
            toggleGroupIndex.Add(extendedIndexToggle);
            var toggleGroup = new List <ProjectSizeToggle>();

            toggleGroup.Add(new ProjectSizeToggle("Small", "A project that contains less than 1000 assets.", toggleGroup, ProjectSize.Small, null));
            toggleGroup.Add(new ProjectSizeToggle("Medium", "Seems reasonable.", toggleGroup, ProjectSize.Medium, null)
            {
                value = true
            });
            toggleGroup.Add(new ProjectSizeToggle("Large", "A project that contains more than 20000 assets.", toggleGroup, ProjectSize.Large, extendedIndexToggle));

            containerSizeProject.Add(toggleGroup[0]);
            containerSizeProject.Add(toggleGroup[1]);
            containerSizeProject.Add(toggleGroup[2]);

            container.Add(containerSizeProject);
            container.Add(new Label("Choose which indexing option you prefer. Indexing your assets will provide better search capabilities. Note that the more options you select, the longer it will take to create your first index."));

            var containerIndex = new VisualElement()
            {
                name = "ContainerIndex"
            };

            containerIndex.style.flexDirection = FlexDirection.Row;
            containerIndex.Add(toggleGroupIndex[0]);
            containerIndex.Add(toggleGroupIndex[1]);
            containerIndex.Add(toggleGroupIndex[2]);

            container.Add(containerIndex);

            var containerButtons = new VisualElement()
            {
                name = "ContainerButtons"
            };

            containerButtons.style.flexDirection = FlexDirection.Row;
            containerButtons.Add(FlexibleSpace());
            containerButtons.Add(new Button(() => OnFinish(toggleGroup, toggleGroupIndex))
            {
                name = "FinishButton", text = "Finish"
            });
            containerButtons.Add(new Button(Close)
            {
                name = "CancelButton", text = "Cancel"
            });

            container.Add(containerButtons);
        }
        static MeshImportJob ImportMesh <T>(SyncMesh syncMesh)
            where T : struct
        {
            var data = new MeshImportJob {
                SyncMesh = syncMesh
            };
            var toggle = new IndexToggle <T>(data);

            var count = syncMesh.Vertices.Count;

            data.Vertices = new Vertex[count];

            for (var i = 0; i < count; ++i)
            {
                var v = syncMesh.Vertices[i];
                data.Vertices[i].Position = new Vector3(v.X, v.Y, v.Z);
            }

            count = syncMesh.Normals.Count;
            for (var i = 0; i < count; ++i)
            {
                var n = syncMesh.Normals[i];
                data.Vertices[i].Normal = new Vector3(n.X, n.Y, n.Z);
            }

            count = syncMesh.Uvs.Count;
            for (var i = 0; i < count; ++i)
            {
                var u = syncMesh.Uvs[i];
                data.Vertices[i].UV = new Vector2(u.X, u.Y);
            }

            var subMeshCount = syncMesh.SubMeshes.Count;
            var nbIndices    = syncMesh.SubMeshes.Sum(x => x.Triangles.Count);

            toggle.InstantiateArray(nbIndices);

            data.SubMeshStarts  = new int[syncMesh.SubMeshes.Count];
            data.SubMeshLengths = new int[syncMesh.SubMeshes.Count];

            var offset = 0;

            for (var i = 0; i < subMeshCount; ++i)
            {
                count = syncMesh.SubMeshes[i].Triangles.Count;

                data.SubMeshStarts[i]  = offset;
                data.SubMeshLengths[i] = count;

                var index = 0;
                foreach (var triangleIndex in syncMesh.SubMeshes[i].Triangles)
                {
                    toggle.Set(offset + index++, triangleIndex);
                }

                offset += count;
            }

            CalculateBounds(data);
            CalculateMeshTangents(data, toggle);

            return(data);
        }
 public ProjectSizeToggle(string title, string description, IEnumerable <ToggleWithTitleAndDescription> toggleGroup, ProjectSize projectSize, IndexToggle extendedIndexToggle) : base(title, description, toggleGroup)
 {
     this.m_ExtendedIndexToggle = extendedIndexToggle;
     this.projectSize           = projectSize;
 }
        static void CalculateMeshTangents <T>(MeshImportJob jobData, IndexToggle <T> toggle) where T : struct
        {
            // Todo: Validate that this function is yielding the same result as the internal unity function
            var vertices = jobData.Vertices;

            var triangleCount = toggle.GetLength();
            var vertexCount   = vertices.Length;

            var tan1 = new Vector3[vertexCount];
            var tan2 = new Vector3[vertexCount];

            for (long a = 0; a < triangleCount; a += 3)
            {
                long i1 = toggle.Get(a + 0);
                long i2 = toggle.Get(a + 1);
                long i3 = toggle.Get(a + 2);

                var v1 = vertices[i1].Position;
                var v2 = vertices[i2].Position;
                var v3 = vertices[i3].Position;

                var w1 = vertices[i1].UV;
                var w2 = vertices[i2].UV;
                var w3 = vertices[i3].UV;

                var x1 = v2.x - v1.x;
                var x2 = v3.x - v1.x;
                var y1 = v2.y - v1.y;
                var y2 = v3.y - v1.y;
                var z1 = v2.z - v1.z;
                var z2 = v3.z - v1.z;

                var s1 = w2.x - w1.x;
                var s2 = w3.x - w1.x;
                var t1 = w2.y - w1.y;
                var t2 = w3.y - w1.y;

                var div = s1 * t2 - s2 * t1;
                var r   = div == 0.0f ? 0.0f : 1.0f / (s1 * t2 - s2 * t1);

                var sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
                var tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

                tan1[i1] += sdir;
                tan1[i2] += sdir;
                tan1[i3] += sdir;

                tan2[i1] += tdir;
                tan2[i2] += tdir;
                tan2[i3] += tdir;
            }

            for (long a = 0; a < vertexCount; ++a)
            {
                var n = vertices[a].Normal;
                var t = tan1[a];

                Vector3.OrthoNormalize(ref n, ref t);
                vertices[a].Tangent.Set(t.x, t.y, t.z, Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f ? -1.0f : 1.0f);
            }
        }