Exemplo n.º 1
0
    void OnPostprocessModel(GameObject g)
    {
        Init();
        //if (storage == null) return;

        ModelImporter importer = (ModelImporter)assetImporter;

        if (importer.generateSecondaryUV)
        {
            // Auto UVs: Adjust UV padding per mesh
            //if (!storage.modifiedAssetPathList.Contains(assetPath) && g.tag == "BakeryProcessed") return;
            //if (ftLightmaps.IsModelProcessed(assetPath)) return;

            //g.tag = "BakeryProcessed";
            Debug.Log("Bakery: processing auto-unwrapped asset " + assetPath);
            if (storage != null)
            {
                ftLightmaps.MarkModelProcessed(assetPath, true);
            }

            uparams = new UnwrapParam();
            UnwrapParam.SetDefaults(out uparams);
            uparams.angleError = importer.secondaryUVAngleDistortion * 0.01f;
            uparams.areaError  = importer.secondaryUVAreaDistortion * 0.01f;
            uparams.hardAngle  = importer.secondaryUVHardAngle;

#if UNITY_2017_1_OR_NEWER
            deserializedSuccess = false;
            var props = importer.extraUserProperties;
            for (int p = 0; p < props.Length; p++)
            {
                if (props[p].Substring(0, 7) == "#BAKERY")
                {
                    var json = props[p].Substring(7);
                    deserialized        = JsonUtility.FromJson <ftGlobalStorage.AdjustedMesh>(json);
                    deserializedSuccess = true;
                    break;
                }
            }
#endif
            if (storage != null)
            {
                storage.InitModifiedMeshMap(assetPath);
            }

            AdjustUV(g.transform);
        }
        else
        {
            if (storage == null)
            {
                return;
            }

            Debug.Log("Bakery: checking for UV overlaps in " + assetPath);

            //if (g.tag == "BakeryProcessed") g.tag = "";
            ftLightmaps.MarkModelProcessed(assetPath, true);//false);

            // Manual UVs: check if overlapping
            CheckUVOverlap(g, assetPath);
        }

        if (g.tag == "BakeryProcessed")
        {
            g.tag = "";                             // remove legacy mark
        }
    }
 public virtual void UnwrapXatlas(Mesh m, UnwrapParam param)
 {
 }
        /// <summary>
        /// Optmizes the mesh geometry, and generates a UV2 channel (if object is marked as LightmapStatic, or generateLightmapUVs is true).
        /// </summary>
        /// <remarks>This is only applicable to meshes with triangle topology. Quad meshes are not affected by this function.</remarks>
        /// <param name="mesh">The ProBuilder mesh component to be optimized.</param>
        /// <param name="generateLightmapUVs">If the Auto UV2 preference is disabled this parameter can be used to force UV2s to be built.</param>
        public static void Optimize(this ProBuilderMesh mesh, bool generateLightmapUVs = false)
        {
            if (mesh == null)
            {
                throw new ArgumentNullException("mesh");
            }

            Mesh umesh = mesh.mesh;

            if (umesh == null || umesh.vertexCount < 1)
            {
                return;
            }

            bool skipMeshProcessing = false;

            // @todo Support mesh compression for topologies other than Triangles.
            for (int i = 0; !skipMeshProcessing && i < umesh.subMeshCount; i++)
            {
                if (umesh.GetTopology(i) != MeshTopology.Triangles)
                {
                    skipMeshProcessing = true;
                }
            }

            if (!skipMeshProcessing)
            {
                bool autoLightmap = Lightmapping.autoUnwrapLightmapUV;

#if UNITY_2019_2_OR_NEWER
                bool lightmapUVs = generateLightmapUVs || (autoLightmap && mesh.gameObject.HasStaticFlag(StaticEditorFlags.ContributeGI));
#else
                bool lightmapUVs = generateLightmapUVs || (autoLightmap && mesh.gameObject.HasStaticFlag(StaticEditorFlags.LightmapStatic));
#endif

                var usedInParticuleSystem = UnityEngine.ProBuilder.MeshUtility.IsUsedInParticleSystem(mesh);

                // if generating UV2, the process is to manually split the mesh into individual triangles,
                // generate uv2, then re-assemble with vertex collapsing where possible.
                // if not generating uv2, just collapse vertices.
                if (lightmapUVs)
                {
                    Vertex[] vertices = UnityEngine.ProBuilder.MeshUtility.GeneratePerTriangleMesh(umesh);

                    float time = Time.realtimeSinceStartup;

                    UnwrapParam unwrap = Lightmapping.GetUnwrapParam(mesh.unwrapParameters);

                    Vector2[] uv2 = Unwrapping.GeneratePerTriangleUV(umesh, unwrap);

                    // If GenerateUV2() takes longer than 3 seconds (!), show a warning prompting user to disable auto-uv2 generation.
                    if ((Time.realtimeSinceStartup - time) > 3f)
                    {
                        Log.Warning(string.Format("Generate UV2 for \"{0}\" took {1} seconds! You may want to consider disabling Auto-UV2 generation in the `Preferences > ProBuilder` tab.", mesh.name, (Time.realtimeSinceStartup - time).ToString("F2")));
                    }

                    if (uv2.Length == vertices.Length)
                    {
                        for (int i = 0; i < uv2.Length; i++)
                        {
                            vertices[i].uv2 = uv2[i];
                        }
                    }
                    else
                    {
                        Log.Warning("Generate UV2 failed. The returned size of UV2 array != mesh.vertexCount");
                    }

                    UnityEngine.ProBuilder.MeshUtility.CollapseSharedVertices(umesh, vertices);
                }
                else
                {
                    UnityEngine.ProBuilder.MeshUtility.CollapseSharedVertices(umesh);
                }

                if (usedInParticuleSystem)
                {
                    UnityEngine.ProBuilder.MeshUtility.RestoreParticleSystem(mesh);
                }
            }

            if (s_AutoResizeCollisions)
            {
                RebuildColliders(mesh);
            }

            if (meshOptimized != null)
            {
                meshOptimized(mesh, umesh);
            }

            if (Experimental.meshesAreAssets)
            {
                TryCacheMesh(mesh);
            }

            UnityEditor.EditorUtility.SetDirty(mesh);
        }
Exemplo n.º 4
0
        internal static void GenerateLightmapUVsForSelectedMeshFilters(UnwrapParam unwrapParam, bool includeChildren = false)
        {
            List <Mesh>             meshesToUpdate = new List <Mesh>();
            Dictionary <Mesh, Mesh> meshes         = new Dictionary <Mesh, Mesh>();
            var meshFilters = includeChildren ?
                              Selection.GetFiltered <MeshFilter>(SelectionMode.OnlyUserModifiable | SelectionMode.Deep) :
                              Selection.GetFiltered <MeshFilter>(SelectionMode.OnlyUserModifiable);

            if (meshFilters.Length == 0)
            {
                return;
            }

            var undoLvl = Undo.GetCurrentGroup();

            Undo.SetCurrentGroupName("Generate Lightmap UVs");

            for (int i = 0; i < meshFilters.Length; i++)
            {
                EditorUtility.DisplayProgressBar("Unwrapping Lightmap UVs", meshFilters[i].gameObject.name, (float)i / (float)meshFilters.Length);
                Undo.RecordObject(meshFilters[i], "Unwrap");

                // updating existing meshes
                var path = AssetDatabase.GetAssetPath(meshFilters[i].sharedMesh);
                if (Path.GetExtension(path) != ".SyncMesh")
                {
                    if (!meshesToUpdate.Contains(meshFilters[i].sharedMesh))
                    {
                        Unwrapping.GenerateSecondaryUVSet(meshFilters[i].sharedMesh);
                        meshesToUpdate.Add(meshFilters[i].sharedMesh);
                    }
                    continue;
                }

                if (!meshes.ContainsKey(meshFilters[i].sharedMesh))
                {
                    var dir = Path.Combine(Path.GetDirectoryName(path), "Lightmapping");
                    if (!Directory.Exists(dir))
                    {
                        Directory.CreateDirectory(dir);
                    }
                    var name    = Path.GetFileName(path);
                    var newPath = Path.Combine(dir, Path.GetFileNameWithoutExtension(name) + ".mesh");

                    Mesh newmesh;

                    if (File.Exists(newPath))
                    {
                        newmesh = AssetDatabase.LoadAssetAtPath <Mesh>(newPath);
                    }
                    else
                    {
                        newmesh = Object.Instantiate <Mesh>(meshFilters[i].sharedMesh);
                    }

                    Unwrapping.GenerateSecondaryUVSet(newmesh);

                    AssetDatabase.CreateAsset(newmesh, newPath);

                    meshes.Add(meshFilters[i].sharedMesh, newmesh);

                    meshFilters[i].sharedMesh = newmesh;
                }
                else
                {
                    meshFilters[i].sharedMesh = meshes[meshFilters[i].sharedMesh];
                }
            }

            AssetDatabase.SaveAssets();
            EditorUtility.ClearProgressBar();
            Undo.CollapseUndoOperations(undoLvl);
        }
Exemplo n.º 5
0
 private void OnEnable()
 {
     UnwrapParam.SetDefaults(out unwrapParam);
 }
Exemplo n.º 6
0
    public void CombineMeshes(Material mat)                                                                                             // -> Combine all the maesh with a specif material.
    {
        Meshcombinervtwo myScript = (Meshcombinervtwo)target;

        GameObject newGameObject = new GameObject();

        newGameObject.AddComponent <MeshFilter>();
        newGameObject.AddComponent <MeshRenderer>();

        newGameObject.GetComponent <Renderer>().sharedMaterial = null;

        newGameObject.name = "Combine_" + mat.name;
        Undo.RegisterCreatedObjectUndo(newGameObject, "CombineMat" + mat.name);

        myScript.list_CreatedObjects.Add(newGameObject);

        bool OneMesh = false;                                                                                   // This variable is used to know if there is at least one mesh to combine

        newGameObject.transform.rotation = Quaternion.identity;                                                 // Init position to zero

        newGameObject.transform.SetParent(myScript.transform);
        newGameObject.transform.localPosition = new Vector3(0, 0, 0);                                                                   // Init position to Vector3(0,0,0)
        newGameObject.isStatic = true;

        MeshFilter[] filters = myScript.gameObject.GetComponentsInChildren <MeshFilter>(); // Find all the children with MeshFilter component

        Mesh finalMesh = new Mesh();                                                       // Create the new mesh

        CombineInstance[] combiners = new CombineInstance[filters.Length];                 // Struct used to describe meshes to be combined using Mesh.CombineMeshes.


        for (int i = 0; i < filters.Length; i++)                                                                // Check all the children
        {
            if (filters[i].transform == myScript.gameObject.transform)                                          // Do not select the parent himself
            {
                continue;
            }
            if (filters[i].gameObject.GetComponent <Renderer>() == null)                        // Check if there is Renderer component
            {
                continue;
            }
            bool checkTag = false;
            for (int j = 0; j < myScript.list_Tags.Count; j++)                                                          // Check tag to know if you need to ignore this gameobject
            {
                if (filters[i].gameObject.tag == myScript.list_Tags[j])
                {
                    checkTag = true;
                }
            }

            if (mat == filters[i].gameObject.GetComponent <Renderer>().sharedMaterial&& !checkTag &&            // Add this gameObject to the combiner
                filters[i].gameObject.GetComponent <Renderer>().enabled)
            {
                combiners[i].subMeshIndex = 0;
                combiners[i].mesh         = filters[i].sharedMesh;

                combiners[i].transform = filters[i].transform.localToWorldMatrix;

                myScript.list_CombineObjects.Add(filters[i].gameObject);

                SerializedObject serializedObject3 = new UnityEditor.SerializedObject(filters[i].gameObject.GetComponents <Renderer>());
                serializedObject3.Update();
                SerializedProperty tmpSer2 = serializedObject3.FindProperty("m_Enabled");
                tmpSer2.boolValue = false;
                serializedObject3.ApplyModifiedProperties();

                OneMesh = true;
            }
        }

        finalMesh.CombineMeshes(combiners);                                                     // Combine the new mesh
        newGameObject.GetComponent <MeshFilter>().sharedMesh = finalMesh;                       // Create the new Mesh Filter
        newGameObject.GetComponent <Renderer>().material     = mat;                             // ADd the good material

        if (!OneMesh)                                                                           // If there is nothing to combine delete the object
        {
            if (myScript.gameObject.GetComponent <MeshFilter>())
            {
                myScript.gameObject.GetComponent <MeshFilter>().sharedMesh = null;
            }
        }
        else
        {
            UnwrapParam param = new UnwrapParam();                                      // enable lightmap
            UnwrapParam.SetDefaults(out param);
            Unwrapping.GenerateSecondaryUVSet(finalMesh, param);
        }
    }
    public void DisplayGUI()
    {
        MegaScatterMeshTexture mod = (MegaScatterMeshTexture)target;

        EditorGUILayout.LabelField("Objs: " + mod.objcount + " scattered: " + mod.scattercount + " verts: " + mod.vertcount);

        mod.seed         = EditorGUILayout.IntField("Seed", mod.seed);
        mod.countmode    = (MegaScatterMode)EditorGUILayout.EnumPopup("Count Mode", mod.countmode);
        mod.Density      = EditorGUILayout.FloatField("Density", mod.Density);
        mod.forcecount   = EditorGUILayout.IntField("Count", mod.forcecount);
        mod.meshPerShape = EditorGUILayout.Toggle("Mesh Per Color", mod.meshPerShape);

        mod.globalScale   = EditorGUILayout.Vector3Field("Global Scale", mod.globalScale);
        mod.scatterWidth  = EditorGUILayout.FloatField("Width", mod.scatterWidth);
        mod.scatterLength = EditorGUILayout.FloatField("Length", mod.scatterLength);
        Texture2D scatterTexture = (Texture2D)EditorGUILayout.ObjectField("Texture", mod.scatterTexture, typeof(Texture2D), true);

        if (scatterTexture != mod.scatterTexture)
        {
            if (scatterTexture != null)
            {
                string          texturePath     = AssetDatabase.GetAssetPath(scatterTexture);
                TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);
                if (textureImporter.isReadable)
                {
                    mod.scatterTexture = scatterTexture;
                }
                else
                {
                    EditorUtility.DisplayDialog("Scatter Texture Select", "Texture is not set to Readable", "OK");
                }
            }
            else
            {
                mod.scatterTexture = scatterTexture;
            }
        }

        mod.alphaDensity = EditorGUILayout.Toggle("Alpha Density", mod.alphaDensity);

        Texture2D scaleTexture = (Texture2D)EditorGUILayout.ObjectField("Scale", mod.scaleTexture, typeof(Texture2D), true);

        if (scaleTexture != mod.scaleTexture)
        {
            if (scaleTexture != null)
            {
                string          texturePath     = AssetDatabase.GetAssetPath(scaleTexture);
                TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);
                if (textureImporter.isReadable)
                {
                    mod.scaleTexture = scaleTexture;
                }
                else
                {
                    EditorUtility.DisplayDialog("Scale Texture Select", "Texture is not set to Readable", "OK");
                }
            }
            else
            {
                mod.scaleTexture = scaleTexture;
            }
        }

        mod.mintexscale  = EditorGUILayout.Slider("Min Scale", mod.mintexscale, 0.0f, 1.0f);
        mod.maxtexscale  = EditorGUILayout.Slider("Max Scale", mod.maxtexscale, 0.0f, 1.0f);
        mod.minsizetoadd = EditorGUILayout.Slider("Min Size To Add", mod.minsizetoadd, 0.0f, 1.0f);

        mod.texturecollider = (Collider)EditorGUILayout.ObjectField("Texture Object", mod.texturecollider, typeof(Collider), true);

        mod.queryObject      = (MegaScatterQuery)EditorGUILayout.ObjectField("Query Object", mod.queryObject, typeof(MegaScatterQuery), true);
        mod.dostaticbatching = EditorGUILayout.Toggle("Static Batching", mod.dostaticbatching);

        mod.raycast         = EditorGUILayout.BeginToggleGroup("Raycast", mod.raycast);
        mod.NeedsGround     = EditorGUILayout.Toggle("Needs Ground", mod.NeedsGround);
        mod.collisionOffset = EditorGUILayout.FloatField("Collision Offset", mod.collisionOffset);
        mod.showignoreobjs  = EditorGUILayout.Foldout(mod.showignoreobjs, "Show Ignore Objects");

        if (mod.showignoreobjs)
        {
            if (GUILayout.Button("Add Ignore Obj"))
            {
                mod.ignoreobjs.Add(new MegaScatterCollisionObj());
            }

            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.LabelField("Ignore Objects");
            for (int i = 0; i < mod.ignoreobjs.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("" + i + ":", GUILayout.MaxWidth(20));
                GUILayout.Label("On", GUILayout.MaxWidth(20));
                mod.ignoreobjs[i].active = EditorGUILayout.Toggle("", mod.ignoreobjs[i].active, GUILayout.MaxWidth(20));
                GUILayout.Label("Children", GUILayout.MaxWidth(52));
                mod.ignoreobjs[i].includechildren = EditorGUILayout.Toggle("", mod.ignoreobjs[i].includechildren, GUILayout.MaxWidth(20));
                mod.ignoreobjs[i].collider        = (Collider)EditorGUILayout.ObjectField("", mod.ignoreobjs[i].collider, typeof(Collider), true, GUILayout.MaxWidth(180));

                //mod.ignoreobjs[i] = (Collider)EditorGUILayout.ObjectField("" + i + ":", mod.ignoreobjs[i], typeof(Collider), true);
                if (GUILayout.Button("Delete", GUILayout.MaxWidth(50)))
                {
                    mod.ignoreobjs.RemoveAt(i);
                }

                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.EndVertical();
        }

        if (mod.raycast)
        {
            if (mod.surfaces.Count == 0)
            {
                EditorGUILayout.HelpBox("No Surface Objects Defined! No Objects will be scattered", MessageType.Info, true);
            }
        }

        mod.showsurfaceobjs = EditorGUILayout.Foldout(mod.showsurfaceobjs, "Show Surface Objects");
        if (mod.showsurfaceobjs)
        {
            if (GUILayout.Button("Add Surface Obj"))
            {
                mod.surfaces.Add(new MegaScatterCollisionObj());
            }

            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.LabelField("Surface Objects");
            for (int i = 0; i < mod.surfaces.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("" + i + ":");
                mod.surfaces[i].active   = EditorGUILayout.Toggle("", mod.surfaces[i].active, GUILayout.MaxWidth(20));
                mod.surfaces[i].collider = (Collider)EditorGUILayout.ObjectField("", mod.surfaces[i].collider, typeof(Collider), true);

                mod.surfaces[i].prebuildenable   = EditorGUILayout.Toggle("", mod.surfaces[i].prebuildenable, GUILayout.MaxWidth(20));
                mod.surfaces[i].postbuilddisable = EditorGUILayout.Toggle("", mod.surfaces[i].postbuilddisable, GUILayout.MaxWidth(20));

                //mod.ignoreobjs[i] = (Collider)EditorGUILayout.ObjectField("" + i + ":", mod.ignoreobjs[i], typeof(Collider), true);
                if (GUILayout.Button("Delete", GUILayout.MaxWidth(50)))
                {
                    mod.surfaces.RemoveAt(i);
                }

                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.EndVertical();
        }

        EditorGUILayout.EndToggleGroup();

        mod.hideObjects  = EditorGUILayout.Toggle("Hide Objects", mod.hideObjects);
        mod.buildOnStart = EditorGUILayout.Toggle("Build on Start", mod.buildOnStart);
        mod.useCoRoutine = EditorGUILayout.Toggle("Scatter Over Frames", mod.useCoRoutine);
        mod.NumPerFrame  = EditorGUILayout.IntField("Number Per Frame", mod.NumPerFrame);
        mod.colorMesh    = EditorGUILayout.Toggle("Color Mesh", mod.colorMesh);
        mod.displaygizmo = EditorGUILayout.Toggle("Display Gizmo", mod.displaygizmo);

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Hide/Show Objects"))
        {
            mod.HideShow();
        }

        if (GUILayout.Button("Remove Objects"))
        {
            mod.RemoveObjects();
        }

        if (GUILayout.Button("Add Mesh"))
        {
            MegaScatterLayer inf = new MegaScatterLayer();
            mod.layers.Add(inf);
            mod.currentEdit = mod.layers.Count - 1;
        }

        EditorGUILayout.EndHorizontal();

        mod.showlightmap = EditorGUILayout.Foldout(mod.showlightmap, "Lightmap Params");

        if (mod.showlightmap)
        {
            mod.genLightMap = EditorGUILayout.BeginToggleGroup("Lightmap Enable", mod.genLightMap);
            mod.angleError  = EditorGUILayout.Slider("Angle Error", mod.angleError, 0.0f, 1.0f);
            mod.areaError   = EditorGUILayout.Slider("Area Error", mod.areaError, 0.0f, 1.0f);
            mod.hardAngle   = EditorGUILayout.FloatField("Hard Angle", mod.hardAngle);
            mod.packMargin  = EditorGUILayout.FloatField("Pack Margin", mod.packMargin);

            if (GUILayout.Button("Build Lightmap UVS"))
            {
                if (mod.genLightMap)
                {
                    UnwrapParam uv = new UnwrapParam();
                    //UnwrapParam.SetDefaults(out uv);
                    uv.angleError = mod.angleError;
                    uv.areaError  = mod.areaError;
                    uv.hardAngle  = mod.hardAngle;
                    uv.packMargin = mod.packMargin;

                    int count = mod.gameObject.transform.childCount;                            //GetChildCount();
                    for (int c = 0; c < count; c++)
                    {
                        float a = (float)c / (float)count;
                        if (EditorUtility.DisplayCancelableProgressBar("Building LightMap UVs", "Mesh " + c + " of " + count, a))
                        {
                            break;
                        }

                        GameObject obj = mod.gameObject.transform.GetChild(c).gameObject;
                        MeshFilter mf  = obj.GetComponent <MeshFilter>();

                        if (mf)
                        {
                            Mesh mesh = mf.sharedMesh;

                            if (mesh)
                            {
                                Unwrapping.GenerateSecondaryUVSet(mesh, uv);
                            }
                        }
                    }

                    EditorUtility.ClearProgressBar();
                }
            }
            EditorGUILayout.EndToggleGroup();
        }

        mod.showadvanced = EditorGUILayout.Foldout(mod.showadvanced, "Advanced");
        if (mod.showadvanced)
        {
            mod.FailCount    = EditorGUILayout.IntField("Fail Count", mod.FailCount);
            mod.PosFailCount = EditorGUILayout.IntField("Pos Fail Count", mod.PosFailCount);
        }

        EditorGUILayout.BeginVertical("box");
        EditorGUILayout.LabelField("Layers");
        for (int i = 0; i < mod.layers.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("" + i + " - " + mod.layers[i].LayerName);
            mod.layers[i].Enabled = EditorGUILayout.Toggle("", mod.layers[i].Enabled, GUILayout.MaxWidth(20));

            if (GUILayout.Button("Edit", GUILayout.MaxWidth(50)))
            {
                mod.currentEdit = i;
                EditorUtility.SetDirty(mod);
            }

            if (GUILayout.Button("Delete", GUILayout.MaxWidth(50)))
            {
                mod.layers.RemoveAt(i);
            }

            if (GUILayout.Button("U", GUILayout.MaxWidth(20)))
            {
                if (i > 0)
                {
                    MegaScatterMeshEditor.SwapInf(mod, i, i - 1);
                }
            }

            if (GUILayout.Button("D", GUILayout.MaxWidth(22)))
            {
                if (i < mod.layers.Count - 1)
                {
                    MegaScatterMeshEditor.SwapInf(mod, i, i + 1);
                }
            }

            EditorGUILayout.EndHorizontal();
        }
        EditorGUILayout.EndVertical();

        GUI.backgroundColor = Color.green;
        if (GUILayout.Button("Update", GUILayout.Height(30)))
        {
            mod.update = true;
            EditorUtility.SetDirty(target);
        }
        GUI.backgroundColor = Color.white;

        if (mod.currentEdit >= mod.layers.Count)
        {
            mod.currentEdit = mod.layers.Count - 1;
            EditorUtility.SetDirty(mod);
        }

        int ci = mod.currentEdit;

        if (ci >= 0)
        {
            MegaScatterLayer inf = mod.layers[ci];

            EditorGUILayout.BeginVertical("box");

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Copy", GUILayout.Width(50)))
            {
                MegaScatterLayer.copylayer = inf;
            }

            if (MegaScatterLayer.copylayer != null)
            {
                if (GUILayout.Button("Paste from " + MegaScatterLayer.copylayer.LayerName))
                {
                    inf.Copy(MegaScatterLayer.copylayer);
                }
            }
            EditorGUILayout.EndHorizontal();

            inf.LayerName  = EditorGUILayout.TextField("Name", inf.LayerName);
            inf.Enabled    = EditorGUILayout.BeginToggleGroup("Enabled", inf.Enabled);
            inf.markstatic = EditorGUILayout.Toggle("Mark Static", inf.markstatic);

            EditorGUILayout.BeginVertical("box");
            if (GUILayout.Button("Add Color Mask"))
            {
                inf.scattercols.Add(new MegaScatterCol());
            }

            for (int cv = 0; cv < inf.scattercols.Count; cv++)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Mask Col " + cv + ":");
                inf.scattercols[cv].lowcol  = EditorGUILayout.ColorField("", inf.scattercols[cv].lowcol, GUILayout.MaxWidth(50));
                inf.scattercols[cv].highcol = EditorGUILayout.ColorField("", inf.scattercols[cv].highcol, GUILayout.MaxWidth(50));

                if (GUILayout.Button("Delete", GUILayout.MaxWidth(50)))
                {
                    inf.scattercols.RemoveAt(cv);
                }

                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();

            inf.obj            = (GameObject)EditorGUILayout.ObjectField("Object", inf.obj, typeof(GameObject), true);
            inf.forcecount     = EditorGUILayout.IntField("Force Count", inf.forcecount);
            inf.maxcount       = EditorGUILayout.IntField("Max Count", inf.maxcount);
            inf.weight         = EditorGUILayout.FloatField("Weight", inf.weight);
            inf.scale          = EditorGUILayout.FloatField("Scale", inf.scale);
            inf.offsetLow      = EditorGUILayout.Vector3Field("Offset Low", inf.offsetLow);
            inf.offsetHigh     = EditorGUILayout.Vector3Field("Offset High", inf.offsetHigh);
            inf.prerot         = EditorGUILayout.Vector3Field("Pre Rot", inf.prerot);
            inf.rotLow         = EditorGUILayout.Vector3Field("Rot Low", inf.rotLow);
            inf.rotHigh        = EditorGUILayout.Vector3Field("Rot High", inf.rotHigh);
            inf.uniformScaling = EditorGUILayout.Toggle("Uniform Scaling", inf.uniformScaling);

            if (inf.uniformScaling)
            {
                inf.uniscalemode = (MegaScatterScaleMode)EditorGUILayout.EnumPopup("Mode", inf.uniscalemode);
                inf.uniscaleLow  = EditorGUILayout.FloatField("Scale Low", inf.uniscaleLow);
                inf.uniscaleHigh = EditorGUILayout.FloatField("Scale High", inf.uniscaleHigh);
            }
            else
            {
                inf.scaleLow  = EditorGUILayout.Vector3Field("Scale Low", inf.scaleLow);
                inf.scaleHigh = EditorGUILayout.Vector3Field("Scale High", inf.scaleHigh);
            }

            inf.snap            = EditorGUILayout.Vector3Field("Snap", inf.snap);
            inf.snapRot         = EditorGUILayout.Vector3Field("Snap Rot", inf.snapRot);
            inf.distCrv         = EditorGUILayout.CurveField("Dist Curve", inf.distCrv);
            inf.seed            = EditorGUILayout.IntField("Seed", inf.seed);
            inf.noOverlap       = EditorGUILayout.Toggle("No Overlap", inf.noOverlap);
            inf.clearOverlap    = EditorGUILayout.Toggle("Clear Overlap", inf.clearOverlap);
            inf.radius          = EditorGUILayout.FloatField("Radius", inf.radius);
            inf.colradiusadj    = EditorGUILayout.FloatField("Col Radius Adj", inf.colradiusadj);
            inf.raycount        = EditorGUILayout.IntSlider("Ray Count", inf.raycount, 1, 8);
            inf.align           = EditorGUILayout.Slider("Align", inf.align, 0.0f, 1.0f);
            inf.minslope        = EditorGUILayout.Slider("Min Slope", inf.minslope, 0.0f, 90.0f);
            inf.maxslope        = EditorGUILayout.Slider("Max Slope", inf.maxslope, 0.0f, 90.0f);
            inf.collisionOffset = EditorGUILayout.FloatField("Collision Offset", inf.collisionOffset);

            inf.useheight = EditorGUILayout.BeginToggleGroup("Use Height Limits", inf.useheight);
            inf.minheight = EditorGUILayout.FloatField("Min Height", inf.minheight);
            inf.maxheight = EditorGUILayout.FloatField("Max Height", inf.maxheight);
            EditorGUILayout.EndToggleGroup();

            if (mod.colorMesh)
            {
                inf.colcurve = EditorGUILayout.CurveField("Col Curve", inf.colcurve);

                inf.showcolvari = EditorGUILayout.Foldout(inf.showcolvari, "Color Variations");

                if (inf.showcolvari)
                {
                    EditorGUILayout.BeginVertical("box");
                    Texture2D colorTexture = (Texture2D)EditorGUILayout.ObjectField("Color", inf.colorTexture, typeof(Texture2D), true);

                    if (colorTexture != inf.colorTexture)
                    {
                        if (colorTexture != null)
                        {
                            string          texturePath     = AssetDatabase.GetAssetPath(colorTexture);
                            TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);
                            if (textureImporter.isReadable)
                            {
                                inf.colorTexture = colorTexture;
                            }
                            else
                            {
                                EditorUtility.DisplayDialog("Color Texture Select", "Texture is not set to Readable", "OK");
                            }
                        }
                        else
                        {
                            inf.colorTexture = colorTexture;
                        }
                    }

                    if (GUILayout.Button("Add Color"))
                    {
                        inf.colvariations.Add(Color.white);
                    }

                    for (int cv = 0; cv < inf.colvariations.Count; cv++)
                    {
                        EditorGUILayout.BeginHorizontal();
                        inf.colvariations[cv] = EditorGUILayout.ColorField("" + cv + ":", inf.colvariations[cv]);

                        if (GUILayout.Button("Delete", GUILayout.MaxWidth(50)))
                        {
                            inf.colvariations.RemoveAt(cv);
                        }

                        EditorGUILayout.EndHorizontal();
                    }
                    EditorGUILayout.EndVertical();
                }
            }

            inf.vertexlimit   = EditorGUILayout.IntSlider("Vertex Limit", inf.vertexlimit, 1000, 65535);
            inf.buildtangents = EditorGUILayout.Toggle("Build Tangents", inf.buildtangents);
            inf.nocollider    = EditorGUILayout.Toggle("No Collider", inf.nocollider);
            inf.buildcollider = EditorGUILayout.Toggle("Build Collider", inf.buildcollider);
            inf.proxymesh     = (Mesh)EditorGUILayout.ObjectField("Collider Mesh", inf.proxymesh, typeof(Mesh), true);

            inf.vertexnoise = EditorGUILayout.BeginToggleGroup("Vertex Noise", inf.vertexnoise);
            inf.noisescale  = EditorGUILayout.FloatField("Noise Scale", inf.noisescale);
            inf.strength    = EditorGUILayout.Vector3Field("Strength", inf.strength);
            EditorGUILayout.EndToggleGroup();

            EditorGUILayout.EndToggleGroup();

            if (GUILayout.Button("Delete"))
            {
                mod.layers.RemoveAt(ci);
                mod.currentEdit = 0;
                EditorUtility.SetDirty(mod);
            }

            EditorGUILayout.EndVertical();

            GUI.backgroundColor = Color.green;
            if (GUILayout.Button("Update", GUILayout.Height(30)))
            {
                mod.update = true;
                EditorUtility.SetDirty(target);
            }
            GUI.backgroundColor = Color.white;
        }
    }
Exemplo n.º 8
0
    static string QuadsToMesh(
        MeshFilter mf,        // output mesh filter
        quadByUV quads,       // input structure -> quads
        string undoTitle      // title for undo operation
        )
    {                         // output a quad list to a mesh structure
        if (mf == null ||     // no output MeshFilter
            quads == null ||  // OR no quad list
            quads.Count <= 0) // OR no quad entries
        {
            return("");
        }
        // get original asset path and convert to a path we can load from/save to
        string path   = AssetDatabase.GetAssetPath(mf.sharedMesh);
        string suffix = path.Substring(path.LastIndexOf("."));
        string name   = path.Replace(suffix, ".asset");
        // get a previous instance of the mesh. if none, create new asset at path.
        Mesh m = AssetDatabase.LoadAssetAtPath <Mesh>(name);

        if (m == null)
        {                                                   // no old asset could be loaded. create new asset with new GUID.
            AssetDatabase.CreateAsset(new Mesh(), name);    // create file in DB
            AssetDatabase.SaveAssets();                     // save changes
            AssetDatabase.Refresh();                        // update DB
            m = AssetDatabase.LoadAssetAtPath <Mesh>(name); // reload from new path
        }
        // now dump every quad into the mesh. decimate vertices by only saving unique sets
        HashSet <Vertex>      allVertices = new HashSet <Vertex>();      // unique vertex entries of (P,N,UV)
        List <List <Vertex> > allQuads    = new List <List <Vertex> >(); // list of quad faces for indexing

        foreach (Vector2 UV in quads.Keys)                               // by UV color
        {
            foreach (Vector3 N in quads[UV].Keys)                        // by normal direction
            {
                foreach (float r in quads[UV][N].Keys)                   // by row
                {
                    foreach (HashSet <Vector3> A in quads[UV][N][r])     // for every "quad vertex set A"
                    {                                                    // dump every quads contents into the lists
                        // get clockwise winding, create vertex entries
                        List <Vector3> v = SortVerticesClockwise(A, N);  // raw A,B,C,D vectors
                        List <Vertex>  e = new List <Vertex>();          // face vertex entries
                        foreach (Vector3 p in v)                         // create vertex entry
                        {
                            e.Add(new Vertex(p, N, UV));
                        }
                        allVertices.UnionWith(e);                                                                               // add them to the global list
                        // now create the references and add them to the face list
                        List <Vertex> singleQuad = new List <Vertex>();
                        singleQuad.AddRange                                                                                     // add vertex-links for A+B triangle
                            (new Vertex[] { e[0], e[1], e[2], e[0], e[2], e[3] });
                        allQuads.Add(singleQuad);                                                                               // add to global quad face list
                    }
                }
            }
        }
        // convert the vertex lists to arrays. (V,N,UV)-lists have to be of same size (WTF, Unity?)
        List <Vertex>  entries  = new List <Vertex>(allVertices);
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> normals  = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        List <Color32> colors   = new List <Color32>();

        foreach (Vertex e in entries)
        {
            e.Dump(vertices, normals, uvs, colors);
        }
        // relink the faces to a proper index into the dumped lists
        List <int> faces = new List <int>();

        foreach (List <Vertex> vertexIndices in allQuads)
        {
            foreach (Vertex e in vertexIndices)
            {
                faces.Add(entries.IndexOf(e));
            }
        }
        // set final contents of output mesh
        m.Clear();                                                      // clear old contents first
        m.vertices = vertices.ToArray();                                // vertices
        m.normals  = normals.ToArray();                                 // normals
        m.uv       = uvs.ToArray();                                     // UV1
        m.colors32 = colors.ToArray();                                  // vertex colors
        m.SetTriangles(faces.ToArray(), 0);                             // triangles indices
        // optimize structures
        m.Optimize();
        m.RecalculateBounds();
        // generate lightmap set as UV2
        UnwrapParam up;                                         // unwrapping parameters

        UnwrapParam.SetDefaults(out up);                        // set to default
        up.hardAngle  *= 4;                                     // increase hard angles for less seams
        up.packMargin *= 4;                                     // increase margin (otherwise: black streaks)
        Unwrapping.GenerateSecondaryUVSet(m, up);               // generate UV2

        // save changes, update AssetDatabase again
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        // update the MeshFilter to use the generated mesh
        Undo.RecordObject(mf, undoTitle);
        mf.sharedMesh = m;
        // check if we have to update a MeshCollider as well
        MeshCollider mc = mf.GetComponent <MeshCollider>();

        if (mc != null)
        {         // if a MeshCollider is present, also update it's shared mesh
            Undo.RecordObject(mc, undoTitle);
            mc.sharedMesh = m;
        }
        // return the title of the converted new mesh asset
        return(name);
    }