Esempio n. 1
0
        void CreateMergedLODGroup()
        {
            string path = EditorUtility.SaveFilePanelInProject("Save merged mesh", "", "",
                                                               "Please enter a file name to save the merged mesh to");

            if (path.Length != 0)
            {
                if (_lodGroupVegetationMeshCombiner.TargetGameObject == null)
                {
                    return;
                }

                LODGroup   lodGroup     = _lodGroupVegetationMeshCombiner.TargetGameObject.GetComponentInChildren <LODGroup>();
                GameObject sourceObject = _lodGroupVegetationMeshCombiner.TargetGameObject;

                Vector3    targetPosition = sourceObject.transform.position;
                Quaternion targetRotation = sourceObject.transform.rotation;
                Vector3    targetScale    = sourceObject.transform.localScale;

                sourceObject.transform.position   = new Vector3(0, 0, 0);
                sourceObject.transform.rotation   = Quaternion.identity;
                sourceObject.transform.localScale = Vector3.one;

                if (lodGroup == null)
                {
                    return;
                }

                GameObject mergedLODGroupObject = new GameObject("Merged_" + sourceObject.name);
                LODGroup   newLODGroup          = mergedLODGroupObject.AddComponent <LODGroup>();
                LOD[]      lods = lodGroup.GetLODs();

                // ReSharper disable once InconsistentNaming
                LOD[] newLODs = lodGroup.GetLODs();

                for (int i = 0; i <= lods.Length - 1; i++)
                {
                    LOD lod = lods[i];

                    if (lod.renderers.Length > 0)
                    {
                        GameObject lodObject = new GameObject(sourceObject.name + "_LOD" + i.ToString());
                        lodObject.transform.SetParent(mergedLODGroupObject.transform);
                        MeshRenderer meshRenderer = lodObject.AddComponent <MeshRenderer>();
                        MeshFilter   meshFilter   = lodObject.AddComponent <MeshFilter>();

                        Renderer   renderer       = lod.renderers[0];
                        MeshFilter tempMeshFilter = lod.renderers[0].gameObject.GetComponent <MeshFilter>();

                        Renderer[] newRenderers = new Renderer[1];
                        newRenderers[0]      = meshRenderer;
                        newLODs[i].renderers = newRenderers;
                        newLODs[i].screenRelativeTransitionHeight = (float)1 / (i + 1);

                        Mesh       mesh      = Instantiate(tempMeshFilter.sharedMesh);
                        Material[] materials = renderer.sharedMaterials;

                        SubmeshCombiner submeshCombiner = new SubmeshCombiner();
                        for (int j = 0; j <= mesh.subMeshCount - 1; j++)
                        {
                            submeshCombiner.AddSubmesh(mesh.GetIndices(j), materials[j]);
                        }

                        submeshCombiner.UpdateMesh(mesh);
                        materials = submeshCombiner.GetMaterials();

                        meshFilter.sharedMesh = mesh;
                        AssetDatabase.CreateAsset(meshFilter.sharedMesh, path + "_LOD" + i.ToString() + ".asset");
                        meshRenderer.materials = materials;
                    }
                }

                newLODGroup.SetLODs(newLODs);

                sourceObject.transform.position   = targetPosition;
                sourceObject.transform.rotation   = targetRotation;
                sourceObject.transform.localScale = targetScale;
            }
        }
Esempio n. 2
0
    public void SaveAsPrefab(bool groupedSave = false)
    {
        string name = gameObject.name;
        string path = saveTreeFolder;

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        bool replacePrefab = false;

        if (!System.IO.Directory.Exists(path))
        {
            EditorUtility.DisplayDialog("Invalid Path", "The path is not valid, you can chose it with the find folder button", "Ok");
            return;
        }
        if (AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject))) // Overriding prefab dialog
        {
            if (EditorUtility.DisplayDialog("Are you sure?", "The prefab already exists. Do you want to overwrite it?", "Yes", "No"))
            {
                FileUtil.DeleteFileOrDirectory(Path.Combine(path, name + "_meshes"));
                AssetDatabase.Refresh();
                replacePrefab = true;
            }
            else
            {
                name += "_1";
            }
        }

        Mesh[] meshes       = new Mesh[4];
        string meshesFolder = AssetDatabase.CreateFolder(path, name + "_meshes");

        meshesFolder = AssetDatabase.GUIDToAssetPath(meshesFolder) + Path.DirectorySeparatorChar;
        Material[] materials  = SaveMaterials(meshesFolder);
        GameObject TreeObject = new GameObject(name);                 // Tree game object
        LODGroup   group      = TreeObject.AddComponent <LODGroup>(); // LOD Group

        group.fadeMode = LODFadeMode.CrossFade;
        int lodNumber = 4; // Creating LODs

        LOD[] lods = new LOD[lodNumber + 1];

        // Generating Billboard
        Lod = 3;
        GenerateTree(true);
        GameObject billboard = CreateBillboard(meshesFolder, name);

        Renderer[] bill_re = new Renderer[1] {
            billboard.GetComponent <MeshRenderer>()
        };
        lods[lodNumber] = new LOD(.01f, bill_re);


        for (int lod = lodNumber - 1; lod > -1; lod--)                                 // create and save all LOD meshes
        {
            string meshPath = meshesFolder + name + "_LOD" + lod.ToString() + ".mesh"; //updating path for each LOD
            Lod = lod;
            Mesh mesh = GenerateTree(ao: true);
            meshes[lod] = mesh;
            AssetDatabase.CreateAsset(mesh, meshPath);
        }

        for (int i = 0; i < lodNumber; i++) // assigning lod meshes to LOD array
        {
            GameObject go = new GameObject(name + "_LOD" + i.ToString());
            go.transform.parent = TreeObject.transform;
            MeshFilter mf = go.AddComponent <MeshFilter>();
            mf.mesh = meshes[i];
            Renderer[] re = new Renderer[1] {
                go.AddComponent <MeshRenderer>()
            };                                                      // the renderer to put in LODs
            re[0].sharedMaterials = materials;
            float t = Mathf.Pow((i + 1) * 1f / (lodNumber + 1), 1); // float between 0 and 1 following f(x) = pow(x, n)
            lods[i] = new LOD((1 - t) * 0.9f + t * .01f, re);       // assigning renderer
            lods[i].fadeTransitionWidth = 0.25f;
        }

        billboard.transform.parent = TreeObject.transform; // making billboard child of tree object


        group.SetLODs(lods); // assigning LODs to lod group
        group.RecalculateBounds();

        string prefabPath = path + "/" + name + ".prefab";

        TreeObject.AddComponent <MtreeWind>();

        Object prefab;

        if (replacePrefab)
        {
            Object targetPrefab = AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject));
            prefab = PrefabUtility.ReplacePrefab(TreeObject, targetPrefab, ReplacePrefabOptions.ConnectToPrefab);
        }
        else
        {
            prefab = PrefabUtility.CreatePrefab(prefabPath, TreeObject, ReplacePrefabOptions.ConnectToPrefab);
        }

        AssetDatabase.SaveAssets();
        DestroyImmediate(TreeObject);

        if (!groupedSave)
        {
            // select newly created prefab in folder
            Selection.activeObject = prefab;
            // Also flash the folder yellow to highlight it
            EditorGUIUtility.PingObject(prefab);
            EditorUtility.DisplayDialog("Prefab saved !", "The prefab is saved, you can now delete the tree and use the prefab instead", "Ok");
        }
    }
Esempio n. 3
0
        public void MergeMeshes()
        {
            // else Debug.LogWarning("Please assign rooftop material in CS Rooftops Component");
            rooftopHolder[iteration].transform.localScale = new Vector3(1, 1, 1);
            MeshFilter[]      meshFilters = rooftopHolder[iteration].GetComponentsInChildren <MeshFilter>();
            CombineInstance[] combine     = new CombineInstance[meshFilters.Length];

            int index = 0;

            for (int x = 0; x < meshFilters.Length; x++)
            {
                if (meshFilters[x].sharedMesh != null)
                {
                    // if (meshFilters[i].sharedMesh == null) continue;
                    combine[index].mesh        = meshFilters[x].sharedMesh;
                    combine[index++].transform = meshFilters[x].transform.localToWorldMatrix;
                }
            }
            MeshFilter meshF = rooftopHolder[iteration].transform.GetComponent <MeshFilter>();

            meshF.sharedMesh = new Mesh();
            meshF.sharedMesh.CombineMeshes(combine);
            meshF.sharedMesh.RecalculateBounds();

            if (lodComponent != null)
            {
                lodComponent.RecalculateBounds();
            }

            foreach (Transform go in rooftopHolder[iteration].transform.Cast <Transform>().Reverse())
            {
                DestroyImmediate(go.gameObject);
            }

            if (rooftopHolder[iteration].GetComponent <MeshRenderer>() == null)
            {
                rh = rooftopHolder[iteration].AddComponent <MeshRenderer>() as MeshRenderer;
                rh = rooftopHolder[iteration].GetComponent <MeshRenderer>();
                rh.sharedMaterial = greebleMat[iteration];
            }
            rh = rooftopHolder[iteration].GetComponent <MeshRenderer>();
            rh.sharedMaterial = greebleMat[iteration];
            Renderer[] renderers = new Renderer[1];
            LOD[]      lod       = new LOD[1];
            renderers[0] = rooftopHolder[iteration].GetComponent <Renderer>();
            lod[0]       = new LOD(lodDistance, renderers);
            lodComponent.SetLODs(lod);
            if (animateLodFade)
            {
                lodComponent.fadeMode = LODFadeMode.CrossFade;
            }
            else
            {
                lodComponent.fadeMode = LODFadeMode.None;
            }
            lodComponent.animateCrossFading = animateLodFade;

            rooftopHolder[iteration].transform.position   = gameObject.transform.position;
            rooftopHolder[iteration].transform.rotation   = gameObject.transform.rotation;
            rooftopHolder[iteration].transform.localScale = new Vector3(1, bmComponent.scale, 1);
        }
        public static void CreateObjects(TerrainData terrainData, Transform transform, List <MeshInfo>[,] meshes)
        {
            Material matBase = new Material(Shader.Find("Diffuse"));

            matBase.mainTexture = BakeBaseTexture(terrainData);
            List <Material> matAdd   = new List <Material>();
            List <Material> matFirst = new List <Material>();

            for (int l = 0; l < terrainData.alphamapLayers; l++)
            {
                matAdd.Add(GetMaterial(terrainData, l, false));
                matFirst.Add(GetMaterial(terrainData, l, true));
            }

            for (int i = 0; i < meshes.GetLength(0); i++)
            {
                for (int j = 0; j < meshes.GetLength(1); j++)
                {
                    Mesh            fullMesh      = null;
                    int             maxValidLayer = 0;
                    int             maxValidNum   = 0;
                    List <MeshInfo> group         = meshes[i, j];
                    group.Sort((MeshInfo m0, MeshInfo m1) => { return(m1.validNum.CompareTo(m0.validNum)); });
                    foreach (var m in group)
                    {
                        if (m.layer == -1)
                        {
                            fullMesh = m.mesh;
                        }
                        else
                        {
                            if (m.validNum > maxValidNum)
                            {
                                maxValidNum   = m.validNum;
                                maxValidLayer = m.layer;
                            }
                        }
                    }

                    if (group.Count > 0)
                    {
                        GameObject obj = new GameObject("mesh_" + group[0].gridX.ToString() + "_" + group[0].gridY.ToString());
                        obj.transform.SetParent(transform);
                        Renderer[] baseRenderer = new Renderer[1];
                        GameObject baseObj      = new GameObject("base");
                        {
                            MeshRenderer renderer = baseObj.AddComponent <MeshRenderer>();
                            MeshFilter   filter   = baseObj.AddComponent <MeshFilter>();
                            filter.sharedMesh       = fullMesh;
                            renderer.sharedMaterial = matBase;
                            baseObj.transform.SetParent(obj.transform);
                            baseRenderer[0] = renderer;
                        }

                        List <Renderer> splatRenderers = new List <Renderer>();
                        foreach (var m in group)
                        {
                            if (m.layer != -1)
                            {
                                GameObject   subObj   = new GameObject("mesh_" + m.gridX.ToString() + "_" + m.gridY.ToString() + "_" + m.layer.ToString());
                                MeshRenderer renderer = subObj.AddComponent <MeshRenderer>();
                                MeshFilter   filter   = subObj.AddComponent <MeshFilter>();
                                filter.sharedMesh       = m.layer == maxValidLayer ? fullMesh : m.mesh;
                                renderer.sharedMaterial = m.layer == maxValidLayer ? matFirst[m.layer] : matAdd[m.layer];
                                subObj.transform.SetParent(obj.transform);
                                splatRenderers.Add(renderer);
                            }
                        }
                        LOD[] lods = new LOD[2];
                        lods[0].renderers = splatRenderers.ToArray();
                        lods[0].screenRelativeTransitionHeight = 0.4f;
                        lods[1].renderers = baseRenderer;
                        lods[1].screenRelativeTransitionHeight = 0f;
                        LODGroup lodg = obj.AddComponent <LODGroup>();
                        lodg.SetLODs(lods);
                    }
                }
            }
        }
        public static void GenerateBillboards(Bounds bounds, FoliageCell cell, GameObject owner, List <FoliageInstance> trees, FoliageType type, bool addLodGroup, float screenFadeSize, bool animatedCrossFade)
        {
            int[] originalTriangles = m_SystemQuadTriangles;

            GameObject meshObj = new GameObject();

            // Mark object as static
#if UNITY_EDITOR
            GameObjectUtility.SetStaticEditorFlags(meshObj, StaticEditorFlags.OccludeeStatic | StaticEditorFlags.ReflectionProbeStatic);
#endif

            string name = string.Format("MeshCell[{0}_{1}]", cell.GetHashCode(), type.m_Prefab.name);

            Transform existing = owner.transform.Find(name);
            if (existing != null)
            {
#if UNITY_EDITOR
                if (UnityEditor.EditorApplication.isPlaying == false)
                {
                    Object.DestroyImmediate(existing.gameObject);
                }
                else
                {
                    Object.Destroy(existing.gameObject);
                }
#else
                Object.Destroy(existing.gameObject);
#endif
                existing = null;
            }

            meshObj.transform.SetParent(owner.transform);
            meshObj.name = name;

            var data = type.m_RuntimeData.m_SpeedTreeData;

            Vector3 worldScale = new Vector3(data.m_Size.x, data.m_Size.y, data.m_Size.x);

            // Set material
            MeshRenderer rend = meshObj.AddComponent <MeshRenderer>();
            rend.sharedMaterial = GenerateBillboardMaterial(type.m_RuntimeData.m_SpeedTreeData);

            MeshFilter filter = meshObj.AddComponent <MeshFilter>();

            Mesh treeMesh = new Mesh();
            treeMesh.name = meshObj.name;

            List <Vector4> m_TempWorldPositions = new List <Vector4>();
            List <Vector3> m_TempWorldScales    = new List <Vector3>();
            List <Vector3> m_TempQuadVertices   = new List <Vector3>();
            List <Vector4> m_TempQuadTangents   = new List <Vector4>();
            List <Vector3> m_TempQuadNormals    = new List <Vector3>();
            List <int>     m_TempQuadIndices    = new List <int>();

            for (int treeIndex = 0; treeIndex < trees.Count; treeIndex++)
            {
                Vector3 position = trees[treeIndex].m_Position;
                Vector3 scale    = trees[treeIndex].m_Scale;
                float   rot      = trees[treeIndex].m_Rotation.eulerAngles.y * Mathf.Deg2Rad;

                // Offset world position, by the grounding factor
                Vector3 instancePos = position;

                // Don't use this, but offset in shader, so that we can have that correct hue
                // instancePos.y += data.m_Size.z;

                // Scale by the world scale too so that we don't have to do an extra multip
                Vector3 instanceScale = scale;
                instanceScale.Scale(worldScale);

                // Add the world and scale data
                for (int index = 0; index < 4; index++)
                {
                    Vector4 posAndRot = instancePos;
                    posAndRot.w = rot;

                    m_TempWorldPositions.Add(posAndRot);
                    m_TempWorldScales.Add(instanceScale);
                }

                // Add stanard quad data
                m_TempQuadVertices.AddRange(m_SystemQuadVertices);
                m_TempQuadTangents.AddRange(m_SystemQuadTangents);
                m_TempQuadNormals.AddRange(m_SystemQuadNormals);

                // Calculate triangle indixes
                m_TempQuadIndices.AddRange(originalTriangles);
                for (int triIndex = 0; triIndex < 6; triIndex++)
                {
                    // Just add to the triangles the existing triangles + the new indices
                    m_TempQuadIndices[triIndex + 6 * treeIndex] = originalTriangles[triIndex] + 4 * treeIndex;
                }
            }

            treeMesh.Clear();

            // Set standard data
            treeMesh.SetVertices(m_TempQuadVertices);
            treeMesh.SetNormals(m_TempQuadNormals);
            treeMesh.SetTangents(m_TempQuadTangents);

            // Set the custom data
            treeMesh.SetUVs(1, m_TempWorldPositions);
            treeMesh.SetUVs(2, m_TempWorldScales);

            // Set triangles and do not calculate bounds
            treeMesh.SetTriangles(m_TempQuadIndices, 0, false);

            // Set the manually calculated bounds
            treeMesh.bounds = bounds;

            treeMesh.UploadMeshData(true);

            // Set the mesh
            filter.mesh = treeMesh;

            if (addLodGroup)
            {
                // Add the mesh' lod group
                LODGroup group = meshObj.AddComponent <LODGroup>();
                group.animateCrossFading = false;

                if (animatedCrossFade)
                {
                    group.fadeMode           = LODFadeMode.CrossFade;
                    group.animateCrossFading = true;
                }
                else
                {
                    group.fadeMode           = LODFadeMode.None;
                    group.animateCrossFading = false;
                }

                group.SetLODs(new LOD[] { new LOD(screenFadeSize, new Renderer[] { rend }) });
                group.RecalculateBounds();
            }

#if UNITY_EDITOR
            UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(meshObj.scene);
#endif
        }
Esempio n. 6
0
        public void MergeMeshes()
        {
            // else Debug.LogWarning("Please assign rooftop material in CS Rooftops Component");


            MeshFilter[] meshFilters = rooftopHolder.GetComponentsInChildren <MeshFilter>();



            CombineInstance[] combine = new CombineInstance[meshFilters.Length - 1];



            int index = 0;

            for (int i = 0; i < meshFilters.Length; i++)
            {
                if (meshFilters[i].sharedMesh != null)
                {
                    // if (meshFilters[i].sharedMesh == null) continue;
                    combine[index].mesh        = meshFilters[i].sharedMesh;
                    combine[index++].transform = meshFilters[i].transform.localToWorldMatrix;
                }
            }
            MeshFilter meshF = rooftopHolder.transform.GetComponent <MeshFilter>();

            meshF.sharedMesh = new Mesh();
            meshF.sharedMesh.CombineMeshes(combine);

            ///assign new color


            //    Mesh newMesh = new Mesh();
            //    newMesh.vertices = meshF.sharedMesh.vertices;
            //    newMesh.normals = meshF.sharedMesh.normals;
            //    newMesh.uv = meshF.sharedMesh.uv;
            //    newMesh.colors = new Color[meshF.sharedMesh.vertices.Length];
            //    newMesh.triangles = meshF.sharedMesh.triangles;
            //    for (int v = 0; v < newMesh.colors.Length; v++)
            //    {
            //        newMesh.colors[v] = new Color(0, 0, 1, 0);
            //    }

            //meshF.sharedMesh = newMesh;



            meshF.sharedMesh.RecalculateBounds();

            if (lodComponent != null)
            {
                lodComponent.RecalculateBounds();
            }

            foreach (Transform go in rooftopHolder.transform.Cast <Transform>().Reverse())
            {
                DestroyImmediate(go.gameObject);
            }

            if (rooftopHolder.GetComponent <MeshRenderer>() == null)
            {
                rh = rooftopHolder.AddComponent <MeshRenderer>() as MeshRenderer;
                rh = rooftopHolder.GetComponent <MeshRenderer>();
                rh.sharedMaterial = greebleMat;
            }
            rh = rooftopHolder.GetComponent <MeshRenderer>();
            rh.sharedMaterial = greebleMat;
            Renderer[] renderers = new Renderer[1];
            LOD[]      lod       = new LOD[1];
            renderers[0] = rooftopHolder.GetComponent <Renderer>();
            lod[0]       = new LOD(lodDistance, renderers);
            lodComponent.SetLODs(lod);
            if (animateLodFade)
            {
                lodComponent.fadeMode = LODFadeMode.CrossFade;
            }
            else
            {
                lodComponent.fadeMode = LODFadeMode.None;
            }
            lodComponent.animateCrossFading = animateLodFade;

            //if (meshF.sharedMesh.vertices.Length < 3)
            //{
            //    DestroyImmediate(rooftopHolder);
            //    noMesh = true;
            //}
            //else noMesh = false;
        }
Esempio n. 7
0
        public override GameObject GetGameObject()
        {
            // Instantiate root prefab
            GameObject prefab = GameObject.Instantiate(Resources.Load <GameObject>("Submarine/Build/Aquarium"));

            prefab.name = this.ClassID;

            // Get sub objects
            GameObject model                         = prefab.FindChild("model");
            GameObject bubbles                       = prefab.FindChild("Bubbles");
            GameObject xBubbles                      = bubbles.FindChild("xBubbles");
            GameObject storage                       = prefab.FindChild("StorageRoot");
            GameObject collider                      = prefab.FindChild("Collider");
            GameObject coral                         = model.FindChild("Coral");
            GameObject coral1                        = coral.FindChild("coral_reef_grass_11");
            GameObject coral2                        = coral.FindChild("coral_reef_grass_10");
            GameObject coral3                        = coral.FindChild("coral_reef_grass_09");
            GameObject coral4                        = coral.FindChild("coral_reef_grass_07");
            GameObject coral5                        = coral.FindChild("coral_reef_plant_middle_03");
            GameObject coral6                        = coral.FindChild("coral_reef_small_deco_15_red");
            GameObject coral7                        = coral.FindChild("coral_reef_grass_03_04");
            GameObject coral8                        = coral.FindChild("coral_reef_small_deco_14");
            GameObject coral9                        = coral.FindChild("coral_reef_grass_03_03");
            GameObject coral10                       = coral.FindChild("coral_reef_grass_03_02");
            GameObject coral11                       = coral.FindChild("Coral_reef_purple_fan");
            GameObject aquariumAnim2                 = model.FindChild("Aquarium_animation2");
            GameObject aquariumAnim2Root             = aquariumAnim2.FindChild("root");
            GameObject aquariumAnim2Geo              = aquariumAnim2.FindChild("Aquarium_geo");
            GameObject aquariumAnim2GeoAquarium      = aquariumAnim2Geo.FindChild("Aquarium");
            GameObject aquariumAnim2GeoAquariumGlass = aquariumAnim2Geo.FindChild("Aquarium_glass");
            GameObject aquariumAnim2Fish1            = aquariumAnim2Root.FindChild("fish1");
            GameObject aquariumAnim2Fish2            = aquariumAnim2Root.FindChild("fish2");
            GameObject aquariumAnim2Fish3            = aquariumAnim2Root.FindChild("fish3");
            GameObject aquariumAnim2Fish4            = aquariumAnim2Root.FindChild("fish4");
            GameObject aquariumAnim2Attach4          = aquariumAnim2Fish4.FindChild("fish_attach4");
            GameObject aquariumAnim1                 = model.FindChild("Aquarium_animation");
            GameObject aquariumAnim1Root             = aquariumAnim1.FindChild("root");
            GameObject aquariumAnim1Geo              = aquariumAnim1.FindChild("Aquarium_geo");
            GameObject aquariumAnim1GeoAquarium      = aquariumAnim1Geo.FindChild("Aquarium");
            GameObject aquariumAnim1GeoAquariumGlass = aquariumAnim1Geo.FindChild("Aquarium_glass");
            GameObject aquariumAnim1Fish1            = aquariumAnim1Root.FindChild("fish1");
            GameObject aquariumAnim1Fish2            = aquariumAnim1Root.FindChild("fish2");
            GameObject aquariumAnim1Fish3            = aquariumAnim1Root.FindChild("fish3");
            GameObject aquariumAnim1Fish4            = aquariumAnim1Root.FindChild("fish4");

            // Load resources
#if BELOWZERO
            GameObject greenCoral  = Resources.Load <GameObject>("WorldEntities/flora/shared/coral_reef_small_deco_13");
            GameObject blueCoral   = Resources.Load <GameObject>("WorldEntities/flora/unused/Coral_reef_blue_coral_tubes");
            GameObject brownCoral  = Resources.Load <GameObject>("WorldEntities/flora/shared/coral_reef_brown_coral_tubes_02_01");
            GameObject brownCoral1 = Resources.Load <GameObject>("WorldEntities/flora/shared/coral_reef_brown_coral_tubes_02_03");
#else
            GameObject greenCoral  = Resources.Load <GameObject>("WorldEntities/Doodads/Coral_reef/coral_reef_small_deco_13");
            GameObject blueCoral   = Resources.Load <GameObject>("WorldEntities/Doodads/Coral_reef/Coral_reef_blue_coral_tubes");
            GameObject brownCoral  = Resources.Load <GameObject>("WorldEntities/Doodads/Coral_reef/coral_reef_brown_coral_tubes_02_01");
            GameObject brownCoral1 = Resources.Load <GameObject>("WorldEntities/Doodads/Coral_reef/coral_reef_brown_coral_tubes_02_03");
#endif

            // Setup green coral
            if (greenCoral != null)
            {
                GameObject iGreenCoral = GameObject.Instantiate(greenCoral);
                iGreenCoral.name                    = "SmallDeco13";
                iGreenCoral.transform.parent        = coral.transform;
                iGreenCoral.transform.localScale   *= 0.179f;
                iGreenCoral.transform.localPosition = new Vector3(iGreenCoral.transform.localPosition.x, iGreenCoral.transform.localPosition.y + 0.17f, iGreenCoral.transform.localPosition.z - 0.635f);
                GameObject.DestroyImmediate(iGreenCoral.GetComponent <LargeWorldEntity>());
                GameObject.DestroyImmediate(iGreenCoral.GetComponent <PrefabIdentifier>());
            }

            // Setup blue coral
            if (blueCoral != null)
            {
                coral9.GetComponent <MeshRenderer>().enabled = false;

                GameObject iBlueCoral = GameObject.Instantiate(blueCoral);
                iBlueCoral.name                    = "BlueCoralTubes1";
                iBlueCoral.transform.parent        = coral.transform;
                iBlueCoral.transform.localPosition = Vector3.zero;
                iBlueCoral.transform.localScale   *= 0.31f;
                iBlueCoral.transform.localPosition = new Vector3(iBlueCoral.transform.localPosition.x + 0.22f, iBlueCoral.transform.localPosition.y + 0.16f, iBlueCoral.transform.localPosition.z - 0.77f);
                var lwe = iBlueCoral.GetComponent <LargeWorldEntity>();
                if (lwe != null)
                {
                    GameObject.DestroyImmediate(lwe);
                }
                var lmi = iBlueCoral.GetComponent <LiveMixin>();
                if (lmi != null)
                {
                    GameObject.DestroyImmediate(lmi);
                }
                var pid = iBlueCoral.GetComponent <PrefabIdentifier>();
                if (pid != null)
                {
                    GameObject.DestroyImmediate(pid);
                }

                var blueCoralModel = iBlueCoral.FindChild("Coral_reef_blue_coral_tubes");
                var blueCoralAnim  = blueCoralModel.GetComponent <Animator>();
                var blueCoralBase  = blueCoralModel.FindChild("base1");
                var blueCoralGeos  = blueCoralModel.FindChild("geos");

                LODGroup lodBlueCoral = iBlueCoral.GetComponent <LODGroup>();
                lodBlueCoral.ForceLOD(0);
                LOD[] lods = lodBlueCoral.GetLODs();
                lodBlueCoral.SetLODs(new LOD[] { lods[0] });
                lodBlueCoral.ForceLOD(0);
                lodBlueCoral.size = 3.0f;
            }

            // Setup brown coral 2
            if (brownCoral != null)
            {
                GameObject iBrownCoral = GameObject.Instantiate(brownCoral);
                iBrownCoral.name                       = "BrownCoralTubes2";
                iBrownCoral.transform.parent           = coral.transform;
                iBrownCoral.transform.localPosition    = Vector3.zero;
                iBrownCoral.transform.localScale      *= 0.3f;
                iBrownCoral.transform.localPosition    = new Vector3(iBrownCoral.transform.localPosition.x + 0.249f, iBrownCoral.transform.localPosition.y + 0.17f, iBrownCoral.transform.localPosition.z - 0.26f);
                iBrownCoral.transform.localEulerAngles = new Vector3(iBrownCoral.transform.localEulerAngles.x, iBrownCoral.transform.localEulerAngles.y + 15f, iBrownCoral.transform.localEulerAngles.z);
                var lwe = iBrownCoral.GetComponent <LargeWorldEntity>();
                if (lwe != null)
                {
                    GameObject.DestroyImmediate(lwe);
                }
                var rbo = iBrownCoral.GetComponent <Rigidbody>();
                if (rbo != null)
                {
                    GameObject.DestroyImmediate(rbo);
                }
                var lmi = iBrownCoral.GetComponent <LiveMixin>();
                if (lmi != null)
                {
                    GameObject.DestroyImmediate(lmi);
                }
                var pid = iBrownCoral.GetComponent <PrefabIdentifier>();
                if (pid != null)
                {
                    GameObject.DestroyImmediate(pid);
                }
                var bco = iBrownCoral.GetComponentInChildren <BoxCollider>();
                if (bco != null)
                {
                    GameObject.DestroyImmediate(bco);
                }
                // Scale models
                iBrownCoral.FindChild("coral_reef_brown_coral_tubes_02_01").transform.localScale      *= 0.4f;
                iBrownCoral.FindChild("coral_reef_brown_coral_tubes_02_01_LOD1").transform.localScale *= 0.4f;
                iBrownCoral.FindChild("coral_reef_brown_coral_tubes_02_01_LOD2").transform.localScale *= 0.4f;
                iBrownCoral.FindChild("coral_reef_brown_coral_tubes_02_01_LOD3").transform.localScale *= 0.4f;

                var lodBrownCoral = iBrownCoral.GetComponent <LODGroup>();
                lodBrownCoral.ForceLOD(0);
                LOD[] lods = lodBrownCoral.GetLODs();
                lodBrownCoral.SetLODs(new LOD[] { lods[0] });
                lodBrownCoral.ForceLOD(0);
                lodBrownCoral.size = 3.0f;
            }

            // Setup brown coral 2 bis
            if (brownCoral != null)
            {
                GameObject iBrownCoralB = GameObject.Instantiate(brownCoral);
                iBrownCoralB.name                       = "BrownCoralTubes2";
                iBrownCoralB.transform.parent           = coral.transform;
                iBrownCoralB.transform.localPosition    = Vector3.zero;
                iBrownCoralB.transform.localScale      *= 0.3f;
                iBrownCoralB.transform.localPosition    = new Vector3(iBrownCoralB.transform.localPosition.x - 0.18f, iBrownCoralB.transform.localPosition.y + 0.055f, iBrownCoralB.transform.localPosition.z - 0.115f);
                iBrownCoralB.transform.localEulerAngles = new Vector3(iBrownCoralB.transform.localEulerAngles.x, iBrownCoralB.transform.localEulerAngles.y - 105.0f, iBrownCoralB.transform.localEulerAngles.z + 15.0f);
                var lwe = iBrownCoralB.GetComponent <LargeWorldEntity>();
                if (lwe != null)
                {
                    GameObject.DestroyImmediate(lwe);
                }
                var rbo = iBrownCoralB.GetComponent <Rigidbody>();
                if (rbo != null)
                {
                    GameObject.DestroyImmediate(rbo);
                }
                var lmi = iBrownCoralB.GetComponent <LiveMixin>();
                if (lmi != null)
                {
                    GameObject.DestroyImmediate(lmi);
                }
                var pid = iBrownCoralB.GetComponent <PrefabIdentifier>();
                if (pid != null)
                {
                    GameObject.DestroyImmediate(pid);
                }
                var bco = iBrownCoralB.GetComponentInChildren <BoxCollider>();
                if (bco != null)
                {
                    GameObject.DestroyImmediate(bco);
                }
                // Scale models
                iBrownCoralB.FindChild("coral_reef_brown_coral_tubes_02_01").transform.localScale      *= 0.4f;
                iBrownCoralB.FindChild("coral_reef_brown_coral_tubes_02_01_LOD1").transform.localScale *= 0.4f;
                iBrownCoralB.FindChild("coral_reef_brown_coral_tubes_02_01_LOD2").transform.localScale *= 0.4f;
                iBrownCoralB.FindChild("coral_reef_brown_coral_tubes_02_01_LOD3").transform.localScale *= 0.4f;

                var lodBrownCoral = iBrownCoralB.GetComponent <LODGroup>();
                lodBrownCoral.ForceLOD(0);
                LOD[] lods = lodBrownCoral.GetLODs();
                lodBrownCoral.SetLODs(new LOD[] { lods[0] });
                lodBrownCoral.ForceLOD(0);
                lodBrownCoral.size = 3.0f;

                iBrownCoralB.transform.localScale *= 1.4f;
            }

            // Setup brown coral 1
            if (brownCoral1 != null)
            {
                GameObject iBrownCoral1 = GameObject.Instantiate(brownCoral1);
                iBrownCoral1.name                       = "BrownCoralTubes2";
                iBrownCoral1.transform.parent           = coral.transform;
                iBrownCoral1.transform.localPosition    = Vector3.zero;
                iBrownCoral1.transform.localScale      *= 0.4f;
                iBrownCoral1.transform.localPosition    = new Vector3(iBrownCoral1.transform.localPosition.x - 0.08f, iBrownCoral1.transform.localPosition.y + 0.055f, iBrownCoral1.transform.localPosition.z - 0.1144f);
                iBrownCoral1.transform.localEulerAngles = new Vector3(iBrownCoral1.transform.localEulerAngles.x, iBrownCoral1.transform.localEulerAngles.y - 30.0f, iBrownCoral1.transform.localEulerAngles.z);
                var lwe = iBrownCoral1.GetComponent <LargeWorldEntity>();
                if (lwe != null)
                {
                    GameObject.DestroyImmediate(lwe);
                }
                var rbo = iBrownCoral1.GetComponent <Rigidbody>();
                if (rbo != null)
                {
                    GameObject.DestroyImmediate(rbo);
                }
                var lmi = iBrownCoral1.GetComponent <LiveMixin>();
                if (lmi != null)
                {
                    GameObject.DestroyImmediate(lmi);
                }
                var pid = iBrownCoral1.GetComponent <PrefabIdentifier>();
                if (pid != null)
                {
                    GameObject.DestroyImmediate(pid);
                }
                var bco = iBrownCoral1.GetComponentInChildren <BoxCollider>();
                if (bco != null)
                {
                    GameObject.DestroyImmediate(bco);
                }
                // Scale models
                iBrownCoral1.FindChild("coral_reef_brown_coral_tubes_02_03").transform.localScale      *= 0.4f;
                iBrownCoral1.FindChild("coral_reef_brown_coral_tubes_02_03_LOD1").transform.localScale *= 0.4f;
                iBrownCoral1.FindChild("coral_reef_brown_coral_tubes_02_03_LOD2").transform.localScale *= 0.4f;
                iBrownCoral1.FindChild("coral_reef_brown_coral_tubes_02_03_LOD3").transform.localScale *= 0.4f;
                // Adjust LOD
                var lodBrownCoral = iBrownCoral1.GetComponent <LODGroup>();
                if (lodBrownCoral != null)
                {
                    lodBrownCoral.ForceLOD(0);
                    LOD[] lods = lodBrownCoral.GetLODs();
                    lodBrownCoral.SetLODs(new LOD[] { lods[0] });
                    lodBrownCoral.ForceLOD(0);
                    lodBrownCoral.size = 3.0f;
                }
            }

            // Adjust corals
            coral1.SetActive(false); // petite fougere jaune (gauche)
            coral2.SetActive(false); // grande fougere jaune 1 (droite)
            coral3.SetActive(false); // grande fougere jaune 2 (droite)
            coral4.SetActive(false); // grande fougere jaune 3 (droite)
            coral5.SetActive(false); // grande plante rose (centre gauche)
            coral6.SetActive(false); // corail rouge foncé a petit points blanc (droite)
            coral7.SetActive(false); // plante rose (droite)
            coral8.SetActive(false); // corail bleu foncé a pointes en spirales et bout rouge (gauche)
            coral9.SetActive(false); // plante rose (centre gauche)
            coral10.SetActive(true); // plante rose (centre gauche)
            coral11.SetActive(true); // algue en courone bleu/violet foncée (centre gauche)
            coral.transform.localScale     *= 0.6f;
            coral10.transform.localScale   *= 0.5f;
            coral10.transform.localPosition = new Vector3(coral10.transform.localPosition.x + 0.10f, coral10.transform.localPosition.y - 0.17f, coral10.transform.localPosition.z - 0.43f);
            coral11.transform.localPosition = new Vector3(coral11.transform.localPosition.x - 0.2f, coral11.transform.localPosition.y - 0.23f, coral11.transform.localPosition.z);

            // Adjust aquarium
            aquariumAnim2Geo.transform.localScale    = new Vector3(aquariumAnim2Geo.transform.localScale.x * (1.0f / 0.239f), aquariumAnim2Geo.transform.localScale.y * (1.0f / 0.24f), aquariumAnim2Geo.transform.localScale.z * (1.0f / 0.239f));
            aquariumAnim1Geo.transform.localScale    = new Vector3(aquariumAnim1Geo.transform.localScale.x * (1.0f / 0.239f), aquariumAnim1Geo.transform.localScale.y * (1.0f / 0.24f), aquariumAnim1Geo.transform.localScale.z * (1.0f / 0.239f));
            aquariumAnim2Geo.transform.localPosition = new Vector3(aquariumAnim2Geo.transform.localPosition.x, aquariumAnim2Geo.transform.localPosition.y - (0.20f * (1.0f / 0.24f)), aquariumAnim2Geo.transform.localPosition.z);
            aquariumAnim1Geo.transform.localPosition = new Vector3(aquariumAnim1Geo.transform.localPosition.x, aquariumAnim1Geo.transform.localPosition.y - (0.20f * (1.0f / 0.24f)), aquariumAnim1Geo.transform.localPosition.z);

            aquariumAnim2Geo.transform.localScale    = new Vector3(aquariumAnim2Geo.transform.localScale.x * 0.50f, aquariumAnim2Geo.transform.localScale.y * 0.285f, aquariumAnim2Geo.transform.localScale.z * 0.16f);
            aquariumAnim1Geo.transform.localScale    = new Vector3(aquariumAnim1Geo.transform.localScale.x * 0.50f, aquariumAnim1Geo.transform.localScale.y * 0.285f, aquariumAnim1Geo.transform.localScale.z * 0.16f);
            aquariumAnim2Geo.transform.localPosition = new Vector3(aquariumAnim2Geo.transform.localPosition.x, aquariumAnim2Geo.transform.localPosition.y, aquariumAnim2Geo.transform.localPosition.z + (0.145f * (1.0f / 0.239f)));
            aquariumAnim1Geo.transform.localPosition = new Vector3(aquariumAnim1Geo.transform.localPosition.x, aquariumAnim1Geo.transform.localPosition.y, aquariumAnim1Geo.transform.localPosition.z + (0.145f * (1.0f / 0.239f)));

            aquariumAnim2GeoAquarium.transform.localPosition = new Vector3(aquariumAnim2GeoAquarium.transform.localPosition.x, aquariumAnim2GeoAquarium.transform.localPosition.y, aquariumAnim2GeoAquarium.transform.localPosition.z - ((0.145f * 2.0f) * (1.0f / 0.16f)));
            aquariumAnim1GeoAquarium.transform.localPosition = new Vector3(aquariumAnim1GeoAquarium.transform.localPosition.x, aquariumAnim1GeoAquarium.transform.localPosition.y, aquariumAnim1GeoAquarium.transform.localPosition.z - ((0.145f * 2.0f) * (1.0f / 0.16f)));

            // Adjust fish
            aquariumAnim2Attach4.transform.localScale = new Vector3(aquariumAnim2Attach4.transform.localScale.x * 2.2f, aquariumAnim2Attach4.transform.localScale.y * 2.2f, aquariumAnim2Attach4.transform.localScale.z * 2.2f);

            // Adjust animators
            Animator anim = aquariumAnim1.GetComponent <Animator>();
            anim.transform.localScale    = new Vector3(anim.transform.localScale.x * 0.239f, anim.transform.localScale.y * 0.24f, anim.transform.localScale.z * 0.239f);
            anim.transform.localPosition = new Vector3(anim.transform.localPosition.x + 0.145f, anim.transform.localPosition.y + 0.20f, anim.transform.localPosition.z);
            Animator anim2 = aquariumAnim2.GetComponent <Animator>();
            anim2.transform.localScale    = new Vector3(anim2.transform.localScale.x * 0.239f, anim2.transform.localScale.y * 0.24f, anim2.transform.localScale.z * 0.239f);
            anim2.transform.localPosition = new Vector3(anim2.transform.localPosition.x + 0.145f, anim2.transform.localPosition.y + 0.20f, anim2.transform.localPosition.z);

            // Adjust bubbles
            bubbles.transform.localScale     = new Vector3(bubbles.transform.localScale.x * 0.07f, bubbles.transform.localScale.y * 0.07f, bubbles.transform.localScale.z * 0.07f);
            xBubbles.transform.localScale    = new Vector3(xBubbles.transform.localScale.x * 0.07f, xBubbles.transform.localScale.y * 0.07f, xBubbles.transform.localScale.z * 0.07f);
            xBubbles.transform.localPosition = new Vector3(xBubbles.transform.localPosition.x + 4.0f, xBubbles.transform.localPosition.y + 1.0f, xBubbles.transform.localPosition.z);
            var ps  = xBubbles.GetComponent <ParticleSystem>();
            var psr = xBubbles.GetComponent <ParticleSystemRenderer>();
#pragma warning disable CS0618
            ps.startSize     *= 0.5f;
            ps.startLifetime *= 0.18f;
            ps.startSpeed     = 0f;
            ps.emissionRate   = 6f;
            ps.maxParticles   = 5;
            ps.playbackSpeed *= 0.4f;
#pragma warning restore CS0618
            psr.lengthScale     *= 0.35f;
            psr.maxParticleSize *= 0.35f;
            foreach (Transform tr in xBubbles.transform)
            {
                tr.localPosition = new Vector3(0.5f, 0.0f, 0.0f);
                psr = tr.GetComponent <ParticleSystemRenderer>();
                if (tr.name.StartsWith("xDots", true, CultureInfo.InvariantCulture))
                {
                    ps = tr.GetComponent <ParticleSystem>();
#pragma warning disable CS0618
                    ps.startSize     *= 0.3f;
                    ps.startLifetime *= 0.11f;
                    ps.startSpeed     = 0.3f;
                    ps.emissionRate   = 3f;
                    ps.maxParticles   = 6;
                    ps.playbackSpeed *= 0.5f;
#pragma warning restore CS0618
                    psr.lengthScale     *= 0.11f;
                    psr.maxParticleSize *= 0.11f;
                }
                else if (tr.name.StartsWith("xLateralBubbles", true, CultureInfo.InvariantCulture))
                {
                    psr.enabled = false;
                }
            }

            // Adjust prefab identifier
            var prefabId = prefab.GetComponent <PrefabIdentifier>();
            prefabId.ClassId = this.ClassID;

            // Adjust tech tag
            var techTag = prefab.GetComponent <TechTag>();
            techTag.type = this.TechType;

            // Adjust contructable
            Constructable constructable = prefab.GetComponent <Constructable>();
            constructable.allowedInBase           = true;
            constructable.allowedInSub            = true;
            constructable.allowedOutside          = true;
            constructable.allowedOnCeiling        = false;
            constructable.allowedOnGround         = true;
            constructable.allowedOnConstructables = true;
#if BELOWZERO
            constructable.allowedUnderwater = true;
#endif
            constructable.controlModelState     = true;
            constructable.deconstructionAllowed = true;
            constructable.rotationEnabled       = true;
            //constructable.model = model;
            constructable.techType = this.TechType;
            constructable.enabled  = true;

            // Adjust constructable bounds
            ConstructableBounds bounds = prefab.GetComponent <ConstructableBounds>();
            bounds.bounds = new OrientedBounds(new Vector3((bounds.bounds.position.x * 0.16f) + (0.145f * 2.0f), bounds.bounds.position.y * 0.285f, bounds.bounds.position.z * 0.5f), bounds.bounds.rotation, new Vector3(bounds.bounds.extents.x * 0.16f, bounds.bounds.extents.y * 0.285f, bounds.bounds.extents.z * 0.5f));

            // Adjust collider
            BoxCollider c = collider.GetComponent <BoxCollider>();
            c.size   = new Vector3(c.size.x * 0.16f, c.size.y * 0.285f, c.size.z * 0.5f);
            c.center = new Vector3((c.center.x * 0.16f) + (0.145f * 2.0f), c.center.y * 0.285f, c.center.z * 0.5f);

            // Adjust aquarium
            var aquarium = prefab.GetComponent <Aquarium>();
            aquarium.storageContainer.width  = 1;
            aquarium.storageContainer.height = 1;
            aquarium.trackObjects            = new GameObject[] { aquariumAnim2Attach4 };

            // Adjust rendering
            var             sas    = prefab.GetComponents <SkyApplier>();
            List <Renderer> rendsA = new List <Renderer>();
            List <Renderer> rendsB = new List <Renderer>();
            int             i      = 0;
            foreach (SkyApplier sa in sas)
            {
                foreach (Renderer rend in sa.renderers)
                {
                    if (string.Compare(rend.name, "Aquarium", true, CultureInfo.InvariantCulture) != 0)
                    {
                        if (ConfigSwitcher.GlowingAquariumGlass && string.Compare(rend.name, "Aquarium_glass", true, CultureInfo.InvariantCulture) == 0)
                        {
                            foreach (Material mat in rend.materials)
                            {
                                mat.EnableKeyword("MARMO_EMISSION");
                                mat.EnableKeyword("MARMO_GLOW");
                                mat.SetFloat("_SpecInt", 16f);
                                mat.SetFloat("_EnableGlow", 1);
                                mat.SetColor("_GlowColor", new Color(0.79f, 0.9785799f, 1.0f, 0.08f));
                                mat.SetFloat("_GlowStrength", 0.18f);
                            }
                        }
                        if (i == 0)
                        {
                            rendsA.Add(rend);
                        }
                        else
                        {
                            rendsB.Add(rend);
                        }
                    }
                }
                i++;
            }
            sas[0].renderers = rendsA.ToArray();
            sas[1].renderers = rendsB.ToArray();
            Renderer[]      tmpRends = prefab.GetAllComponentsInChildren <Renderer>();
            List <Renderer> rends    = new List <Renderer>();
            foreach (Renderer tmpRend in tmpRends)
            {
                if (string.Compare(tmpRend.name, "Aquarium", true, CultureInfo.InvariantCulture) == 0)
                {
                    rends.Add(tmpRend);
                }
            }

            var fixedSa = prefab.AddComponent <SkyApplier>();
            fixedSa.anchorSky    = Skies.Auto;
            fixedSa.dynamic      = true;
            fixedSa.renderers    = rends.ToArray();
            fixedSa.updaterIndex = 0;

            // Adjust bubbles LOD
            var lodBubbles = bubbles.GetComponent <LODGroup>();
            lodBubbles.size *= (1.0f / 0.07f);

            // Remove unwanted elements
            GameObject.DestroyImmediate(aquariumAnim2Fish1);
            GameObject.DestroyImmediate(aquariumAnim2Fish2);
            GameObject.DestroyImmediate(aquariumAnim2Fish3);
            GameObject.DestroyImmediate(aquariumAnim1Fish1);
            GameObject.DestroyImmediate(aquariumAnim1Fish2);
            GameObject.DestroyImmediate(aquariumAnim1Fish3);
            GameObject.DestroyImmediate(aquariumAnim1Fish4);

            // Adjust prefab position
            foreach (Transform tr in prefab.transform)
            {
                tr.transform.localPosition = new Vector3(tr.transform.localPosition.x - 0.29f, tr.transform.localPosition.y, tr.transform.localPosition.z);
            }

            return(prefab);
        }
Esempio n. 8
0
    // Token: 0x06000E20 RID: 3616 RVA: 0x00064CCC File Offset: 0x00062ECC
    private void UpdateMesh()
    {
        MineRock5.m_tempInstancesA.Clear();
        MineRock5.m_tempInstancesB.Clear();
        Material  y       = this.m_meshRenderer.sharedMaterials[0];
        Matrix4x4 inverse = base.transform.localToWorldMatrix.inverse;

        for (int i = 0; i < this.m_hitAreas.Count; i++)
        {
            MineRock5.HitArea hitArea = this.m_hitAreas[i];
            if (hitArea.m_health > 0f)
            {
                CombineInstance item = default(CombineInstance);
                item.mesh      = hitArea.m_meshFilter.sharedMesh;
                item.transform = inverse * hitArea.m_meshFilter.transform.localToWorldMatrix;
                for (int j = 0; j < hitArea.m_meshFilter.sharedMesh.subMeshCount; j++)
                {
                    item.subMeshIndex = j;
                    if (hitArea.m_meshRenderer.sharedMaterials[j] == y)
                    {
                        MineRock5.m_tempInstancesA.Add(item);
                    }
                    else
                    {
                        MineRock5.m_tempInstancesB.Add(item);
                    }
                }
                hitArea.m_meshRenderer.enabled = false;
                hitArea.m_collider.gameObject.SetActive(true);
            }
            else
            {
                hitArea.m_collider.gameObject.SetActive(false);
            }
        }
        if (MineRock5.m_tempMeshA == null)
        {
            MineRock5.m_tempMeshA = new Mesh();
            MineRock5.m_tempMeshB = new Mesh();
        }
        MineRock5.m_tempMeshA.CombineMeshes(MineRock5.m_tempInstancesA.ToArray());
        MineRock5.m_tempMeshB.CombineMeshes(MineRock5.m_tempInstancesB.ToArray());
        CombineInstance combineInstance = default(CombineInstance);

        combineInstance.mesh = MineRock5.m_tempMeshA;
        CombineInstance combineInstance2 = default(CombineInstance);

        combineInstance2.mesh = MineRock5.m_tempMeshB;
        this.m_meshFilter.mesh.CombineMeshes(new CombineInstance[]
        {
            combineInstance,
            combineInstance2
        }, false, false);
        this.m_meshRenderer.enabled = true;
        Renderer[] array = new Renderer[this.m_extraRenderers.Count + 1];
        this.m_extraRenderers.CopyTo(0, array, 0, this.m_extraRenderers.Count);
        array[array.Length - 1] = this.m_meshRenderer;
        LODGroup component = base.gameObject.GetComponent <LODGroup>();

        LOD[] lods = component.GetLODs();
        lods[0].renderers = array;
        component.SetLODs(lods);
    }
Esempio n. 9
0
    void loadSubTree(GameObject parent, PiXYZ4UnityWrapper.ScenePath subTree, int currentMateriaId, bool editor, UnityEngine.Object prefab, bool importLines, int curLOD, ref Dictionary <int, List <Renderer> > lodToRenderers, ref Dictionary <int, double> lodToThreshold, bool isMaterialOverride = false)
    {
        if (!isPart(subTree.node()) && !isAssembly(subTree.node()) || isHidden(subTree)) //Last part is HOOPS workaround.
        {
            return;                                                                      //no light or camera
        }
        GameObject obj = new GameObject();

        Transform parentTransform = parent != null ? parent.transform : null;

        obj.name             = PiXYZ4UnityWrapper.getNodeName(subTree.node());
        obj.transform.parent = parentTransform;
        Matrix4x4 matrix = PiXYZ4UnityWrapper.getLocalMatrix(subTree.node());

        int parentInstance = subTree.parentInstance();

        if (parentInstance > 0)
        {
            Matrix4x4 parentMatrix = PiXYZ4UnityWrapper.getLocalMatrix(parentInstance);
            matrix = parentMatrix * matrix;
        }
        SetTransformFromMatrix(obj.transform, ref matrix);
        if (parent == null)  //apply mirror and rotation once
        {
            lastImportedObject        = obj;
            obj.transform.localScale *= _scale;
            if (_mirrorX)
            {
                obj.transform.localScale = new Vector3(-obj.transform.localScale.x, obj.transform.localScale.y, obj.transform.localScale.z);
            }
            if (_rotation.eulerAngles.sqrMagnitude > 0)
            {
                obj.transform.localRotation = _rotation;
            }
        }

        if (!isMaterialOverride || isAssembly(subTree.node()) || currentMateriaId == 0)
        {
            int materialId = PiXYZ4UnityWrapper.getOccurrenceMaterial(subTree);
            if (materialId > 0)
            {
                currentMateriaId = materialId;
            }
        }

        int  lodCount   = 0;
        bool isLodGroup = PiXYZ4UnityWrapper.isLODGroup(subTree.node(), out lodCount);

        if (_lodsMode != LODsMode.NONE)
        {
            if (isLodGroup)
            {
                lodToRenderers.Clear();
                lodToThreshold.Clear();
            }

            if (PiXYZ4UnityWrapper.isLOD(subTree.node()))
            {
                double threshold;
                curLOD = PiXYZ4UnityWrapper.getLODNumber(subTree.node(), out threshold);
                if (!lodToThreshold.ContainsKey(curLOD))
                {
                    lodToThreshold.Add(curLOD, threshold);
                }
            }
        }
        if (isPart(subTree.node()))
        {
            loadPart(obj, subTree.node(), currentMateriaId, editor, prefab, importLines, curLOD, ref lodToRenderers);
        }
        else if (isAssembly(subTree.node()))
        {
            foreach (PiXYZ4UnityWrapper.ScenePath child in PiXYZ4UnityWrapper.getChildren(subTree))
            {
                try
                {
                    loadSubTree(obj, child, currentMateriaId, editor, prefab, importLines, curLOD, ref lodToRenderers, ref lodToThreshold, isMaterialOverride || isAssembly(subTree.node()));
                }
                catch (KeyNotFoundException knf)
                {
                    Debug.LogError("Key not found: " + knf.ToString());
                }
            }
        }

        if (_lodsMode != LODsMode.NONE && isLodGroup)
        {
            LOD[]        lods         = new LOD[lodCount];
            const double e            = 0.00001;
            double       minThreshold = 1;
            for (int iLOD = 0; iLOD < lodCount; ++iLOD)
            {
                double threshold = Math.Min(lodToThreshold[iLOD], minThreshold);
                if (!lodToRenderers.ContainsKey(iLOD))
                {
                    Debug.LogError("Key '" + iLOD + "' not found.");
                    continue;
                }
                Renderer[] renderers = new Renderer[lodToRenderers[iLOD].Count];
                for (int iRenderer = 0; iRenderer < lodToRenderers[iLOD].Count; ++iRenderer)
                {
                    renderers[iRenderer] = lodToRenderers[iLOD][iRenderer];
                }
                lods.SetValue(new LOD((float)threshold, renderers), iLOD);
                minThreshold = threshold - e;
            }
            LODGroup lodGroup = obj.AddComponent <LODGroup>();
            lodGroup.SetLODs(lods);
            lodToRenderers.Clear();
            lodToThreshold.Clear();
        }
    }
Esempio n. 10
0
    protected override void OnFinished()
    {
        GameObject go = null;

        try
        {
            if (filename.Contains("_terrain_"))
            {
                TerrainObj tobj = parent.gameObject.GetComponent <TerrainObj>();
                if (tobj == null)
                {
                    parent.gameObject.AddComponent <TerrainObj>();
                }
                else
                {
                    tobj.enabled = true;
                }
            }
            count--;
            // This is executed by the Unity main thread when the job is finished
            if (niffile != null)
            {
                go = NIFLoader.loadNIF(niffile, filename);
                if (lodfile != null)
                {
                    GameObject lodgo = NIFLoader.loadNIF(lodfile, filename);

                    // terrain lod
                    LODGroup group = parent.gameObject.GetComponent <LODGroup>();
                    if (group == null)
                    {
                        group = parent.gameObject.AddComponent <LODGroup>();
                    }
                    group.enabled            = true;
                    group.animateCrossFading = true;
                    group.fadeMode           = LODFadeMode.SpeedTree;
                    LOD[]      lods         = new LOD[2];
                    Renderer[] renderersMax = go.GetComponentsInChildren <Renderer>();
                    Renderer[] renderersLow = lodgo.GetComponentsInChildren <Renderer>();
                    lods[0] = new LOD(0.6f, renderersMax);
                    lods[1] = new LOD(0.03f, renderersLow);
                    //lods[1] = new LOD(1f - LODCutoff, renderers);
                    group.SetLODs(lods);

                    GameObject lodObj = new GameObject();
                    lodObj.name = "LOD-" + filename;
                    lodgo.transform.SetParent(lodObj.transform);
                    lodObj.transform.SetParent(go.transform);
                }

                lock (originals)
                {
                    originals[filename] = go;
                }
            }
            else
            {
                go = getCachedObject(filename);
            }

            if (go != null)
            {
                if (Assets.GameWorld.useColliders)
                {
                    GameObject.Destroy(parent.GetComponent <BoxCollider>());
                    GameObject.Destroy(parent.GetComponent <SphereCollider>());
                }
                go.transform.SetParent(parent.transform);
                go.transform.localScale    = Vector3.one;
                go.transform.localPosition = Vector3.zero;
                go.transform.localRotation = Quaternion.identity;

                if (parent.gameObject.GetComponent <LODGroup>() != null)
                {
                    parent.gameObject.GetComponent <LODGroup>().RecalculateBounds();
                }
            }
        }
        catch (Exception ex)
        {
            Debug.LogWarning("Unable to load nif:" + niffile + " " + filename);
            Debug.Log(ex);
            if (null != go)
            {
                GameObject.Destroy(go);
            }
        }
        finally
        {
            if (cacheWait.ContainsKey(filename))
            {
                cacheWait[filename].Release();
            }
        }
    }
Esempio n. 11
0
        public void BuildPrefabLod()
        {
#if UNITY_EDITOR
            string path = EditorUtility.SaveFilePanelInProject("Save prefab", "", "prefab",
                                                               "Please enter a file name to save the prefab to");
            if (path.Length == 0)
            {
                return;
            }

            string prefabName       = Path.GetFileNameWithoutExtension(path);
            string directory        = Path.GetDirectoryName(path);
            string prefabFilename   = path;
            string meshFilenameLod0 = directory + "/" + prefabName + "_LOD0.asset";
            string meshFilenameLod1 = directory + "/" + prefabName + "_LOD1.asset";
            string meshFilenameLod2 = directory + "/" + prefabName + "_LOD2.asset";
            string materialFilename = Path.ChangeExtension(prefabFilename, ".mat");

            Vector3    oldPosition = transform.position;
            Quaternion oldRotation = transform.rotation;

            transform.position = Vector3.zero;
            transform.rotation = Quaternion.identity;

            //string patchID = Time.realtimeSinceStartup.ToString();
            Material material;

            if (CustomMaterial)
            {
                material = new Material(CustomMaterial);
                material.SetTexture("_MainTex", GrassTexture);
            }
            else
            {
                material = new Material(Shader.Find("AwesomeTechnologies/Grass/Grass"));
                material.SetTexture("_MainTex", GrassTexture);
                material.SetColor("_Color", ColorTint1);
                material.SetColor("_ColorB", ColorTint2);
                material.SetFloat("_Cutoff", TextureCutoff);
                material.SetFloat("_RandomDarkening", RandomDarkening);
                material.SetFloat("_RootAmbient", RootAmbient);
                material.SetVector("_AG_ColorNoiseArea", new Vector4(0, 30, 0, 1));
                material.SetTexture("_AG_ColorNoiseTex", Resources.Load("PerlinSeamless") as Texture2D);
                material.EnableKeyword("_ALPHATEST_ON");
            }

            AssetDatabase.CreateAsset(material, materialFilename);
            GameObject go = new GameObject {
                name = prefabName
            };
            // "New grass patch_" + patchID;
            go.transform.position = transform.position;
            go.transform.rotation = transform.localRotation;

            Mesh meshLod0 = GetCombinedMesh(0);
            Mesh meshLod1 = GetCombinedMesh(1);
            Mesh meshLod2 = GetCombinedMesh(2);

            GameObject goLod0 = new GameObject {
                name = prefabName + "_LOD0"
            };
            goLod0.transform.SetParent(go.transform, false);
            goLod0.AddComponent <MeshFilter>().sharedMesh       = meshLod0;
            goLod0.AddComponent <MeshRenderer>().sharedMaterial = material;

            GameObject goLod1 = new GameObject {
                name = prefabName + "_LOD1"
            };
            goLod1.transform.SetParent(go.transform, false);
            goLod1.AddComponent <MeshFilter>().sharedMesh       = meshLod1;
            goLod1.AddComponent <MeshRenderer>().sharedMaterial = material;

            GameObject goLod2 = new GameObject {
                name = prefabName + "_LOD2"
            };
            goLod2.transform.SetParent(go.transform, false);
            goLod2.AddComponent <MeshFilter>().sharedMesh       = meshLod2;
            goLod2.AddComponent <MeshRenderer>().sharedMaterial = material;

            AssetDatabase.CreateAsset(meshLod0, meshFilenameLod0);
            AssetDatabase.CreateAsset(meshLod1, meshFilenameLod1);
            AssetDatabase.CreateAsset(meshLod2, meshFilenameLod2);

            LODGroup lodGroup = go.AddComponent <LODGroup>();
            LOD[]    lods     = new LOD[4];
            lods[0] = CreateLOD(goLod0, 1f);
            lods[1] = CreateLOD(goLod0, 0.50f);
            lods[2] = CreateLOD(goLod1, 0.15f);
            lods[3] = CreateLOD(goLod2, 0.05f);
            lodGroup.SetLODs(lods);

            transform.position = oldPosition;
            transform.rotation = oldRotation;

#if UNITY_2018_3_OR_NEWER
            PrefabUtility.SaveAsPrefabAsset(go, prefabFilename);
#else
            PrefabUtility.CreatePrefab(prefabFilename, go);
#endif

            AssetDatabase.Refresh();
#endif
        }
Esempio n. 12
0
    private void BuildTreeTypeCellMesh(GameObject owner, TreeSystemStructuredTrees cell, List <TreeSystemStoredInstance> trees, TreeSystemPrototypeData data)
    {
        int[] originalTriangles = m_SystemQuad.triangles;

        RowCol pos = cell.m_Position;

        GameObject mesh = new GameObject();

        // Mark object as static
        GameObjectUtility.SetStaticEditorFlags(mesh, StaticEditorFlags.OccludeeStatic | StaticEditorFlags.ReflectionProbeStatic);

        mesh.transform.SetParent(owner.transform);
        mesh.name = "MeshCell[" + pos.m_Row + "_" + pos.m_Col + "_" + data.m_TreePrototype.name + "]";

        Vector3 worldScale = new Vector3(data.m_Size.x, data.m_Size.y, data.m_Size.x);

        // Set material
        MeshRenderer rend = mesh.AddComponent <MeshRenderer>();

        rend.sharedMaterial = data.m_BillboardBatchMaterial;

        MeshFilter filter = mesh.AddComponent <MeshFilter>();

        Mesh treeMesh = new Mesh();

        treeMesh.name = "TreeCell[" + pos.m_Row + "_" + pos.m_Col + "_" + data.m_TreePrototype.name + "]";

        List <Vector4> m_TempWorldPositions = new List <Vector4>();
        List <Vector3> m_TempWorldScales    = new List <Vector3>();
        List <Vector3> m_TempQuadVertices   = new List <Vector3>();
        List <Vector4> m_TempQuadTangents   = new List <Vector4>();
        List <Vector3> m_TempQuadNormals    = new List <Vector3>();
        List <int>     m_TempQuadIndices    = new List <int>();

        Bounds newBounds = new Bounds();

        newBounds.center = cell.m_BoundsBox.center;

        // TODO: populate mesh data
        for (int treeIndex = 0; treeIndex < trees.Count; treeIndex++)
        {
            Vector3 position = trees[treeIndex].m_WorldPosition;
            Vector3 scale    = trees[treeIndex].m_WorldScale;
            float   rot      = trees[treeIndex].m_WorldRotation;

            // Offset world position, by the grounding factor
            Vector3 instancePos = position;
            instancePos.y += data.m_Size.z;

            // Scale by the world scale too so that we don't have to do an extra multip
            Vector3 instanceScale = scale;
            instanceScale.Scale(worldScale);

            // Encapsulate bottom and top also
            newBounds.Encapsulate(instancePos);
            newBounds.Encapsulate(instancePos + new Vector3(0, data.m_Size.y, 0));

            // Add the world and scale data
            for (int index = 0; index < 4; index++)
            {
                Vector4 posAndRot = instancePos;
                posAndRot.w = rot;

                m_TempWorldPositions.Add(posAndRot);
                m_TempWorldScales.Add(instanceScale);
            }

            // Add stanard quad data
            m_TempQuadVertices.AddRange(m_SystemQuad.vertices);
            m_TempQuadTangents.AddRange(m_SystemQuad.tangents);
            m_TempQuadNormals.AddRange(m_SystemQuad.normals);

            // Calculate triangle indixes
            m_TempQuadIndices.AddRange(originalTriangles);
            for (int triIndex = 0; triIndex < 6; triIndex++)
            {
                // Just add to the triangles the existing triangles + the new indices
                m_TempQuadIndices[triIndex + 6 * treeIndex] = originalTriangles[triIndex] + 4 * treeIndex;
            }
        }

        treeMesh.Clear();

        // Set standard data
        treeMesh.SetVertices(m_TempQuadVertices);
        treeMesh.SetNormals(m_TempQuadNormals);
        treeMesh.SetTangents(m_TempQuadTangents);

        // Set the custom data
        treeMesh.SetUVs(1, m_TempWorldPositions);
        treeMesh.SetUVs(2, m_TempWorldScales);

        // Set triangles and do not calculate bounds
        treeMesh.SetTriangles(m_TempQuadIndices, 0, false);

        // Set the manually calculated bounds
        treeMesh.bounds = newBounds;

        treeMesh.UploadMeshData(true);

        // Set the mesh
        filter.mesh = treeMesh;

        // Add the mesh' lod group
        if (m_AddLODGroupToBillboards)
        {
            LODGroup group = mesh.AddComponent <LODGroup>();
            group.animateCrossFading = false;
            group.fadeMode           = LODFadeMode.None;

            group.SetLODs(new LOD[] { new LOD(m_BillboardScreenSize, new Renderer[] { rend }) });
            group.RecalculateBounds();
        }
    }
Esempio n. 13
0
        void CreateMergedLODGroupFromSingleMaterialMeshes()
        {
            string path = EditorUtility.SaveFilePanelInProject("Save merged mesh", "", "",
                                                               "Please enter a file name to save the merged mesh to");

            if (path.Length != 0)
            {
                if (_lodGroupVegetationMeshCombiner.TargetGameObject == null)
                {
                    return;
                }

                LODGroup   lodGroup     = _lodGroupVegetationMeshCombiner.TargetGameObject.GetComponentInChildren <LODGroup>();
                GameObject sourceObject = _lodGroupVegetationMeshCombiner.TargetGameObject;

                Vector3    targetPosition = sourceObject.transform.position;
                Quaternion targetRotation = sourceObject.transform.rotation;
                Vector3    targetScale    = sourceObject.transform.localScale;

                sourceObject.transform.position   = new Vector3(0, 0, 0);
                sourceObject.transform.rotation   = Quaternion.identity;
                sourceObject.transform.localScale = Vector3.one;

                if (lodGroup == null)
                {
                    return;
                }

                GameObject             mergedLODGroupObject = new GameObject("Merged_" + sourceObject.name);
                LODGroup               newLODGroup          = mergedLODGroupObject.AddComponent <LODGroup>();
                List <CombineInstance> combineInstanceList  = new List <CombineInstance>();

                LOD[] lods = lodGroup.GetLODs();

                // ReSharper disable once InconsistentNaming
                LOD[] newLODs = lodGroup.GetLODs();
                for (int i = 0; i <= lods.Length - 1; i++)
                {
                    combineInstanceList.Clear();
                    LOD lod = lods[i];

                    if (lod.renderers.Length > 0)
                    {
                        GameObject lodObject = new GameObject(sourceObject.name + "_LOD" + i.ToString());
                        lodObject.transform.SetParent(mergedLODGroupObject.transform);
                        MeshRenderer meshRenderer = lodObject.AddComponent <MeshRenderer>();
                        MeshFilter   meshFilter   = lodObject.AddComponent <MeshFilter>();
                        Renderer[]   newRenderers = new Renderer[1];
                        newRenderers[0]      = meshRenderer;
                        newLODs[i].renderers = newRenderers;


                        List <Material> materialList = new List <Material>();
                        for (int j = 0; j <= lod.renderers.Length - 1; j++)
                        {
                            MeshFilter tempMeshFilter = lod.renderers[j].gameObject.GetComponent <MeshFilter>();
                            if (!tempMeshFilter)
                            {
                                continue;
                            }

                            CombineInstance combineInstance = new CombineInstance
                            {
                                mesh = tempMeshFilter.sharedMesh, transform = meshFilter.transform.localToWorldMatrix
                            };
                            combineInstanceList.Add(combineInstance);
                            materialList.Add(lod.renderers[j].sharedMaterial);
                        }

                        Mesh       mesh      = new Mesh();
                        Material[] materials = materialList.ToArray();
                        mesh.CombineMeshes(combineInstanceList.ToArray(), false, true);

                        if (_lodGroupVegetationMeshCombiner.MergeSubmeshesWitEquialMaterial)
                        {
                            SubmeshCombiner submeshCombiner = new SubmeshCombiner();
                            for (int j = 0; j <= mesh.subMeshCount - 1; j++)
                            {
                                submeshCombiner.AddSubmesh(mesh.GetIndices(j), materials[j]);
                            }

                            submeshCombiner.UpdateMesh(mesh);
                            materials = submeshCombiner.GetMaterials();
                        }

                        meshFilter.sharedMesh = mesh;
                        AssetDatabase.CreateAsset(meshFilter.sharedMesh, path + "_LOD" + i.ToString() + ".asset");
                        meshRenderer.materials = materials;
                    }
                }

                newLODGroup.SetLODs(newLODs);

                sourceObject.transform.position   = targetPosition;
                sourceObject.transform.rotation   = targetRotation;
                sourceObject.transform.localScale = targetScale;
            }
        }
Esempio n. 14
0
        public static void GenerateLODs(LODGroup lodGroup, HashSet <Mesh> newMeshes = null)
        {
            LOD[] lods = lodGroup.GetLODs();

            // Cleanup
            for (int i = 1; i < lods.Length; i++)
            {
                foreach (Renderer renderer in lods[i].renderers)
                {
                    if (renderer != null)
                    {
                        Object.DestroyImmediate(renderer.gameObject);
                    }
                }
            }

            if (newMeshes == null)
            {
                newMeshes = new HashSet <Mesh>();
            }

            // Assign LOD0
            Renderer[] renderers = lodGroup.GetComponentsInChildren <Renderer>();
            lods[0].renderers = renderers;

            Dictionary <Mesh, ConnectedMesh> uniqueMeshes = new Dictionary <Mesh, ConnectedMesh>();

            foreach (Renderer renderer in renderers)
            {
                if (renderer is MeshRenderer meshRenderer)
                {
                    MeshFilter meshFilter = renderer.gameObject.GetComponent <MeshFilter>();
                    if (meshFilter)
                    {
                        Mesh mesh = meshFilter.sharedMesh;
                        if (!uniqueMeshes.ContainsKey(mesh))
                        {
                            uniqueMeshes.TryAdd(mesh, m => UnityConverter.ToSharedMesh(m).ToConnectedMesh());
                        }
                    }
                }
                else if (renderer is SkinnedMeshRenderer skinnedMeshRenderer)
                {
                    Mesh mesh = skinnedMeshRenderer.sharedMesh;
                    if (!uniqueMeshes.ContainsKey(mesh))
                    {
                        uniqueMeshes.TryAdd(mesh, m => UnityConverter.ToSharedMesh(m).ToConnectedMesh());
                    }
                }
            }

            foreach (KeyValuePair <Mesh, ConnectedMesh> uniqueMesh in uniqueMeshes)
            {
                uniqueMesh.Value.MergePositions(0.0001);
                uniqueMesh.Value.MergeAttributes();
                uniqueMesh.Value.Compact();
            }

            SceneDecimator sceneDecimator = new SceneDecimator();

            sceneDecimator.Initialize(uniqueMeshes.Values);

            // Build LODs
            for (int i = 1; i < lods.Length; i++)
            {
                // Decimates gradually
                sceneDecimator.DecimateToRatio(lods[i - 1].screenRelativeTransitionHeight);

                Dictionary <Mesh, Mesh> optimizedMeshes = uniqueMeshes.ToDictionary(x => x.Key, x => x.Value.ToSharedMesh().ToUnityMesh());

                List <Renderer> lodRenderers = new List <Renderer>();

                foreach (Renderer renderer in renderers)
                {
                    if (renderer is MeshRenderer meshRenderer)
                    {
                        MeshFilter meshFilter = renderer.gameObject.GetComponent <MeshFilter>();
                        if (meshFilter)
                        {
                            GameObject gameObject = new GameObject(renderer.gameObject.name + "_LOD" + i);
                            gameObject.transform.parent        = renderer.transform;
                            gameObject.transform.localPosition = UnityEngine.Vector3.zero;
                            gameObject.transform.localRotation = UnityEngine.Quaternion.identity;
                            gameObject.transform.localScale    = UnityEngine.Vector3.one;

                            MeshRenderer mr = gameObject.AddComponent <MeshRenderer>();
                            MeshFilter   mf = gameObject.AddComponent <MeshFilter>();

                            Mesh originalMesh  = meshFilter.sharedMesh;
                            Mesh optimizedMesh = optimizedMeshes[originalMesh]; // Todo : Don't create new mesh if it's the same (tri count);

                            optimizedMesh.name = originalMesh.name + "_LOD" + i;

                            mr.sharedMaterials = meshRenderer.sharedMaterials;
                            mf.sharedMesh      = optimizedMesh;

                            newMeshes.Add(optimizedMesh);

                            lodRenderers.Add(mr);
                        }
                    }
                    else if (renderer is SkinnedMeshRenderer skinnedMeshRenderer)
                    {
                        GameObject gameObject = new GameObject(renderer.gameObject.name + "_LOD" + i);
                        gameObject.transform.parent        = renderer.transform;
                        gameObject.transform.localPosition = UnityEngine.Vector3.zero;
                        gameObject.transform.localRotation = UnityEngine.Quaternion.identity;
                        gameObject.transform.localScale    = UnityEngine.Vector3.one;

                        SkinnedMeshRenderer smr = gameObject.AddComponent <SkinnedMeshRenderer>();
                        smr.bones    = skinnedMeshRenderer.bones;
                        smr.rootBone = skinnedMeshRenderer.rootBone;

                        Mesh originalMesh  = skinnedMeshRenderer.sharedMesh;
                        Mesh optimizedMesh = optimizedMeshes[originalMesh]; // Todo : Don't create new mesh if it's the same (tri count);

                        optimizedMesh.name = originalMesh.name + "_LOD" + i;

                        smr.sharedMaterials = skinnedMeshRenderer.sharedMaterials;
                        smr.sharedMesh      = optimizedMesh;

                        optimizedMesh.bindposes = originalMesh.bindposes; // Copy poses

                        newMeshes.Add(optimizedMesh);

                        lodRenderers.Add(smr);
                    }
                }

                ///Debug.Log($"LOD{i} created with {lodRenderers.Count} renderers at {100f * lods[i - 1].screenRelativeTransitionHeight}% poly ratio");
                lods[i].renderers = lodRenderers.ToArray();
            }

            lodGroup.SetLODs(lods);
        }
    //READING / SAVING XML FILE

    public void ReadXMLTiles()
    {
        var tileContainer = TileCollection.Load(Path.Combine(Application.dataPath, "Tiles.xml"));
        // var xmlData = @"<TileCollection><tiles><Tiles name=""a""><model_path></model_path>x<material_path>y</material_path></Tiles></tiles></TileCollection>";
        // var tileContainer = TileCollection.LoadFromText(xmlData);
        // Debug.Log("Number of tiles in database: " + tileContainer.tiles.Length);
        //  Debug.Log(tileContainer.tiles[0].model_path);

        // AddButton(tileContainer.tiles.Length);  //ADD BUTTONS TO UI


        var parentDatabase = new GameObject();

        parentDatabase.name  = "Tile_Database";
        parentDatabase.layer = 10;
        for (int c = 0; c < tileContainer.tiles.Length; c++)
        {
            FilePath = tileContainer.tiles[c].model_path;
            Debug.Log(tileContainer.tiles[c].model_path);
            //  FilePath = "Models/Tiles/Floors/nukeguard/mesh1";
            GameObject model = Resources.Load <GameObject>(FilePath);
            GameObject obj   = (GameObject)Instantiate(model);

            //  obj.AddComponent(typeof(LODGroup));


            foreach (Transform child in obj.transform)
            {
                child.gameObject.layer = 10;
            }

            // obj.SetActive(false);
            obj.transform.SetParent(parentDatabase.transform);
            // obj.name = tileContainer.tiles[c].Name;
            obj.name = c.ToString();


            newButton  = Instantiate(Button);
            but        = newButton.GetComponent <SelectTileButton>();
            but.TileID = c;
            newButton.GetComponentInChildren <Text>().text = tileContainer.tiles[c].Name;
            newButton.transform.SetParent(BuildingMenu.transform);

            // TO REMOVE WHEN ALL TILES IS UNIFIED
            if (obj.transform.Find("Camera") != null)
            {
                obj.transform.Find("Camera").GetComponent <Camera>().enabled = false;
            }
            // END REMOVE


            //obj.GetComponent<LODGroup>().
            // /*
            if (obj.transform.Find("model") != null)
            {
                group = obj.AddComponent <LODGroup>();

                // Add 4 LOD levels
                LOD[] lods = new LOD[4];

                for (int i = 0; i < 4; i++)
                {
                    GameObject primType = obj.transform.Find("model").gameObject;
                    switch (i)
                    {
                    case 1:
                        primType = obj.transform.Find("lod1").gameObject;
                        break;

                    case 2:
                        primType = obj.transform.Find("lod2").gameObject;
                        break;

                    case 3:
                        primType = obj.transform.Find("lod3").gameObject;
                        break;
                    }

                    Renderer[] renderers = new Renderer[1];
                    renderers[0] = primType.GetComponentInChildren <Renderer>();
                    lods[i]      = new LOD(1.0F / (i + 1.2f), renderers);
                }
                group.SetLODs(lods);
                group.RecalculateBounds();
            }
        }
    }
Esempio n. 16
0
        private static void ParseFile_SceneShapesAttributes(XmlReader xml, ref I3DModel model, Entity part)
        {
            Entity.ShapeType type;
            if (!Enum.TryParse(xml.LocalName, out type))
            {
                throw new Exception($"Unrecognized shape type {xml.LocalName}");
            }
            part.Type = type;

            string name = ParseString(xml.GetAttribute("name"));

            //I3DTransform
            I3DTransform t = part.gameObject.AddComponent <I3DTransform>();

            t.Name            = name;
            t.Id              = ParseInt(xml.GetAttribute("nodeId"));
            t.IndexPath       = ""; //TODO: Make this
            t.Visibility      = ParseBool(xml.GetAttribute("visibility"), true);
            t.ClipDistance    = ParseInt(xml.GetAttribute("clipDistance"), 1000000);
            t.MinClipDistance = ParseInt(xml.GetAttribute("minClipDistance"));
            t.ObjectMask      = ParseInt(xml.GetAttribute("objectMask"), 0xffff);
            t.LOD             = ParseBool(xml.GetAttribute("lodDistance"));

            //Transform
            part.gameObject.transform.localPosition    = ParseVector3(xml.GetAttribute("translation"));
            part.gameObject.transform.localEulerAngles = ParseVector3(xml.GetAttribute("rotation"));
            Vector3 scale = xml.GetAttribute("scale") != null?ParseVector3(xml.GetAttribute("scale")) : Vector3.one;

            //scale.x *= -1;
            part.gameObject.transform.localScale = scale;

            //Rigidbody
            bool bStatic    = ParseBool(xml.GetAttribute("static"));
            bool bDynamic   = ParseBool(xml.GetAttribute("dynamic"));
            bool bKinematic = ParseBool(xml.GetAttribute("kinematic"));

            if (bStatic || bDynamic || bKinematic)
            {
                t.RigidBody = true;

                I3DRigidBody r = part.gameObject.AddComponent <I3DRigidBody>();
                if (bStatic)
                {
                    r.Type = RigidBodyType.Static;
                }
                else if (bDynamic)
                {
                    r.Type = RigidBodyType.Dynamic;
                }
                else
                {
                    r.Type = RigidBodyType.Kinematic;
                }

                r.Compound         = ParseBool(xml.GetAttribute("compound"));
                r.CompoundChild    = ParseBool(xml.GetAttribute("compoundChild"));
                r.Collision        = ParseBool(xml.GetAttribute("collision"), true);
                r.Trigger          = ParseBool(xml.GetAttribute("trigger"));
                r.CollisionMask    = ParseInt(xml.GetAttribute("collisionMask"));
                r.Restitution      = ParseFloat(xml.GetAttribute("restitution"));
                r.StaticFriction   = ParseFloat(xml.GetAttribute("staticFriction"), 0.5f);
                r.DynamicFriction  = ParseFloat(xml.GetAttribute("dynamicFriction"), 0.5f);
                r.LinearDamping    = ParseFloat(xml.GetAttribute("linearDamping"), 0.5f);
                r.AngularDamping   = ParseFloat(xml.GetAttribute("angularDamping"), 0.5f);
                r.Density          = ParseFloat(xml.GetAttribute("density"), 1);
                r.SolverIterations = ParseInt(xml.GetAttribute("solverIterationCount"), 4);
                //r.Mass = ParseFloat(xml.GetAttribute("mass"), 0.5f);
            }

            //Shape
            if (part.Type == Entity.ShapeType.Shape)
            {
                if (name.EndsWith("_lod0") || name.EndsWith("_lod1") || name.EndsWith("_lod2"))
                {
                    Transform parent   = part.transform.parent;
                    LODGroup  lodGroup = parent.GetComponent <LODGroup>();
                    if (lodGroup == null)
                    {
                        lodGroup = parent.gameObject.AddComponent <LODGroup>();
                        lodGroup.SetLODs(new LOD[] {});
                    }

                    int lodIndex = ParseInt(name.Substring(name.Length - 1));

                    LOD lod = new LOD {
                        renderers = new Renderer[] { part.GetComponent <MeshRenderer>() }
                    };

                    List <LOD> lods = lodGroup.GetLODs().ToList();

                    if (lodIndex > lods.Count)
                    {
                        lods.Add(lod);
                    }
                    else
                    {
                        lods.Insert(lodIndex, lod);
                    }

                    // Update the transition point for all LODs
                    float lodGap = 1f / lods.Count;
                    for (int i = 0; i < lods.Count; i++)
                    {
                        lods[i] = new LOD((lods.Count - i - 1) * lodGap, lods[i].renderers);
                    }

                    lodGroup.SetLODs(lods.ToArray());
                    lodGroup.RecalculateBounds();
                }

                Shape s = part.gameObject.AddComponent <Shape>();
                s.ID               = ParseInt(xml.GetAttribute("shapeId"));
                s.CastShadows      = ParseBool(xml.GetAttribute("castsShadows"));
                s.ReceiveShadows   = ParseBool(xml.GetAttribute("receiveShadows"));
                s.NonRenderable    = ParseBool(xml.GetAttribute("nonRenderable"));
                s.BuildNavMeshMask = ParseInt(xml.GetAttribute("buildNavMeshMask"));
                s._Materials       = Shape.ParseMaterialString(ParseString(xml.GetAttribute("materialIds")));

                part.Shape = s;

                //Assign the shape object according to ID
                foreach (I3DShapeData sh in model.ShapeDatas)
                {
                    if (part.Shape.ID != sh.ID)
                    {
                        continue;
                    }

                    part.Shape.ID   = sh.ID;
                    part.Shape.Name = sh.Name;
                    part.Shape.Mesh = sh.Mesh;

                    part.GetComponent <MeshFilter>().mesh = sh.Mesh;
                    break;
                }

                //Assign material according to ID
                part.Shape.Materials = new I3DMaterial[part.Shape._Materials.Length];

                for (int i = 0; i < part.Shape._Materials.Length; i++)
                {
                    int shapeMatId = part.Shape._Materials[i];
                    foreach (I3DMaterial mat in model.Materials)
                    {
                        if (mat.Id != shapeMatId)
                        {
                            continue;
                        }

                        part.Shape.Materials[i] = mat;
                    }
                }
            }
            else if (part.Type == Entity.ShapeType.TerrainTransformGroup)
            {
                int heightMapId = ParseInt(xml.GetAttribute("heightMapId"));
                //int patchSize = ParseInt(xml.GetAttribute("patchSize"));
                float heightScale   = ParseFloat(xml.GetAttribute("heightScale"));
                float unitsPerPixel = ParseFloat(xml.GetAttribute("unitsPerPixel"));

                I3DFile heightMapFile = model.GetFile(heightMapId);
                if (heightMapFile != null)
                {
                    I3DTerrain i3DTerrain = part.gameObject.AddComponent <I3DTerrain>();
                    i3DTerrain.AlphaWidth             = ParseInt(xml.GetAttribute("lodTextureSize"));
                    i3DTerrain.AlphaHeight            = ParseInt(xml.GetAttribute("lodTextureSize"));
                    i3DTerrain.Terrain                = part.gameObject.AddComponent <Terrain>();
                    i3DTerrain.TerrainData            = new TerrainData();
                    i3DTerrain.TerrainCollider        = part.gameObject.AddComponent <TerrainCollider>();
                    i3DTerrain.HeightMapScale         = heightScale;
                    i3DTerrain.HeightMapUnitsPerPixel = unitsPerPixel;
                    i3DTerrain.HeightMap              = TextureLoader.GetTexture(heightMapFile.AbsolutePath);

                    i3DTerrain.BuildHeightmap();
                }
            }
            else if (part.Type == Entity.ShapeType.Layer)
            {
                I3DFile detailMapFile = model.GetFile(ParseInt(xml.GetAttribute("detailMapId"))); // Detail map = diffuse texture
                I3DFile normalMapFile = model.GetFile(ParseInt(xml.GetAttribute("normalMapId"))); // Normal map = normal texture
                I3DFile weightMapFile = model.GetFile(ParseInt(xml.GetAttribute("weightMapId"))); // Weight map = splat map?
                //I3DFile distanceMapFile = model.GetFile(ParseInt(xml.GetAttribute("distanceMapId"))); // Distance map = low-res diffuse texture

                int unitSize = ParseInt(xml.GetAttribute("unitSize"));
                //int distanceMapUnitSize = ParseInt(xml.GetAttribute("distanceMapUnitSize")); // Unknown

                SplatPrototype splat = new SplatPrototype
                {
                    texture    = TextureLoader.GetTexture(detailMapFile.AbsolutePath),
                    normalMap  = TextureLoader.GetTexture(normalMapFile.AbsolutePath),
                    tileSize   = new Vector2(unitSize, unitSize),
                    tileOffset = Vector2.zero
                };

                I3DTerrain i3Dterrain = part.GetComponentInParent <I3DTerrain>();
                i3Dterrain.Layers.Add(new I3DTerrainLayer
                {
                    Priority   = ParseInt(xml.GetAttribute("priority")),
                    Attributes = ParseVector4(xml.GetAttribute("attributes")),
                    SplatMap   = splat,
                    Weights    = I3DTerrainUtil.Parse8BitMap(TextureLoader.GetTexture(weightMapFile.AbsolutePath))
                });
            }
        }
    public void Generate()
    {
        //----------------- INITIALIZE VARIABLES/LISTS
        CombinableMeshObject[] CMOS = GetComponentsInChildren <CombinableMeshObject>();

        if (CMOS.Length == 0)
        {
            throw new Exception("Object has no children");
        }
        else if (CMOS.Length == 1)
        {
            throw new Exception("Object has only one child");
        }

        TotalObjects = CMOS.Length;

        TotalVerts = CMOS[0].MeshLODS[0].sharedMesh.vertices.Length * CMOS.Length;

        if (TotalVerts > 60000)
        {
            throw new Exception("Object has too many vertices");
        }

        CombinedPositions = new List <Vector3>();
        CombinedRotations = new List <Quaternion>();

        foreach (CombinableMeshObject CMO in CMOS)
        {
            CombinedPositions.Add(CMO.transform.position);
            CombinedRotations.Add(CMO.transform.rotation);
        }

        CombinedPrefab = PrefabUtility.GetCorrespondingObjectFromSource(CMOS[0].gameObject);

        //----------------- MAKE PARENT OBJECTS/COMPONENTS
        CombinedObject      = new GameObject();
        CombinedObject.name = "Combined Object";
        CombinedObject.transform.SetParent(this.transform);
        MeshCollider CombinedObjectCollider = CombinedObject.AddComponent(typeof(MeshCollider)) as MeshCollider;
        LODGroup     CombinedObjectLODGroup = CombinedObject.AddComponent(typeof(LODGroup)) as LODGroup;

        GameObject CombinedMapModel = new GameObject();

        CombinedMapModel.name  = "Combined Map Model";
        CombinedMapModel.layer = 10;
        CombinedMapModel.transform.SetParent(CombinedObject.transform);
        Material     MapMaterial     = CMOS[0].MapMesh.GetComponent <MeshRenderer>().sharedMaterial;
        MeshRenderer MapMeshRenderer = CombinedMapModel.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
        MeshFilter   MapMeshFilter   = CombinedMapModel.AddComponent(typeof(MeshFilter)) as MeshFilter;

        MapMeshRenderer.sharedMaterial    = MapMaterial;
        MapMeshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;

        GameObject CombinedModel = new GameObject();

        CombinedModel.name = "Combined Model";
        CombinedModel.transform.SetParent(CombinedObject.transform);

        //----------------- MAKE LOD OBJECTS AND MERGE MESHES

        int LODCount = CMOS[0].MeshLODS.Count;

        MeshRenderer[] Rends = new MeshRenderer[LODCount];

        for (int i = 0; i < CMOS.Length; i++)
        {
            PrefabUtility.UnpackPrefabInstance(CMOS[i].gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
        }

        for (int i = 0; i < LODCount; i++)
        {
            GameObject CombinedLOD = new GameObject();
            CombinedLOD.name = "Model_LOD" + i;
            CombinedLOD.transform.SetParent(CombinedModel.transform);

            Material   ModelMaterial   = CMOS[0].MeshLODS[i].GetComponent <MeshRenderer>().sharedMaterial;
            MeshFilter ModelMeshFilter = CombinedLOD.AddComponent(typeof(MeshFilter)) as MeshFilter;

            MeshFilter[]      modelMeshFilters = new MeshFilter[CMOS.Length];
            CombineInstance[] modelCombine     = new CombineInstance[CMOS.Length];

            for (int x = 0; x < CMOS.Length; x++)
            {
                modelMeshFilters[x] = CMOS[x].MeshLODS[i];
            }

            for (int x = 0; x < CMOS.Length; x++)
            {
                modelCombine[x].mesh      = modelMeshFilters[x].sharedMesh;
                modelCombine[x].transform = modelMeshFilters[x].transform.localToWorldMatrix;
            }

            ModelMeshFilter.sharedMesh = new Mesh();
            ModelMeshFilter.sharedMesh.CombineMeshes(modelCombine);

            MeshRenderer ModelMeshRenderer = CombinedLOD.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
            ModelMeshRenderer.sharedMaterial    = ModelMaterial;
            ModelMeshRenderer.shadowCastingMode = CMOS[0].MeshLODS[i].GetComponent <MeshRenderer>().shadowCastingMode;
            Rends[i] = ModelMeshRenderer;
        }

        //----------------- GENERATE MAP MESH
        CombineInstance[] mapCombine     = new CombineInstance[CMOS.Length];
        MeshFilter[]      mapMeshFilters = new MeshFilter[CMOS.Length];

        for (int i = 0; i < CMOS.Length; i++)
        {
            mapMeshFilters[i] = CMOS[i].MapMesh;
        }

        for (int i = 0; i < CMOS.Length; i++)
        {
            mapCombine[i].mesh      = mapMeshFilters[i].sharedMesh;
            mapCombine[i].transform = mapMeshFilters[i].transform.localToWorldMatrix;
        }

        MapMeshFilter.sharedMesh = new Mesh();
        MapMeshFilter.sharedMesh.CombineMeshes(mapCombine);

        CombinedObjectCollider.sharedMesh = Rends[CMOS[0].ColliderLODIndex].GetComponent <MeshFilter>().sharedMesh;

        //Debug.Log(Rends[0].GetComponent<MeshFilter>().sharedMesh.vertices.Length);

        MeshRenderer[,] LODRenderers = new MeshRenderer[LODCount, 1];  //only 1 mesh per lod group

        for (int i = 0; i < LODCount; i++)
        {
            LODRenderers[i, 0] = Rends[i];
        }

        //----------------- MAKE LODS WITH EACH RENDERER
        LOD[] CombinedMeshLODS = new LOD[LODCount];
        for (int i = 0; i < LODCount; i++)
        {
            MeshRenderer[] MeshRenArray = new MeshRenderer[] { LODRenderers[i, 0] };

            if (i < LODCount - 1)
            {
                CombinedMeshLODS[i] = new LOD(0.85f / (i + 1f), MeshRenArray);
            }
            else
            {
                CombinedMeshLODS[i] = new LOD(0.005f, MeshRenArray);
            }
        }
        CombinedObjectLODGroup.SetLODs(CombinedMeshLODS);

        //----------------- FINALIZE
        foreach (CombinableMeshObject CMO in CMOS)
        {
            DestroyImmediate(CMO.gameObject);
        }

        CombinedObjectLODGroup.RecalculateBounds();

        AddTag();

        Generated = true;
    }
Esempio n. 18
0
    public void SaveAsPrefab(bool groupedSave = false, bool usingHDRP = false)
    {
        var    oldMesh = filter.sharedMesh;
        string name    = gameObject.name;
        string path    = saveTreeFolder;

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        #if (UNITY_2017 || UNITY_2018_1 || UNITY_2018_2)
        bool replacePrefab = false;  //=> value never Used, taged by dan_wipf => used for unity up to 2018.2
        #endif

        if (!System.IO.Directory.Exists(path))
        {
            EditorUtility.DisplayDialog("Invalid Path", "The path is not valid, you can chose it with the find folder button", "Ok");
            return;
        }
        if (AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject))) // Overriding prefab dialog
        {
            if (EditorUtility.DisplayDialog("Are you sure?", "The prefab already exists. Do you want to overwrite it?", "Yes", "No"))
            {
                FileUtil.DeleteFileOrDirectory(Path.Combine(path, name + "_meshes"));
                #if (UNITY_2017 || UNITY_2018_1 || UNITY_2018_2)
                replacePrefab = true; //  => value never Used, taged by dan_wipf => used for unity up to 2018.2
                #endif
            }
            else
            {
                name += "_1";
            }
        }
        Mesh[] meshes       = new Mesh[LODs.Count];
        string meshesFolder = AssetDatabase.CreateFolder(path, name + "_meshes");
        meshesFolder = AssetDatabase.GUIDToAssetPath(meshesFolder) + Path.DirectorySeparatorChar;
        Material[] materials  = SaveMaterials(meshesFolder);
        GameObject TreeObject = new GameObject(name);                 // Tree game object
        LODGroup   group      = TreeObject.AddComponent <LODGroup>(); // LOD Group
        group.fadeMode = LODFadeMode.CrossFade;
        LOD[] lods = new LOD[LODs.Count + 1];

        // Generating Billboard
        LodIndex = LODs.Count - 1;
        GenerateTree(true);
        GameObject billboard = CreateBillboard(meshesFolder, name, usingHDRP);
        Renderer[] bill_re   = new Renderer[1] {
            billboard.GetComponent <MeshRenderer>()
        };
        lods[lods.Length - 1] = new LOD(.01f, bill_re);


        for (LodIndex = LODs.Count - 1; LodIndex >= 0; LodIndex--)               // create and save all LOD meshes
        {
            string meshPath = meshesFolder + name + "_LOD" + LodIndex + ".mesh"; //updating path for each LOD
            Mesh   mesh     = GenerateTree(instantAo: true);
            meshes[LodIndex] = mesh;
            AssetDatabase.CreateAsset(mesh, meshPath);
        }

        for (int i = 0; i < LODs.Count; i++) // assigning lod meshes to LOD array
        {
            GameObject go = new GameObject(name + "_LOD" + i.ToString());
            go.transform.parent = TreeObject.transform;
            MeshFilter mf = go.AddComponent <MeshFilter>();
            mf.mesh = meshes[i];
            Renderer[] re = new Renderer[1] {
                go.AddComponent <MeshRenderer>()
            };                                                       // the renderer to put in LODs
            re[0].sharedMaterials = materials;
            float t = Mathf.Pow((i + 1) * 1f / (LODs.Count + 1), 1); // float between 0 and 1 following f(x) = pow(x, n)
            lods[i] = new LOD((1 - t) * 0.9f + t * .01f, re);        // assigning renderer
            lods[i].fadeTransitionWidth = 0.25f;
        }

        billboard.transform.parent = TreeObject.transform; // making billboard child of tree object


        group.SetLODs(lods); // assigning LODs to lod group
        group.animateCrossFading = true;
        group.RecalculateBounds();

        string prefabPath = path + "/" + name + ".prefab";

        Object prefab;

        #if (UNITY_2017 || UNITY_2018_1 || UNITY_2018_2)
        if (replacePrefab)
        {
            Object targetPrefab = AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject));
            prefab = PrefabUtility.ReplacePrefab(TreeObject, targetPrefab, ReplacePrefabOptions.ConnectToPrefab);
        }
        else
        {
            prefab = PrefabUtility.CreatePrefab(prefabPath, TreeObject, ReplacePrefabOptions.ConnectToPrefab);
        }
        #else
        prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(TreeObject, prefabPath, InteractionMode.AutomatedAction);
        #endif

        AssetDatabase.SaveAssets();
        DestroyImmediate(TreeObject);

        if (!groupedSave)
        {
            // select newly created prefab in folder
            Selection.activeObject = prefab;
            // Also flash the folder yellow to highlight it
            EditorGUIUtility.PingObject(prefab);
            EditorUtility.DisplayDialog("Prefab saved !", "The prefab is saved, you can now delete the tree and use the prefab instead", "Ok");
        }

        LodIndex          = 0;
        filter.sharedMesh = oldMesh;
    }
        override public void OnInspectorGUI()
        {
            //base.OnInspectorGUI();

            if (m_foldout == null)
            {
                m_foldout = "foldout";
            }

            if (LockIconOpen == null)
            {
                LockIconOpen = new GUIContent(EditorGUIUtility.IconContent("LockIcon-On"));
            }

            if (LockIconClosed == null)
            {
                LockIconClosed = new GUIContent(EditorGUIUtility.IconContent("LockIcon"));
            }

            if (TextureIcon == null)
            {
                TextureIcon      = new GUIContent(EditorGUIUtility.IconContent("Texture Icon"));
                TextureIcon.text = " Bake Impostor";
            }

            if (CreateIcon == null)
            {
                CreateIcon      = new GUIContent(EditorGUIUtility.IconContent("Toolbar Plus"));
                CreateIcon.text = "";
            }

            if (SettingsIcon == null)
            {
                SettingsIcon = new GUIContent(EditorGUIUtility.IconContent("icons/d_TerrainInspector.TerrainToolSettings.png"));
            }

            m_instance = (target as AmplifyImpostor);

            bool triangulateMesh    = false;
            bool autoChangeToManual = false;
            bool bakeTextures       = false;

            if (m_instance.LodGroup != null && m_instance.m_lastImpostor == null)
            {
                double deltaTime = Time.realtimeSinceStartup - lastTime;
                lastTime = Time.realtimeSinceStartup;
                m_flash  = Color.Lerp(m_flash, Color.white, (float)deltaTime * 3f);
            }
            else
            {
                m_flash = Color.white;
            }
            EditorGUI.BeginChangeCheck();
            m_instance.Data = EditorGUILayout.ObjectField(AssetFieldStr, m_instance.Data, typeof(AmplifyImpostorAsset), false) as AmplifyImpostorAsset;
            if (m_instance.Data != null)
            {
                m_currentData = m_instance.Data;
            }

            m_instance.LodGroup = EditorGUILayout.ObjectField(LODGroupStr, m_instance.LodGroup, typeof(LODGroup), true) as LODGroup;

            EditorGUILayout.BeginHorizontal();
            Color tempC = GUI.color;

            GUI.color = m_flash;
            EditorGUILayout.PropertyField(m_renderers, RenderersStr, true);
            GUI.color = tempC;
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(9);

            EditorGUILayout.BeginHorizontal();
            if (m_instance.Data != null)
            {
                EditorGUI.BeginChangeCheck();
                ImpostorBakingTools.GlobalBakingOptions = GUILayout.Toggle(ImpostorBakingTools.GlobalBakingOptions, SettingsIcon, "buttonleft", GUILayout.Width(32), GUILayout.Height(24));
                if (EditorGUI.EndChangeCheck())
                {
                    EditorPrefs.SetBool(ImpostorBakingTools.PrefGlobalBakingOptions, ImpostorBakingTools.GlobalBakingOptions);
                }
            }
            else
            {
                if (GUILayout.Button(CreateIcon, "buttonleft", GUILayout.Width(32), GUILayout.Height(24)))
                {
                    m_instance.CreateAssetFile(m_currentData);
                }
            }

            if (GUILayout.Button(TextureIcon, "buttonright", GUILayout.Height(24)))
            {
                if (m_instance.m_alphaTex == null)
                {
                    m_recalculatePreviewTexture = true;
                }

                bakeTextures = true;
            }

            EditorGUILayout.EndHorizontal();

            if (!(m_instance.transform.transform.localScale.x == m_instance.transform.transform.localScale.y && m_instance.transform.transform.localScale.y == m_instance.transform.transform.localScale.z))
            {
                EditorGUILayout.HelpBox("Impostors can't render non-uniform scales correctly. Please consider scaling the object uniformly or generate it as a child of one.", MessageType.Warning);
            }

            if ((m_currentData.HorizontalFrames > 16 || m_currentData.VerticalFrames > 16))
            {
                EditorGUILayout.HelpBox("Creating impostors with the axis frame number above 16 may take a lot longer to bake and save and the extra frames usually aren't necessary.", MessageType.Info);
            }

            if ((m_currentData.TexSize.x > 2048 || m_currentData.TexSize.y > 2048))
            {
                EditorGUILayout.HelpBox("Creating impostors with texture resolution above 2048px may take a while to bake and save.", MessageType.Info);
            }

            if (ImpostorBakingTools.GlobalBakingOptions && m_instance.Data != null)
            {
                EditorGUILayout.BeginVertical("helpbox");
                {
                    EditorGUI.BeginChangeCheck();
                    m_currentData.ImpostorType = (ImpostorType)EditorGUILayout.EnumPopup(BakeTypeStr, m_currentData.ImpostorType);
                    if (EditorGUI.EndChangeCheck())
                    {
                        m_recalculatePreviewTexture = true;
                        m_instance.m_alphaTex       = null;
                        if (m_instance.m_cutMode == CutMode.Automatic)
                        {
                            m_recalculateMesh = true;
                        }
                    }

                    EditorGUILayout.BeginHorizontal();
                    EditorGUI.BeginChangeCheck();
                    if (m_currentData.LockedSizes)
                    {
                        m_currentData.SelectedSize = EditorGUILayout.IntPopup(TextureSizeStr, m_currentData.SelectedSize, m_sizesStr, m_sizes);
                        m_currentData.LockedSizes  = GUILayout.Toggle(m_currentData.LockedSizes, LockIconOpen, "minibutton", GUILayout.Width(22));
                        m_currentData.TexSize.Set(m_currentData.SelectedSize, m_currentData.SelectedSize);
                    }
                    else
                    {
                        m_currentData.TexSize     = EditorGUILayout.Vector2Field(TextureSizeStr, m_currentData.TexSize);
                        m_currentData.LockedSizes = GUILayout.Toggle(m_currentData.LockedSizes, LockIconClosed, "minibutton", GUILayout.Width(22));
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        m_instance.m_alphaTex       = null;
                        m_recalculatePreviewTexture = true;
                        if (m_instance.m_cutMode == CutMode.Automatic)
                        {
                            m_recalculateMesh = true;
                        }
                    }
                    EditorGUILayout.EndHorizontal();

                    if (!m_currentData.DecoupleAxisFrames || m_currentData.ImpostorType != ImpostorType.Spherical)
                    {
                        EditorGUILayout.BeginHorizontal();
                        m_currentData.HorizontalFrames = EditorGUILayout.IntSlider(AxisFramesStr, m_currentData.HorizontalFrames, 1, 32);
                        m_currentData.VerticalFrames   = m_currentData.HorizontalFrames;
                        if (m_currentData.ImpostorType == ImpostorType.Spherical)
                        {
                            m_currentData.DecoupleAxisFrames = !GUILayout.Toggle(!m_currentData.DecoupleAxisFrames, LockIconOpen, "minibutton", GUILayout.Width(22));
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    else
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField(AxisFramesStr, "");
                        m_currentData.DecoupleAxisFrames = !GUILayout.Toggle(!m_currentData.DecoupleAxisFrames, LockIconClosed, "minibutton", GUILayout.Width(22));
                        EditorGUILayout.EndHorizontal();
                        EditorGUI.indentLevel++;
                        m_currentData.HorizontalFrames = EditorGUILayout.IntSlider("X", m_currentData.HorizontalFrames, 1, 32);
                        m_currentData.VerticalFrames   = EditorGUILayout.IntSlider("Y", m_currentData.VerticalFrames, 1, 32);
                        EditorGUI.indentLevel--;
                    }
                    m_currentData.PixelPadding = EditorGUILayout.IntSlider(PixelPaddingStr, m_currentData.PixelPadding, 0, 64);
#if UNITY_2017_3_OR_NEWER
                    m_currentData.BufferMask = (DeferredBuffers)EditorGUILayout.EnumFlagsField(RenderingMapsStr, m_currentData.BufferMask);
#else
                    m_currentData.BufferMask = (DeferredBuffers)EditorGUILayout.EnumMaskField(RenderingMapsStr, m_currentData.BufferMask);
#endif
                    m_currentData.NormalCompression = (NormalCompression)EditorGUILayout.EnumPopup(NormalCompressionStr, m_currentData.NormalCompression);
                    EditorGUI.BeginDisabledGroup(m_instance.m_lastImpostor != null || m_instance.LodGroup == null);
                    EditorGUI.BeginChangeCheck();
                    m_instance.m_lodReplacement = (LODReplacement)EditorGUILayout.EnumPopup(LODModeStr, m_instance.m_lodReplacement);
                    EditorGUI.BeginDisabledGroup(m_instance.m_lodReplacement < LODReplacement.ReplaceSpecific || m_instance.LodGroup == null);
                    {
                        int maxLods = 0;
                        if (m_instance.LodGroup != null)
                        {
                            maxLods = m_instance.LodGroup.lodCount - 1;
                        }

                        m_instance.m_insertIndex = EditorGUILayout.IntSlider(LODTargetIndexStr, m_instance.m_insertIndex, 0, maxLods);
                    }
                    EditorGUI.EndDisabledGroup();
                    if (EditorGUI.EndChangeCheck())
                    {
                        ReCheckRenderers();
                    }
                    EditorGUI.EndDisabledGroup();

                    if ((m_billboardMesh || m_recalculatePreviewTexture) && m_instance.m_alphaTex == null)
                    {
                        m_instance.RenderCombinedAlpha(m_currentData);
                        RenderTexture.active  = m_instance.CombinedAlphaTexture;
                        m_instance.m_alphaTex = new Texture2D(m_instance.CombinedAlphaTexture.width, m_instance.CombinedAlphaTexture.height, TextureFormat.RGBAFloat, false);
                        m_instance.m_alphaTex.ReadPixels(new Rect(0, 0, m_instance.CombinedAlphaTexture.width, m_instance.CombinedAlphaTexture.height), 0, 0);
                        m_instance.m_alphaTex.Apply();
                        m_instance.ClearCombinedAlphaBuffer();

                        m_recalculatePreviewTexture = false;
                    }

                    EditorGUI.indentLevel++;
                    m_billboardMesh = GUILayout.Toggle(m_billboardMesh, "Billboard Mesh", "foldout");
                    EditorGUI.indentLevel--;
                    int cutPreviewSize = 160;
                    EditorGUILayout.BeginHorizontal();
                    if (m_billboardMesh)
                    {
                        Rect rect      = GUILayoutUtility.GetRect(cutPreviewSize + 10, cutPreviewSize + 10, cutPreviewSize + 10, cutPreviewSize + 10);
                        int  controlID = GUIUtility.GetControlID("miniShapeEditorControl".GetHashCode(), FocusType.Passive, rect);
                        Rect texRect   = new Rect(5, 5, cutPreviewSize, cutPreviewSize);
                        Rect hotRect   = new Rect(0, 0, cutPreviewSize + 10, cutPreviewSize + 10);
                        GUI.BeginClip(rect);
                        if (m_instance.m_alphaTex != null)
                        {
                            Graphics.DrawTexture(texRect, m_instance.m_alphaTex, m_alphaMaterial, 3);
                        }
                        else
                        {
                            Graphics.DrawTexture(texRect, Texture2D.blackTexture, m_alphaMaterial, 3);
                        }

                        switch (Event.current.GetTypeForControl(controlID))
                        {
                        case EventType.MouseDown:
                            if (hotRect.Contains(Event.current.mousePosition))
                            {
                                for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                                {
                                    Rect handleRect = new Rect(m_currentData.ShapePoints[i].x * cutPreviewSize, m_currentData.ShapePoints[i].y * cutPreviewSize, 10, 10);
                                    if (Event.current.type == EventType.MouseDown && handleRect.Contains(Event.current.mousePosition))
                                    {
                                        EditorGUI.FocusTextInControl(null);
                                        m_activeHandle      = i;
                                        m_lastPointSelected = i;
                                        m_lastMousePos      = Event.current.mousePosition;
                                        m_originalPos       = m_currentData.ShapePoints[i];
                                    }
                                }

                                GUIUtility.hotControl = controlID;
                                //Event.current.Use();
                            }
                            break;

                        case EventType.Ignore:
                        case EventType.MouseUp:
                            if (GUIUtility.hotControl == controlID)
                            {
                                m_activeHandle        = -1;
                                triangulateMesh       = true;
                                GUIUtility.hotControl = 0;
                                //Event.current.Use();
                                GUI.changed = true;
                            }
                            break;

                        case EventType.MouseDrag:
                            if (GUIUtility.hotControl == controlID && m_activeHandle > -1)
                            {
                                m_currentData.ShapePoints[m_activeHandle] = m_originalPos + (Event.current.mousePosition - m_lastMousePos) / (cutPreviewSize + 10);
                                if (Event.current.modifiers != EventModifiers.Control)
                                {
                                    m_currentData.ShapePoints[m_activeHandle].x = (float)Math.Round(m_currentData.ShapePoints[m_activeHandle].x, 2);
                                    m_currentData.ShapePoints[m_activeHandle].y = (float)Math.Round(m_currentData.ShapePoints[m_activeHandle].y, 2);
                                }

                                m_currentData.ShapePoints[m_activeHandle].x = Mathf.Clamp01(m_currentData.ShapePoints[m_activeHandle].x);
                                m_currentData.ShapePoints[m_activeHandle].y = Mathf.Clamp01(m_currentData.ShapePoints[m_activeHandle].y);
                                autoChangeToManual = true;
                                //Event.current.Use();
                            }
                            break;
                        }

                        if (Event.current.type == EventType.Repaint)
                        {
                            Vector3[] allpoints = new Vector3[m_currentData.ShapePoints.Length + 1];
                            for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                            {
                                allpoints[i] = new Vector3(m_currentData.ShapePoints[i].x * cutPreviewSize + 5, m_currentData.ShapePoints[i].y * cutPreviewSize + 5, 0);
                            }
                            allpoints[m_currentData.ShapePoints.Length] = allpoints[0];

                            Dictionary <string, bool> drawnList = new Dictionary <string, bool>();
                            for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                            {
                                if (i == m_currentData.ShapePoints.Length - 1)
                                {
                                    drawnList.Add(("0" + i), true);
                                }
                                else
                                {
                                    drawnList.Add((i + "" + (i + 1)), true);
                                }
                            }

                            if (m_previewMesh != null && m_instance.m_cutMode == CutMode.Manual)
                            {
                                //draw inside
                                Color cache = Handles.color;
                                Handles.color = new Color(1, 1, 1, 0.5f);
                                //Handles.color = Color.black;
                                for (int i = 0; i < m_previewMesh.triangles.Length - 1; i += 3)
                                {
                                    int    vert  = m_previewMesh.triangles[i];
                                    int    vert2 = m_previewMesh.triangles[i + 1];
                                    int    vert3 = m_previewMesh.triangles[i + 2];
                                    string ab    = vert < vert2 ? vert + "" + vert2 : vert2 + "" + vert;
                                    string bc    = vert2 < vert3 ? vert2 + "" + vert3 : vert3 + "" + vert2;
                                    string ac    = vert < vert3 ? vert + "" + vert3 : vert3 + "" + vert;

                                    Vector3 a = new Vector3(m_currentData.ShapePoints[vert].x * cutPreviewSize + 5, m_currentData.ShapePoints[vert].y * cutPreviewSize + 5, 0);
                                    Vector3 b = new Vector3(m_currentData.ShapePoints[vert2].x * cutPreviewSize + 5, m_currentData.ShapePoints[vert2].y * cutPreviewSize + 5, 0);
                                    Vector3 c = new Vector3(m_currentData.ShapePoints[vert3].x * cutPreviewSize + 5, m_currentData.ShapePoints[vert3].y * cutPreviewSize + 5, 0);
                                    if (!drawnList.ContainsKey(ab))
                                    {
                                        Handles.DrawAAPolyLine(new Vector3[] { a, b });
                                        drawnList.Add(ab, true);
                                    }
                                    if (!drawnList.ContainsKey(bc))
                                    {
                                        Handles.DrawAAPolyLine(new Vector3[] { b, c });
                                        drawnList.Add(bc, true);
                                    }
                                    if (!drawnList.ContainsKey(ac))
                                    {
                                        Handles.DrawAAPolyLine(new Vector3[] { a, c });
                                        drawnList.Add(ac, true);
                                    }
                                }
                                Handles.color = cache;
                            }

                            Handles.DrawAAPolyLine(allpoints);

                            if (m_instance.m_cutMode == CutMode.Manual)
                            {
                                for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                                {
                                    Rect handleRect = new Rect(m_currentData.ShapePoints[i].x * cutPreviewSize + 1, m_currentData.ShapePoints[i].y * cutPreviewSize + 1, 8, 8);
                                    Handles.DrawSolidRectangleWithOutline(handleRect, (m_activeHandle == i ? Color.cyan : Color.clear), (m_lastPointSelected == i && m_instance.m_cutMode == CutMode.Manual ? Color.cyan : Color.white));
                                }
                            }
                            else
                            {
                                for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                                {
                                    Rect handleRect = new Rect(m_currentData.ShapePoints[i].x * cutPreviewSize + 3, m_currentData.ShapePoints[i].y * cutPreviewSize + 3, 4, 4);
                                    Handles.DrawSolidRectangleWithOutline(handleRect, Color.white, Color.white);
                                }
                            }
                        }

                        GUI.EndClip();

                        EditorGUILayout.BeginVertical();
                        {
                            EditorGUI.BeginChangeCheck();
                            m_instance.m_cutMode = (CutMode)GUILayout.Toolbar((int)m_instance.m_cutMode, new[] { "Automatic", "Manual" });
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (m_instance.m_cutMode == CutMode.Automatic)
                                {
                                    m_recalculateMesh = true;
                                }
                            }
                            float cacheLabel = EditorGUIUtility.labelWidth;
                            EditorGUIUtility.labelWidth = 120;

                            switch (m_instance.m_cutMode)
                            {
                            default:
                            case CutMode.Automatic:
                            {
                                EditorGUI.BeginChangeCheck();
                                {
                                    m_currentData.MaxVertices = EditorGUILayout.IntSlider(MaxVerticesStr, m_currentData.MaxVertices, 4, 16);
                                    m_currentData.Tolerance   = EditorGUILayout.Slider(OutlineToleranceStr, m_currentData.Tolerance * 5, 0, 1f) * 0.2f;
                                    m_currentData.NormalScale = EditorGUILayout.Slider(NormalScaleStr, m_currentData.NormalScale, 0, 1.0f);
                                }
                                if (EditorGUI.EndChangeCheck())
                                {
                                    m_recalculateMesh = true;
                                }
                            }
                            break;

                            case CutMode.Manual:
                            {
                                m_currentData.MaxVertices = EditorGUILayout.IntSlider(MaxVerticesStr, m_currentData.MaxVertices, 4, 16);
                                m_currentData.Tolerance   = EditorGUILayout.Slider(OutlineToleranceStr, m_currentData.Tolerance * 5, 0, 1f) * 0.2f;
                                m_currentData.NormalScale = EditorGUILayout.Slider(NormalScaleStr, m_currentData.NormalScale, 0, 1.0f);
                                if (GUILayout.Button("Update"))
                                {
                                    m_recalculateMesh = true;
                                }

                                m_lastPointSelected = Mathf.Clamp(m_lastPointSelected, 0, m_currentData.ShapePoints.Length - 1);
                                EditorGUILayout.Space();
                                m_currentData.ShapePoints[m_lastPointSelected]   = EditorGUILayout.Vector2Field("", m_currentData.ShapePoints[m_lastPointSelected]);
                                m_currentData.ShapePoints[m_lastPointSelected].x = Mathf.Clamp01(m_currentData.ShapePoints[m_lastPointSelected].x);
                                m_currentData.ShapePoints[m_lastPointSelected].y = Mathf.Clamp01(m_currentData.ShapePoints[m_lastPointSelected].y);
                            }
                            break;
                            }
                            EditorGUIUtility.labelWidth = cacheLabel;
                        }
                        EditorGUILayout.EndVertical();
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndVertical();
            }

            if (m_recalculateMesh && m_instance.m_alphaTex != null)
            {
                m_recalculateMesh = false;

                // create a 2d texture for calculations
                Rect        testRect = new Rect(0, 0, m_instance.m_alphaTex.width, m_instance.m_alphaTex.height);
                Vector2[][] paths;
                SpriteUtilityEx.GenerateOutline(m_instance.m_alphaTex, testRect, m_currentData.Tolerance, 254, false, out paths);
                int sum = 0;
                for (int i = 0; i < paths.Length; i++)
                {
                    sum += paths[i].Length;
                }

                m_currentData.ShapePoints = new Vector2[sum];
                int index = 0;
                for (int i = 0; i < paths.Length; i++)
                {
                    for (int j = 0; j < paths[i].Length; j++)
                    {
                        m_currentData.ShapePoints[index] = (Vector2)(paths[i][j]) + (new Vector2(m_instance.m_alphaTex.width * 0.5f, m_instance.m_alphaTex.height * 0.5f));
                        m_currentData.ShapePoints[index] = Vector2.Scale(m_currentData.ShapePoints[index], new Vector2(1.0f / m_instance.m_alphaTex.width, 1.0f / m_instance.m_alphaTex.height));
                        index++;
                    }
                }

                // make it convex hull
                m_currentData.ShapePoints = Vector2Ex.ConvexHull(m_currentData.ShapePoints);

                // reduce vertices
                m_currentData.ShapePoints = Vector2Ex.ReduceVertices(m_currentData.ShapePoints, m_currentData.MaxVertices);

                // Resize the mesh using calculated normals
                m_currentData.ShapePoints = Vector2Ex.ScaleAlongNormals(m_currentData.ShapePoints, m_currentData.NormalScale);

                // clamp to box (needs a cut algorithm)
                for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                {
                    m_currentData.ShapePoints[i].x = Mathf.Clamp01(m_currentData.ShapePoints[i].x);
                    m_currentData.ShapePoints[i].y = Mathf.Clamp01(m_currentData.ShapePoints[i].y);
                }

                // make it convex hull gain to clean edges
                m_currentData.ShapePoints = Vector2Ex.ConvexHull(m_currentData.ShapePoints);

                // invert Y
                for (int i = 0; i < m_currentData.ShapePoints.Length; i++)
                {
                    m_currentData.ShapePoints[i] = new Vector2(m_currentData.ShapePoints[i].x, 1 - m_currentData.ShapePoints[i].y);
                }

                triangulateMesh = true;

                EditorUtility.SetDirty(m_instance);
            }

            if (EditorGUI.EndChangeCheck())
            {
                if (m_instance.Data == null)
                {
                    EditorPrefs.SetString(ImpostorBakingTools.PrefDataImpType, m_currentData.ImpostorType.ToString());
                    EditorPrefs.SetInt(ImpostorBakingTools.PrefDataTexSizeSelected, m_currentData.SelectedSize);
                    EditorPrefs.SetBool(ImpostorBakingTools.PrefDataTexSizeLocked, m_currentData.LockedSizes);
                    EditorPrefs.SetFloat(ImpostorBakingTools.PrefDataTexSizeX, m_currentData.TexSize.x);
                    EditorPrefs.SetFloat(ImpostorBakingTools.PrefDataTexSizeY, m_currentData.TexSize.y);
                    EditorPrefs.SetBool(ImpostorBakingTools.PrefDataDecoupledFrames, m_currentData.DecoupleAxisFrames);
                    EditorPrefs.SetInt(ImpostorBakingTools.PrefDataXFrames, m_currentData.HorizontalFrames);
                    EditorPrefs.SetInt(ImpostorBakingTools.PrefDataYFrames, m_currentData.VerticalFrames);
                    EditorPrefs.SetInt(ImpostorBakingTools.PrefDataPixelBleeding, m_currentData.PixelPadding);

                    EditorPrefs.SetFloat(ImpostorBakingTools.PrefDataTolerance, m_currentData.Tolerance);
                    EditorPrefs.SetFloat(ImpostorBakingTools.PrefDataNormalScale, m_currentData.NormalScale);
                    EditorPrefs.SetInt(ImpostorBakingTools.PrefDataMaxVertices, m_currentData.MaxVertices);
                }

                EditorUtility.SetDirty(m_instance);
            }

            if (triangulateMesh)
            {
                m_previewMesh = GeneratePreviewMesh(m_currentData.ShapePoints, true);
            }

            if (autoChangeToManual /*&& Event.current.type == EventType.Layout*/)
            {
                autoChangeToManual   = false;
                m_instance.m_cutMode = CutMode.Manual;
                Event.current.Use();
            }

            // Bake textures after alpha generation
            if (bakeTextures)
            {
                bakeTextures = false;
                m_instance.RenderAllDeferredGroups(m_currentData);

                bool createLodGroup = false;
                if (ImpostorBakingTools.GlobalCreateLodGroup)
                {
                    LODGroup group = m_instance.RootTransform.GetComponentInParent <LODGroup>();
                    if (group == null)
                    {
                        group = m_instance.RootTransform.GetComponentInChildren <LODGroup>();
                    }
                    if (group == null && m_instance.LodGroup == null)
                    {
                        createLodGroup = true;
                    }
                }

                if (createLodGroup && m_instance.m_lastImpostor != null)
                {
                    GameObject lodgo    = new GameObject(m_instance.name + "_LODGroup");
                    LODGroup   lodGroup = lodgo.AddComponent <LODGroup>();
                    lodGroup.transform.position = m_instance.transform.position;
                    int hierIndex = m_instance.transform.GetSiblingIndex();

                    m_instance.transform.SetParent(lodGroup.transform, true);
                    m_instance.m_lastImpostor.transform.SetParent(lodGroup.transform, true);
                    LOD[] lods = lodGroup.GetLODs();
                    ArrayUtility.RemoveAt <LOD>(ref lods, 2);
                    lods[0].fadeTransitionWidth            = 0.5f;
                    lods[0].screenRelativeTransitionHeight = 0.15f;
                    lods[0].renderers                      = m_instance.RootTransform.GetComponentsInChildren <Renderer>();
                    lods[1].fadeTransitionWidth            = 0.5f;
                    lods[1].screenRelativeTransitionHeight = 0.01f;
                    lods[1].renderers                      = m_instance.m_lastImpostor.GetComponentsInChildren <Renderer>();
                    lodGroup.fadeMode                      = LODFadeMode.CrossFade;
                    lodGroup.animateCrossFading            = true;
                    lodGroup.SetLODs(lods);
                    lodgo.transform.SetSiblingIndex(hierIndex);
                }
            }

            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 20
0
        public void CreateWMOObject()
        {
            if (terrainHandler.working)
            {
                WMO.WMOStruct data        = WMO.AllWMOData.Dequeue();
                GameObject    WMOinstance = new GameObject();

                terrainHandler.LoadedWMOIds[data.fileDataId] = WMOinstance;

                int nGroups = data.Info.nGroups;
                for (int g = 0; g < nGroups; g++)
                {
                    // group object //
                    GameObject GroupInstance = new GameObject();
                    GroupInstance.isStatic = true;
                    GroupInstance.transform.SetParent(terrainHandler.LoadedWMOIds[data.fileDataId].transform);
                    GroupInstance.name = data.groupsData[g].groupName;

                    LODGroup   Lodgroup  = GroupInstance.AddComponent <LODGroup>();
                    LOD[]      lods      = new LOD[1];
                    Renderer[] renderers = new Renderer[data.groupsData[g].nBatches];

                    // Batches //
                    for (int bn = 0; bn < data.groupsData[g].nBatches; bn++)
                    {
                        ////////////////////////////////
                        #region object

                        GameObject BatchInstance = new GameObject();
                        BatchInstance.isStatic = true;
                        BatchInstance.transform.SetParent(GroupInstance.transform);
                        BatchInstance.name = bn.ToString();
                        BatchInstance.transform.transform.eulerAngles = new Vector3(BatchInstance.transform.transform.eulerAngles.x, BatchInstance.transform.transform.eulerAngles.y - 180, GroupInstance.transform.transform.eulerAngles.z);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region mesh

                        BatchInstance.AddComponent <MeshRenderer>();
                        BatchInstance.GetComponent <MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
                        renderers[bn] = BatchInstance.GetComponent <MeshRenderer>();
                        BatchInstance.AddComponent <MeshFilter>();
                        Mesh bmesh = new Mesh();

                        uint batchVertSize = data.groupsData[g].batch_MaxIndex[bn] - data.groupsData[g].batch_MinIndex[bn] + 1;

                        Vector3[]  batchVertices      = new Vector3[batchVertSize];
                        Vector2[]  batchUVs           = new Vector2[batchVertSize];
                        Vector3[]  batchNormals       = new Vector3[batchVertSize];
                        Color32[]  batchVertexColors  = new Color32[batchVertSize];
                        List <int> batchTrianglesList = new List <int>();
                        int[]      batchTriangles;

                        int  arrayPosition     = 0;
                        uint batch_startVertex = data.groupsData[g].batch_MinIndex[bn];
                        uint batch_endVertex   = data.groupsData[g].batch_MaxIndex[bn];
                        for (uint v = batch_startVertex; v <= batch_endVertex; v++)
                        {
                            batchVertices[arrayPosition] = data.groupsData[g].vertices[v];
                            batchUVs[arrayPosition]      = data.groupsData[g].UVs[v];
                            batchNormals[arrayPosition]  = data.groupsData[g].normals[v];
                            if (!data.groupsData[g].flags.Hasvertexolors)
                            {
                                batchVertexColors[arrayPosition] = new Color32(127, 127, 127, 127);
                            }
                            else
                            {
                                batchVertexColors[arrayPosition] = data.groupsData[g].vertexColors[(int)v];
                            }
                            arrayPosition++;
                        }

                        uint batch_startIndex = data.groupsData[g].batch_StartIndex[bn];
                        uint batch_nIndices   = data.groupsData[g].batch_Count[bn];
                        for (uint idx = batch_startIndex; idx <= batch_startIndex + batch_nIndices - 2; idx = idx + 3)
                        {
                            uint in1 = data.groupsData[g].triangles[idx + 0];
                            uint in2 = data.groupsData[g].triangles[idx + 1];
                            uint in3 = data.groupsData[g].triangles[idx + 2];
                            int  a   = (int)(in1 - batch_startVertex);
                            int  b   = (int)(in2 - batch_startVertex);
                            int  c   = (int)(in3 - batch_startVertex);

                            batchTrianglesList.Add(a);
                            batchTrianglesList.Add(b);
                            batchTrianglesList.Add(c);
                        }
                        batchTrianglesList.Reverse();
                        batchTriangles = batchTrianglesList.ToArray();

                        bmesh.vertices  = batchVertices;
                        bmesh.uv        = batchUVs;
                        bmesh.normals   = batchNormals;
                        bmesh.triangles = batchTriangles;
                        bmesh.colors32  = batchVertexColors;
                        BatchInstance.GetComponent <MeshFilter>().mesh             = bmesh;
                        BatchInstance.GetComponent <MeshRenderer>().sharedMaterial = missingMaterial;

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region material

                        uint TextureFileDataId = data.texturePaths[data.materials[data.groupsData[g].batchMaterialIDs[bn]].TextureId1];
                        BatchInstance.GetComponent <Renderer>().material = WMOmaterials[(int)data.materials[data.groupsData[g].batchMaterialIDs[bn]].ShaderType];

                        ////////////////////////////////
                        #region Set Fragment Shader

                        WMOFragmentShader shader = data.materials[data.groupsData[g].batchMaterialIDs[bn]].ShaderType;
                        switch (shader)
                        {
                        case WMOFragmentShader.Diffuse:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderDiffuse", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Specular:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderSpecular", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Metal:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderMetal", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Env:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderEnv", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Opaque:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderOpaque", 1.0f);
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_AlphaToMask", 1.0f);
                            break;
                        }

                        default:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderDiffuse", 1.0f);
                            break;
                        }
                        }


                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Set Material Flags

                        // F_UNCULLED //
                        int Culling = 2; // on (only front)
                        if (data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNCULLED)
                        {
                            Culling = 0; // off (both sides_
                        }
                        BatchInstance.GetComponent <Renderer>().material.SetFloat("F_UNCULLED", Culling);
                        // F_UNLIT //
                        if (data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNLIT)
                        {
                            BatchInstance.GetComponent <Renderer>().material.EnableKeyword("F_UNLIT");
                        }
                        //BatchInstance.GetComponent<Renderer>().material.SetFloat("_F_UNLIT", data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNLIT ? 1 : 0);
                        // F_UNFOGGED //
                        BatchInstance.GetComponent <Renderer>().material.SetFloat("_F_UNFOGGED", data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNFOGGED ? 1 : 0);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Set Blending Mode

                        // set default blend: One Zero, basicly off
                        UnityEngine.Rendering.BlendMode source      = UnityEngine.Rendering.BlendMode.One;
                        UnityEngine.Rendering.BlendMode destination = UnityEngine.Rendering.BlendMode.Zero;

                        BlendingMode blending = data.materials[data.groupsData[g].batchMaterialIDs[bn]].BlendMode;

                        switch (blending)
                        {
                        case BlendingMode.Opaque:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.AlphaKey:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.Alpha:
                        {
                            source      = UnityEngine.Rendering.BlendMode.SrcAlpha;
                            destination = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                            break;
                        }

                        case BlendingMode.Additive:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.One;
                            break;
                        }

                        case BlendingMode.Modulate:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.Modulate2x:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.SrcColor;
                            break;
                        }

                        case BlendingMode.ModulateAdditive:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.One;
                            break;
                        }

                        default:
                        {
                            Debug.Log("BlendMode To Add: " + blending.ToString() + " Texture Used: " + TextureFileDataId);
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }
                        }
                        BatchInstance.GetComponent <Renderer>().material.SetInt("MySrcMode", (int)source);
                        BatchInstance.GetComponent <Renderer>().material.SetInt("MyDstMode", (int)destination);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Assign Textures

                        if (LoadedWMOTextures.ContainsKey(TextureFileDataId))
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetTexture("_MainTex", LoadedWMOTextures[TextureFileDataId]);
                        }
                        else
                        {
                            try
                            {
                                Texture2Ddata tdata = data.textureData[TextureFileDataId];
                                Texture2D     tex   = new Texture2D(tdata.width, tdata.height, tdata.textureFormat, tdata.hasMipmaps);
                                tex.LoadRawTextureData(tdata.TextureData);
                                tex.Apply();
                                LoadedWMOTextures[TextureFileDataId] = tex;
                                BatchInstance.GetComponent <Renderer>().material.SetTexture("_MainTex", tex);
                            }
                            catch (Exception ex)
                            {
                                Debug.Log("Error: Loading RawTextureData @ WMOhandler");
                                Debug.LogException(ex);
                            }
                        }
                        #endregion
                        ////////////////////////////////

                        #endregion
                        ////////////////////////////////
                    }

                    lods[0] = new LOD(.1f, renderers);
                    Lodgroup.SetLODs(lods);
                    Lodgroup.animateCrossFading = true;
                    Lodgroup.fadeMode           = LODFadeMode.SpeedTree;
                    Lodgroup.RecalculateBounds();
                }

                terrainHandler.LoadedWMOIds[data.fileDataId].transform.position   = data.position;
                terrainHandler.LoadedWMOIds[data.fileDataId].transform.rotation   = data.rotation;
                terrainHandler.LoadedWMOIds[data.fileDataId].transform.localScale = data.scale;
                if (data.uniqueID != -1)
                {
                    if (terrainHandler.ADTBlockWMOParents[data.uniqueID] != null)
                    {
                        terrainHandler.LoadedWMOIds[data.fileDataId].transform.SetParent(terrainHandler.ADTBlockWMOParents[data.uniqueID].transform);
                    }
                    else
                    {
                        Destroy(terrainHandler.LoadedWMOIds[data.fileDataId]);
                    }
                }
                terrainHandler.LoadedWMOIds[data.fileDataId].name = data.Info.wmoID.ToString();

                terrainHandler.frameBusy = false;
            }
        }
Esempio n. 21
0
		public static void CreateFileForResult (List<Core_Voxel.Result> resultList, Shader[] shaders, string[] shaderKeywords, Vector2[] shaderRemaps, float scale, Vector3 pivot, ReplacementMode replacementMode) {

			var diffuseShader = shaders[0];

			for (int index = 0; index < resultList.Count; index++) {

				var result = resultList[index];
				bool lod = result.VoxelModels.Length > 1;
				bool isRig = !lod && result.IsRigged;
				int realLodNum = result.IsRigged ? 1 : result.VoxelModels.Length;

				var root = new GameObject(result.FileName).transform;
				var meshs = new List<Mesh>();
				var materialsMap = new Dictionary<Texture2D, Material[]>();
				Transform[] lodRoots = new Transform[realLodNum];
				for (int lodIndex = 0; lodIndex < realLodNum; lodIndex++) {

					var voxelModel = result.VoxelModels[lodIndex];
					var model = CreateModelFrom(voxelModel.RootNode, voxelModel.Materials, root, pivot, ref meshs, ref materialsMap, isRig, result.WithAvatar, shaders, shaderKeywords, shaderRemaps, scale);
					model.name = string.Format("Root{0}", lod ? "_lod " + lodIndex.ToString() : "");
					lodRoots[lodIndex] = model;

					// Rig			 
					if (isRig) {

						Vector3 halfModelSize = voxelModel.ModelSize[0] * 0.5f;
						halfModelSize.x = Mathf.Floor(halfModelSize.x);
						halfModelSize.y = Mathf.Floor(halfModelSize.y);
						halfModelSize.z = Mathf.Floor(halfModelSize.z);

						var skinMR = model.GetComponent<SkinnedMeshRenderer>();
						if (skinMR) {
							Vector3 rootBoneOffset = halfModelSize * scale;
							var boneTFList = new List<Transform>();
							if (voxelModel.RootBones != null) {
								for (int i = 0; i < voxelModel.RootBones.Length; i++) {
									var boneTF = CreateBoneTransform(voxelModel.RootBones[i], model, scale, ref boneTFList);
									if (boneTF) {
										boneTF.localPosition -= rootBoneOffset;
									}
								}
							}

							skinMR.bones = boneTFList.ToArray();
							skinMR.rootBone = model;

							// Bind Poses
							var poses = new Matrix4x4[boneTFList.Count];
							for (int i = 0; i < boneTFList.Count; i++) {
								poses[i] = boneTFList[i].worldToLocalMatrix * model.localToWorldMatrix;
							}
							skinMR.sharedMesh.bindposes = poses;

						}

						// Foot Fix
						model.localPosition = (halfModelSize - voxelModel.FootPoints[lodIndex]) * scale;

					}

				}



				// Lod
				if (lod) {
					LODGroup group = root.gameObject.AddComponent<LODGroup>();
					LOD[] lods = new LOD[realLodNum];
					for (int i = 0; i < realLodNum; i++) {
						lods[i] = new LOD(
							i == realLodNum - 1 ? 0.001f : GetLodRant(result.VoxelModels[i].MaxModelBounds, i),
							lodRoots[i].GetComponentsInChildren<MeshRenderer>(true)
						);
					}
					group.SetLODs(lods);
					group.RecalculateBounds();
				} else if (!isRig && root.childCount > 0) {
					var newRoot = root.GetChild(0);
					newRoot.name = root.name;
					root = newRoot;
				}



				// File
				string path = Util.CombinePaths(
					result.ExportRoot,
					result.ExportSubRoot,
					result.FileName + result.Extension
				);
				path = Util.FixPath(path);
				string parentPath = Util.GetParentPath(path);
				Util.CreateFolder(parentPath);
				List<Object> oldSubObjs = new List<Object>();

				if (result.Extension == ".prefab") {

					Object prefab;

					if (Util.FileExists(path)) {

						// Get Prefab
						prefab = AssetDatabase.LoadAssetAtPath<Object>(path);
						if (prefab as GameObject) {
							var group = (prefab as GameObject).GetComponent<LODGroup>();
							if (group) {
								Object.DestroyImmediate(group, true);
							}
						}

						// Old Sub Objs
						oldSubObjs.AddRange(AssetDatabase.LoadAllAssetRepresentationsAtPath(path));

						if (replacementMode == ReplacementMode.DeleteOldObjects) {
							foreach (Object o in oldSubObjs) {
								Object.DestroyImmediate(o, true);
							}
							oldSubObjs.Clear();
						}

					} else {
#if UNITY_4 || UNITY_5 || UNITY_2017 || UNITY_2018_1 || UNITY_2018_2
						prefab = PrefabUtility.CreateEmptyPrefab(path);
#else   // 2018.3+
						var tempObject = new GameObject();
						prefab = PrefabUtility.SaveAsPrefabAsset(tempObject, path);
						Object.DestroyImmediate(tempObject, false);
#endif
					}

					if (prefab) {

						// Get Old Sub Objects
						var oldSubMeshs = new List<Mesh>();
						var oldSubMaterials = new List<Material>();
						var oldSubTextures = new List<Texture2D>();
						var new2old = new Dictionary<Object, Object>();

						for (int i = 0; i < oldSubObjs.Count; i++) {
							var obj = oldSubObjs[i];
							if (obj is Mesh) {
								oldSubMeshs.Add(obj as Mesh);
							} else if (obj is Material) {
								oldSubMaterials.Add(obj as Material);
							} else if (obj is Texture2D) {
								oldSubTextures.Add(obj as Texture2D);
							}
						}


						if (replacementMode == ReplacementMode.ReplaceByName) {
							// Replace by Name
							// Delete Non-Replaced Old Sub / Create New2Old Map
							for (int i = 0; i < oldSubObjs.Count; i++) {

								var oldObj = oldSubObjs[i];
								bool deleteFlag = true;
								string name = oldObj.name;

								if (oldObj is Mesh) {
									// Mesh
									for (int j = 0; j < meshs.Count; j++) {
										if (new2old.ContainsKey(meshs[j])) { continue; }
										if (name == meshs[j].name) {
											new2old.Add(meshs[j], oldObj);
											deleteFlag = false;
											break;
										}
									}
								} else if (oldObj is Material) {
									// Material
									foreach (var textureMat in materialsMap) {
										var mats = textureMat.Value;
										for (int j = 0; j < mats.Length; j++) {
											if (new2old.ContainsKey(mats[j])) { continue; }
											if (mats[j].name == name) {
												new2old.Add(mats[j], oldObj);
												deleteFlag = false;
												break;
											}
										}
									}
								} else if (oldObj is Texture2D) {
									// Texture
									foreach (var textureMat in materialsMap) {
										if (new2old.ContainsKey(textureMat.Key)) { continue; }
										if (name == textureMat.Key.name) {
											new2old.Add(textureMat.Key, oldObj);
											deleteFlag = false;
											break;
										}
									}
								}

								if (deleteFlag) {
									Object.DestroyImmediate(oldObj, true);
									oldSubObjs.RemoveAt(i);
									i--;
								}
							}

							// Create Meshs
							for (int i = 0; i < meshs.Count; i++) {
								var mesh = meshs[i];
								if (new2old.ContainsKey(mesh)) {
									Util.OverrideMesh(new2old[mesh] as Mesh, mesh);
								} else {
									AssetDatabase.AddObjectToAsset(meshs[i], path);
								}
							}

							// Create Textures
							foreach (var textureMat in materialsMap) {
								if (new2old.ContainsKey(textureMat.Key)) {
									Util.OverrideTexture(new2old[textureMat.Key] as Texture2D, textureMat.Key);
								} else {
									AssetDatabase.AddObjectToAsset(textureMat.Key, path);
								}
							}

							// Create Materials
							foreach (var textureMat in materialsMap) {
								var mats = textureMat.Value;
								for (int i = 0; i < mats.Length; i++) {
									var mat = mats[i];
									if (new2old.ContainsKey(mat)) {
										Util.OverrideMaterial(new2old[mat] as Material, mat);
									} else {
										AssetDatabase.AddObjectToAsset(mat, path);
									}
								}
							}

						} else {

							// Just Create New
							// Create Meshs
							for (int i = 0; i < meshs.Count; i++) {
								AssetDatabase.AddObjectToAsset(meshs[i], path);
							}

							// Create Textures
							foreach (var textureMat in materialsMap) {
								AssetDatabase.AddObjectToAsset(textureMat.Key, path);
							}

							// Create Materials
							foreach (var textureMat in materialsMap) {
								var mats = textureMat.Value;
								for (int i = 0; i < mats.Length; i++) {
									AssetDatabase.AddObjectToAsset(mats[i], path);
								}
							}

						}

						// Create Avatar
						if (isRig && result.WithAvatar) {
							var avatar = GetVoxelAvatarInRoot(root);
							if (avatar) {
								avatar.name = result.FileName;
								AssetDatabase.AddObjectToAsset(avatar, path);

								// Animator
								var ani = root.GetComponent<Animator>();
								if (!ani) {
									ani = root.gameObject.AddComponent<Animator>();
								}
								ani.avatar = avatar;

							} else {
								Debug.LogWarning("[Voxel to Unity] Failed to get avatar from the prefab. Use \"+ Human Bones\" button in rig editor to create bones and don\'t change their names and layout.");
							}
						}

						// Replace to Old Instance
						var mrs = root.GetComponentsInChildren<MeshRenderer>(true);
						var srs = root.GetComponentsInChildren<SkinnedMeshRenderer>(true);
						var mfs = root.GetComponentsInChildren<MeshFilter>(true);
						for (int i = 0; i < mrs.Length; i++) {
							var mr = mrs[i];
							if (mr.sharedMaterial && new2old.ContainsKey(mr.sharedMaterial)) {
								var mat = new2old[mr.sharedMaterial] as Material;
								mr.sharedMaterial = mat;
								if (mat.mainTexture && new2old.ContainsKey(mat.mainTexture)) {
									var texture = new2old[mat.mainTexture] as Texture2D;
									mat.mainTexture = texture;
								}
							}
						}
						for (int i = 0; i < mfs.Length; i++) {
							var mf = mfs[i];
							if (mf.sharedMesh && new2old.ContainsKey(mf.sharedMesh)) {
								mf.sharedMesh = new2old[mf.sharedMesh] as Mesh;
							}
						}
						for (int i = 0; i < srs.Length; i++) {
							var sr = srs[i];
							if (sr.sharedMesh && new2old.ContainsKey(sr.sharedMesh)) {
								sr.sharedMesh = new2old[sr.sharedMesh] as Mesh;
							}
							if (sr.sharedMaterial && new2old.ContainsKey(sr.sharedMaterial)) {
								var mat = new2old[sr.sharedMaterial] as Material;
								sr.sharedMaterial = mat;
								if (mat.mainTexture && new2old.ContainsKey(mat.mainTexture)) {
									var texture = new2old[mat.mainTexture] as Texture2D;
									mat.mainTexture = texture;
								}
							}
						}


						// Prefab
#if UNITY_4 || UNITY_5 || UNITY_2017 || UNITY_2018_1 || UNITY_2018_2
						PrefabUtility.ReplacePrefab(root.gameObject, prefab, ReplacePrefabOptions.ReplaceNameBased);
#else  // 2018.3+
						prefab = PrefabUtility.SaveAsPrefabAsset(root.gameObject, path);
#endif

					}

				} else { // Obj

					string objFolderPath = Util.CombinePaths(parentPath, result.FileName);
					string textureFolderPath = Util.CombinePaths(objFolderPath, "Textures");
					Util.CreateFolder(objFolderPath);

					VoxelPostprocessor.TheShader = diffuseShader;

					// Assets
					var model = result.VoxelModels[0];
					for (int modelIndex = 0; modelIndex < model.Meshs.Length; modelIndex++) {

						string modelIndexedName = GetIndexedName(result.FileName, modelIndex, model.Meshs.Length);
						string modelPathRoot = Util.CombinePaths(objFolderPath, modelIndexedName);

						// Texture
						string texturePath = Util.CombinePaths(textureFolderPath, modelIndexedName + ".png");
						texturePath = Util.FixPath(texturePath);
						var texture = model.Textures[modelIndex];
						Util.ByteToFile(texture.EncodeToPNG(), texturePath);
						VoxelPostprocessor.AddTexture(texturePath);

						// Meshs
						var uMesh = model.Meshs[modelIndex];
						for (int i = 0; i < uMesh.Count; i++) {
							uMesh[i].name = GetIndexedName("Mesh", i, uMesh.Count);
							string obj = Util.GetObj(uMesh[i]);
							string objPath = GetIndexedName(modelPathRoot, i, uMesh.Count) + ".obj";

							bool hasObjBefore = Util.FileExists(objPath);

							Util.Write(obj, objPath);
							VoxelPostprocessor.AddObj(objPath, texturePath);

							if (hasObjBefore) {
								AssetDatabase.ImportAsset(Util.FixedRelativePath(objPath), ImportAssetOptions.ForceUpdate);
							}

						}

					}

				}


				// Delete Objects
				if (root.parent) {
					Object.DestroyImmediate(root.parent.gameObject, false);
				} else {
					Object.DestroyImmediate(root.gameObject, false);
				}

			}
			AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
			AssetDatabase.SaveAssets();
			Resources.UnloadUnusedAssets();

			EditorApplication.delayCall += VoxelPostprocessor.ClearAsset;

		}
Esempio n. 22
0
    void Mesh()
    {
        counting = 0;
        canMerge = false;
        int numOfseObjList = 0;

        totalcount = dataDic.Count;
        foreach (string key in dataDic.Keys)
        {
            counting++;
            UpdateProgress();
            if (showList.Count > 0 && showList[numOfseObjList] == false)
            {
                numOfseObjList++;
                continue;
            }
            numOfseObjList++;
            if (polyMergeCountDic[key] > 65000)
            {
                continue;
            }
            NewFolder(meshContainsName, key);
            LOD[] lods     = new LOD[dataDic[key].Count];
            int   lodCount = 0;
            int   merCoung = 0;
            foreach (MergeData m in dataDic[key])
            {
                //Mesh
                for (int i = 0; i < m._matLists.Count; i++)
                {
                    subMeshList = m._subMeshLists[i];
                    string     header       = meshContainsName;
                    GameObject mergedObject = new GameObject(header + "_" + m._objectLists[i][0].name + "_" + m._matLists[i][0].name, typeof(MeshFilter), typeof(MeshRenderer));
                    Mesh       combinedMesh = CombineSubmeshes(subMeshList, mergedObject);

                    if (m._tranMeshColLists.Count != 0)
                    {
                        int mesColCou = 0;
                        for (int t = 0; t < m._tranMeshColLists.Count; t++)
                        {
                            GameObject addMesh = new GameObject(m._meshColLists[t].name + "_" + mesColCou);
                            mesColCou++;
                            MeshCollider mc = addMesh.AddComponent <MeshCollider> ();
                            mc.sharedMesh = m._meshColLists[t];
                            addMesh.transform.position   = m._tranMeshColLists[t].transform.position;
                            addMesh.transform.rotation   = m._tranMeshColLists[t].transform.rotation;
                            addMesh.transform.localScale = m._tranMeshColLists[t].localScale;
                            addMesh.transform.SetParent(mergedObject.transform);
                        }
                    }

                    AssetDatabase.CreateAsset(combinedMesh, filePath + "/" + header + "_" + m._objectLists[i][0].name + "_" + m._matLists[i][0].name + ".asset");
                    mergedObject.GetComponent <MeshFilter>().mesh = combinedMesh;
                    mergedObject.GetComponent <MeshRenderer>().sharedMaterials = m._matLists[i].ToArray();
                    lodList.Add(mergedObject);

                    Renderer[] renderers = new Renderer[1];
                    renderers[0]   = mergedObject.GetComponent <Renderer>();
                    lods[lodCount] = new LOD(1.0f / (lodCount + 2f), renderers);
                    lodCount++;
                }
            }
            string     m_header     = meshContainsName;
            GameObject newMergedObj = new GameObject(m_header + "_" + key);
            foreach (GameObject n in lodList)
            {
                n.transform.SetParent(newMergedObj.transform);
            }

            if (lodGroup)
            {
                LODGroup lodObj = newMergedObj.AddComponent <LODGroup> ();
                lodObj.SetLODs(lods);
                lodObj.RecalculateBounds();
                for (int n = lodObj.GetLODs().Count() - 1; n >= 0; n--)
                {
                    if (lodObj.GetLODs()[n].renderers.Length == 0)
                    {
                        List <LOD> _lodObj = lodObj.GetLODs().ToList();
                        _lodObj.RemoveAt(n);
                        lodObj.SetLODs(_lodObj.ToArray());
                    }
                }
                if (lodRTH.ContainsKey(key))
                {
                    lods = lodObj.GetLODs();
                    for (int u = 0; u < lodRTH[key].Count; u++)
                    {
                        lods [u].screenRelativeTransitionHeight = lodRTH [key] [u];
                    }
                    lodObj.SetLODs(lods);
                }
            }

            PrefabUtility.CreatePrefab(filePath + "/" + m_header + "_" + key + ".prefab", (GameObject)newMergedObj, ReplacePrefabOptions.ConnectToPrefab);
            lodList.Clear();
        }
    }
    public void printLoDSlider(SerializedObject serializedObject, string prefix, int winId, bool showLODMode = true, GameObject gameObject = null)
    {
        bool isInspector = serializedObject.FindProperty("isInspector") != null?serializedObject.FindProperty("isInspector").boolValue : false;

        SerializedProperty serializedProperty = serializedObject.FindProperty(prefix);

        tt = "Use the button “Add LOD level” to add multiple LODs (or Level of Detail, see documentation for more information).\n\nFor each LOD(up to 5, including LOD 0), choose a Quality preset.\n\nUse the horizontal bar to set screen size percentage for each LOD.\n\nRight-click in the horizontal bar to add / remove a new LOD.";
        PiXYZUtils.beginGroupBox("LODs Mesh Quality", tooltip: tt);
        {
            int currentLodIndex = -1;
            tt = "To insert or remove a LoD, right-click on the row";

            EditorGUILayout.BeginVertical();
            {
                EditorGUILayout.Space();
                bool changed = false || reset;
                if (changed)
                {
                    reset = false;
                }
                if (showLODMode)
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        GUILayout.Space(20);
                        float width = GUI.skin.label.CalcSize(new GUIContent("Quality")).x;
                        GUILayout.Label("Mode", GUILayout.Width(width));
                        List <string> propertyNames = new List <string>(3);
                        propertyNames.Add("LOD Group put on root object");
                        propertyNames.Add("LOD Groups put on the parent of each mesh");
                        List <int> intValue = new List <int>(3);
                        intValue.Add(1);
                        intValue.Add(2);
                        width = (float)Math.Truncate(Screen.width * 0.6);
                        Rect rect = EditorGUILayout.GetControlRect();
                        rect.width = width;
                        GUILayout.FlexibleSpace();
                        int originalValue = serializedProperty.FindPropertyRelative("lodsMode").intValue;
                        serializedProperty.FindPropertyRelative("lodsMode").intValue = EditorGUI.IntPopup(rect, originalValue, propertyNames.ToArray(), intValue.ToArray());
                        if (isInspector && gameObject != null && originalValue != serializedProperty.FindPropertyRelative("lodsMode").intValue)
                        {
                            if (originalValue == 1)
                            {
                                LODGroup lodGroup = gameObject.GetComponent <LODGroup>();
                                Dictionary <LODGroup, Dictionary <float, List <Renderer> > > finalLods = new Dictionary <LODGroup, Dictionary <float, List <Renderer> > >();
                                foreach (LOD lod in lodGroup.GetLODs())
                                {
                                    foreach (Renderer renderer in lod.renderers)
                                    {
                                        LODGroup parentLODGroup = renderer.transform.parent.GetComponent <LODGroup>();
                                        if (parentLODGroup == null)
                                        {
                                            parentLODGroup = renderer.transform.parent.gameObject.AddComponent <LODGroup>();
                                        }
                                        if (!finalLods.ContainsKey(parentLODGroup))
                                        {
                                            finalLods.Add(parentLODGroup, new Dictionary <float, List <Renderer> >());
                                        }
                                        if (!finalLods[parentLODGroup].ContainsKey(lod.screenRelativeTransitionHeight))
                                        {
                                            finalLods[parentLODGroup].Add(lod.screenRelativeTransitionHeight, new List <Renderer>());
                                        }
                                        finalLods[parentLODGroup][lod.screenRelativeTransitionHeight].Add(renderer);
                                    }
                                }
                                UnityEngine.Object.DestroyImmediate(lodGroup);
                                foreach (var groupPair in finalLods)
                                {
                                    List <LOD> lods = new List <LOD>();
                                    foreach (var pair in groupPair.Value)
                                    {
                                        lods.Add(new LOD(pair.Key, pair.Value.ToArray()));
                                    }
                                    lods.Sort(delegate(LOD x, LOD y)
                                    {
                                        if (x.screenRelativeTransitionHeight < y.screenRelativeTransitionHeight)
                                        {
                                            return(1);
                                        }
                                        else if (x.screenRelativeTransitionHeight == y.screenRelativeTransitionHeight)
                                        {
                                            return(0);
                                        }
                                        else
                                        {
                                            return(-1);
                                        }
                                    });
                                    groupPair.Key.SetLODs(lods.ToArray());
                                }
                            }
                            else
                            {
                                Dictionary <float, List <Renderer> > newLods = new Dictionary <float, List <Renderer> >();
                                foreach (LODGroup lodGroup in gameObject.GetComponentsInChildren <LODGroup>())
                                {
                                    foreach (LOD lod in lodGroup.GetLODs())
                                    {
                                        if (!newLods.ContainsKey(lod.screenRelativeTransitionHeight))
                                        {
                                            newLods.Add(lod.screenRelativeTransitionHeight, new List <Renderer>());
                                        }
                                        newLods[lod.screenRelativeTransitionHeight].AddRange(lod.renderers);
                                    }
                                    UnityEngine.Object.DestroyImmediate(lodGroup);
                                }
                                LODGroup   parentLODGroup = gameObject.AddComponent <LODGroup>();
                                List <LOD> lods           = new List <LOD>();
                                foreach (KeyValuePair <float, List <Renderer> > pair in newLods)
                                {
                                    lods.Add(new LOD(pair.Key, pair.Value.ToArray()));
                                }
                                lods.Sort(delegate(LOD x, LOD y)
                                {
                                    if (x.screenRelativeTransitionHeight < y.screenRelativeTransitionHeight)
                                    {
                                        return(1);
                                    }
                                    else if (x.screenRelativeTransitionHeight == y.screenRelativeTransitionHeight)
                                    {
                                        return(0);
                                    }
                                    else
                                    {
                                        return(-1);
                                    }
                                });
                                parentLODGroup.SetLODs(lods.ToArray());
                            }
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                    GUILayout.Space(10);
                }
                EditorGUILayout.BeginHorizontal();
                {
                    GUILayout.Space(20);
                    slider.show(serializedObject, gameObject);
                    GUILayout.Space(20);
                }
                EditorGUILayout.EndHorizontal();
                GUILayout.Space(10);
                if (!isInspector)
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        GUILayout.FlexibleSpace();
                        if (!serializedProperty.FindPropertyRelative("useLods").boolValue)
                        {
                            if (GUILayout.Button(new GUIContent("Activate LODs")))
                            {
                                serializedProperty.FindPropertyRelative("useLods").boolValue = true;
                            }
                        }
                        GUILayout.FlexibleSpace();
                    }
                    EditorGUILayout.EndHorizontal();
                }
                GUILayout.Space(10);
            }
            EditorGUILayout.EndVertical();

            currentLodIndex = serializedProperty.FindPropertyRelative("lodCurrentIndex").intValue;

            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
                if (EditorWindow.focusedWindow != null)
                {
                    EditorWindow.focusedWindow.Repaint();
                }
            }

            if (!isInspector)
            {
                GUILayout.BeginHorizontal();
                {
                    GUILayout.BeginVertical();
                    {
                        if (serializedProperty.FindPropertyRelative("useLods").boolValue)
                        {
                            printLoDSettings(currentLodIndex, serializedObject, prefix + "." + PiXYZLODSettings.serializePrefix);
                        }
                        serializedObject.ApplyModifiedProperties();
                        GUILayout.Space(10);
                    }
                    GUILayout.EndVertical();
                }
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                GUILayout.BeginHorizontal();
                {
                    GUILayout.FlexibleSpace();
                    if (GUILayout.Button(new GUIContent("Propagate Materials from LOD0", "After applying a new material to one (or multiple) LOD0, use this button to propagate the material assignment to all the other LODs.")))
                    {
                        if (serializedProperty.FindPropertyRelative("lodsMode").intValue == 2)
                        {
                            foreach (var lodGroup in gameObject.GetComponentsInChildren <LODGroup>())
                            {
                                for (int i = 1; i < lodGroup.lodCount; ++i)
                                //foreach(LOD lod in lodGroup.GetLODs())
                                {
                                    if (lodGroup.GetLODs()[0].renderers.Length != lodGroup.GetLODs()[i].renderers.Length)
                                    {
                                        Debug.Log("The number of renderers on each LOD is not equal, can't synchronize !");
                                    }
                                    else
                                    {
                                        for (int j = 0; j < lodGroup.GetLODs()[0].renderers.Length; ++j)
                                        {
                                            Renderer renderer = lodGroup.GetLODs()[i].renderers[j].gameObject.GetComponent <Renderer>();
                                            renderer.sharedMaterial  = lodGroup.GetLODs()[0].renderers[j].sharedMaterial;
                                            renderer.sharedMaterials = lodGroup.GetLODs()[0].renderers[j].sharedMaterials;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            LODGroup lodGroup = gameObject.GetComponent <LODGroup>();
                            for (int i = 1; i < lodGroup.lodCount; ++i)
                            //foreach(LOD lod in lodGroup.GetLODs())
                            {
                                if (lodGroup.GetLODs()[0].renderers.Length != lodGroup.GetLODs()[i].renderers.Length)
                                {
                                    Debug.Log("The number of renderers on each LOD is not equal, can't synchronize !");
                                }
                                else
                                {
                                    for (int j = 0; j < lodGroup.GetLODs()[0].renderers.Length; ++j)
                                    {
                                        Renderer renderer = lodGroup.GetLODs()[i].renderers[j].gameObject.GetComponent <Renderer>();
                                        renderer.sharedMaterial  = lodGroup.GetLODs()[0].renderers[j].sharedMaterial;
                                        renderer.sharedMaterials = lodGroup.GetLODs()[0].renderers[j].sharedMaterials;
                                    }
                                }
                            }
                        }
                    }
                    GUILayout.FlexibleSpace();
                }
                GUILayout.EndHorizontal();
            }
        }
        PiXYZUtils.endGroupBox();
    }
Esempio n. 24
0
        public static void CreateFileForResult(List <VoxelCore.Result> resultList, Shader shader, float scale)
        {
            TheShader  = shader;
            ModelScale = scale;

            for (int index = 0; index < resultList.Count; index++)
            {
                var  result     = resultList[index];
                bool lod        = result.VoxelModels.Length > 1;
                bool isRig      = !lod && result.IsRigged;
                int  realLodNum = result.VoxelModels.Length;

                var         root         = new GameObject(result.FileName).transform;
                var         meshs        = new List <Mesh>();
                var         materialsMap = new Dictionary <Texture2D, Material>();
                Transform[] lodRoots     = new Transform[realLodNum];
                for (int lodIndex = 0; lodIndex < realLodNum; lodIndex++)
                {
                    var voxelModel = result.VoxelModels[lodIndex];
                    var model      = CreateModelFrom(voxelModel.RootNode, root, ref meshs, ref materialsMap, isRig, result.WithAvatar);
                    model.name         = string.Format("Root{0}", lod ? "_lod " + lodIndex.ToString() : "");
                    lodRoots[lodIndex] = model;


                    // Rig
                    if (isRig)
                    {
                        Vector3 halfModelSize = voxelModel.ModelSize[0] * 0.5f;
                        halfModelSize.x = Mathf.Floor(halfModelSize.x);
                        halfModelSize.y = Mathf.Floor(halfModelSize.y);
                        halfModelSize.z = Mathf.Floor(halfModelSize.z);

                        var skinMR = model.GetComponent <SkinnedMeshRenderer>();
                        if (skinMR)
                        {
                            Vector3 rootBoneOffset = halfModelSize * ModelScale;
                            var     boneTFList     = new List <Transform>();
                            if (voxelModel.RootBones != null)
                            {
                                for (int i = 0; i < voxelModel.RootBones.Length; i++)
                                {
                                    var boneTF = CreateBoneTransform(voxelModel.RootBones[i], model, ref boneTFList);
                                    if (boneTF)
                                    {
                                        boneTF.localPosition -= rootBoneOffset;
                                    }
                                }
                            }

                            skinMR.bones    = boneTFList.ToArray();
                            skinMR.rootBone = model;

                            // Bind Poses
                            var poses = new Matrix4x4[boneTFList.Count];
                            for (int i = 0; i < boneTFList.Count; i++)
                            {
                                poses[i] = boneTFList[i].worldToLocalMatrix * model.localToWorldMatrix;
                            }
                            skinMR.sharedMesh.bindposes = poses;
                        }

                        // Foot Fix
                        model.localPosition = (halfModelSize - voxelModel.FootPoints[lodIndex] + Vector3.up * 0.5f) * ModelScale;
                    }
                }

                // Lod
                if (lod)
                {
                    LODGroup group = root.gameObject.AddComponent <LODGroup>();
                    LOD[]    lods  = new LOD[realLodNum];
                    for (int i = 0; i < realLodNum; i++)
                    {
                        lods[i] = new LOD(
                            i == realLodNum - 1 ? 0.001f : GetLodRant(result.VoxelModels[i].MaxModelBounds, i),
                            lodRoots[i].GetComponentsInChildren <MeshRenderer>(true)
                            );
                    }
#if UNITY_5_0 || UNITY_5_1 || UNITY_4
                    group.SetLODS(lods);
                    group.RecalculateBounds();
#else
                    group.SetLODs(lods);
                    group.RecalculateBounds();
#endif
                }

                // File
                string path = Util.CombinePaths(
                    result.ExportRoot,
                    result.ExportSubRoot,
                    result.FileName + result.Extension
                    );
                path = Util.FixPath(path);
                string parentPath = Util.GetParentPath(path);
                Util.CreateFolder(parentPath);

                if (result.Extension == ".prefab")
                {
                    Object prefab;

                    if (Util.FileExists(path))
                    {
                        prefab = AssetDatabase.LoadAssetAtPath <Object>(path);
                        if (prefab as GameObject)
                        {
                            var group = (prefab as GameObject).GetComponent <LODGroup>();
                            if (group)
                            {
                                Object.DestroyImmediate(group, true);
                            }
                        }
                        Object[] things = AssetDatabase.LoadAllAssetRepresentationsAtPath(path);
                        foreach (Object o in things)
                        {
                            Object.DestroyImmediate(o, true);
                        }
                    }
                    else
                    {
                        prefab = PrefabUtility.CreateEmptyPrefab(path);
                    }

                    if (prefab)
                    {
                        // Assets
                        for (int i = 0; i < meshs.Count; i++)
                        {
                            meshs[i].name = GetIndexedName("Mesh", i, meshs.Count);
                            AssetDatabase.AddObjectToAsset(meshs[i], path);
                        }
                        int currentIndex = 0;
                        foreach (var textureMat in materialsMap)
                        {
                            textureMat.Key.name   = GetIndexedName("Texture", currentIndex, materialsMap.Count);
                            textureMat.Value.name = GetIndexedName("Material", currentIndex, materialsMap.Count);
                            currentIndex++;
                            AssetDatabase.AddObjectToAsset(textureMat.Key, path);
                            AssetDatabase.AddObjectToAsset(textureMat.Value, path);
                        }

                        // Avatar
                        if (isRig && result.WithAvatar)
                        {
                            var avatar = GetVoxelAvatarInRoot(root);
                            if (avatar)
                            {
                                avatar.name = result.FileName;
                                AssetDatabase.AddObjectToAsset(avatar, path);

                                // Animator
                                var ani = root.GetComponent <Animator>();
                                if (!ani)
                                {
                                    ani = root.gameObject.AddComponent <Animator>();
                                }
                                ani.avatar = avatar;
                            }
                        }

                        // Prefab
                        PrefabUtility.ReplacePrefab(root.gameObject, prefab, ReplacePrefabOptions.ReplaceNameBased);
                    }
                }
                else                     // Obj

                {
                    string objFolderPath     = Util.CombinePaths(parentPath, result.FileName);
                    string textureFolderPath = Util.CombinePaths(objFolderPath, "Textures");
                    Util.CreateFolder(objFolderPath);

                    VoxelPostprocessor.TheShader = TheShader;

                    // Assets
                    var model = result.VoxelModels[0];
                    for (int modelIndex = 0; modelIndex < model.Meshs.Length; modelIndex++)
                    {
                        string modelIndexedName = GetIndexedName(result.FileName, modelIndex, model.Meshs.Length);
                        string modelPathRoot    = Util.CombinePaths(objFolderPath, modelIndexedName);

                        // Texture
                        string texturePath = Util.CombinePaths(textureFolderPath, modelIndexedName + ".png");
                        texturePath = Util.FixPath(texturePath);
                        var texture = model.Textures[modelIndex];
                        Util.ByteToFile(texture.EncodeToPNG(), texturePath);
                        VoxelPostprocessor.AddTexture(texturePath);

                        // Meshs
                        var uMesh = model.Meshs[modelIndex];
                        for (int i = 0; i < uMesh.Count; i++)
                        {
                            uMesh[i].name = GetIndexedName("Mesh", i, uMesh.Count);
                            string obj     = Util.GetObj(uMesh[i]);
                            string objPath = GetIndexedName(modelPathRoot, i, uMesh.Count) + ".obj";

                            bool hasObjBefore = Util.FileExists(objPath);

                            Util.Write(obj, objPath);
                            VoxelPostprocessor.AddObj(objPath, texturePath);

                            if (hasObjBefore)
                            {
                                AssetDatabase.ImportAsset(Util.FixedRelativePath(objPath), ImportAssetOptions.ForceUpdate);
                            }
                        }
                    }
                }

                Object.DestroyImmediate(root.gameObject, false);
            }
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            AssetDatabase.SaveAssets();
            Resources.UnloadUnusedAssets();

            EditorApplication.delayCall += VoxelPostprocessor.ClearAsset;
        }
Esempio n. 25
0
    public override void OnInspectorGUI()
    {
        GUILayout.BeginHorizontal();
        GUILayout.Box(WorldIcon, GUILayout.Width(WorldIcon.width), GUILayout.Height(WorldIcon.height), GUILayout.ExpandWidth(true));
        //GUILayout.Label(WorldIcon, GUILayout.Width(WorldIcon.width), GUILayout.Height(WorldIcon.height),GUILayout.ExpandWidth(true));
        GUILayout.EndHorizontal();
        EditorGUILayout.Space();
        PWT.SetupTerrainAssociation();
        PWT.chunkSizes = PWT.GetChunkSizes();
        GUI.color      = new Color(1f, 1f, 1f);

        GUILayout.BeginVertical(GUI.skin.box);
        GUILayout.Label("Terrain Visibility:");
        GUILayout.BeginHorizontal();
        PWT.terrainGOEnabled = GUILayout.Toggle(PWT.terrainGOEnabled, "Source Terrain", GUI.skin.button, GUILayout.Height(30));
        PWT.gameObject.GetComponent <Terrain>().enabled = PWT.terrainGOEnabled;

        PWT.PWTGOEnabled = GUILayout.Toggle(PWT.PWTGOEnabled, "PolyWorld Terrain", GUI.skin.button, GUILayout.Height(30));
        GUILayout.EndVertical();
        GUILayout.EndHorizontal();

        GUILayout.BeginVertical();
        if (Selection.activeGameObject.transform.childCount > 0)
        {
            GUILayout.Space(10f);
            Transform      goc      = Selection.activeGameObject.transform.GetChild(0);
            MeshRenderer[] children = goc.gameObject.GetComponentsInChildren <MeshRenderer>();
            foreach (MeshRenderer t in children)
            {
                t.enabled = PWT.PWTGOEnabled;
            }


            if (GUILayout.Button(UpdateColor, GUILayout.Height(UpdateColor.height), GUILayout.Width(UpdateColor.width), GUILayout.ExpandWidth(true)))
            {
                MeshFilter[]      meshes = Selection.activeGameObject.transform.GetChild(0).GetComponentsInChildren <MeshFilter>();
                List <GameObject> LOD0   = new List <GameObject>();
                List <GameObject> LOD1   = new List <GameObject>();
                foreach (MeshFilter m in meshes)
                {
                    if (m.name.Contains("LOD0"))
                    {
                        LOD0.Add(m.gameObject);
                    }
                    else if (m.name.Contains("LOD1"))
                    {
                        LOD1.Add(m.gameObject);
                    }
                    else
                    {
                        LOD0.Add(m.gameObject);
                    }
                }


                PWT.RenderVertexColors(LOD0.ToArray());
                if (LOD1.Count > 0)
                {
                    //set the quadsizebias up one, then put it back down to reflect the top LOD level
                    PWT.quadsizeBiasIndex++;
                    PWT.RenderVertexColors(LOD1.ToArray());
                    PWT.quadsizeBiasIndex--;
                }
            }
            GUILayout.Space(10f);
        }
        else
        {
            PWT.prefabPath = null; //we reset the prefab path since there aren't any polyworld terrains
            PWT.meshPath   = null;
        }

        #region Generate Button
        if (GUILayout.Button(UpdateImg, GUILayout.Height(UpdateImg.height), GUILayout.Width(UpdateImg.width), GUILayout.ExpandWidth(true)))
        {
            if (RunChecks())
            {
                if (PWT.deletePWTerrain)
                {
                    if (Selection.activeGameObject.transform.childCount > 0)
                    {
                        for (int c = Selection.activeGameObject.transform.childCount - 1; c >= 0; c--)
                        {
                            GameObject.DestroyImmediate(Selection.activeGameObject.transform.GetChild(c).gameObject);
                        }
                    }
                }

                int priorBiasIndex = PWT.quadsizeBiasIndex;
                List <GameObject[]> everyLODSet = new List <GameObject[]>(); // a list of gameobject arrays. Each element represents LOD sets. everyLODSet[0] is LOD0, [1] is LOD1, etc.. We do this becasue we don't know how many LOD sets there will be.

                GameObject previousPWT = (GameObject)PrefabUtility.GetPrefabParent(PWT.gameObject.GetComponentInChildren <Transform>().gameObject);

                GameObject PWTParent = new GameObject(); //our main parent.
                PWTParent.name = PWT.gameObject.name + "-Faceted";
                PWTParent.transform.position = PWT.gameObject.transform.position;
                PWTParent.transform.parent   = PWT.gameObject.transform;



                if (PWT.GenerateLODs)
                {
                    int lodCounter = 0;
                    everyLODSet.Add(PWT.GeneratePolyWorldTerrain(PWTParent, lodCounter));
                    if (PWT.quadsizeBiasIndex != PWT.quadsizeBias.Length - 1) //change ths to a while loop for more lods. don't forget to change UpdateLODSizes() method and LODSizes!
                    {
                        lodCounter++;
                        PWT.quadsizeBiasIndex++;
                        everyLODSet.Add(PWT.GeneratePolyWorldTerrain(PWTParent, lodCounter));
                    }
                }
                else
                {
                    everyLODSet.Add(PWT.GeneratePolyWorldTerrain(PWTParent, 0));
                }

                //save the meshes to disk. associate them with the right gameobject.
                //WriteAllContent(PWTParent, everyLODSet);

                //go through all the chunks. we do [0] because each element is the same length, and we reference them directly, so it doesn't matter.
                if (PWT.GenerateLODs)
                {
                    //for every chunk..
                    for (int chunkIndex = 0; chunkIndex < everyLODSet[0].Length; chunkIndex++)
                    {
                        //everylodset[0] is lod0, [1] is lod1, etc..
                        GameObject LODObject = new GameObject();
                        LODObject.transform.parent   = PWTParent.transform;                           //parent it to the terrain
                        LODObject.transform.position = everyLODSet[0][chunkIndex].transform.position; //move it to the lod0 position
                        LODObject.name = everyLODSet[0][chunkIndex].name;
                        LODObject.name = LODObject.name.Replace("LOD0", "");

                        everyLODSet[0][chunkIndex].transform.parent = LODObject.transform;

                        LODGroup LODG = LODObject.AddComponent <LODGroup>();

                        LOD[] lods = new LOD[everyLODSet.Count];

                        //go through each LOD at the current chunkindex and grab the renderer component
                        for (int LODIndex = 0; LODIndex < everyLODSet.Count; LODIndex++)
                        {
                            everyLODSet[LODIndex][chunkIndex].transform.parent = LODObject.transform;
                            Renderer[] renderer = new Renderer[1]; //declare an array to hold the mesh renderer component of the associated lod
                            //grab the renderer component from the LOD->Chunk
                            renderer[0] = everyLODSet[LODIndex][chunkIndex].GetComponent <Renderer>();
                            //plug it into the lod array
                            lods[LODIndex] = new LOD(PWT.LODSizes[LODIndex], renderer);
                            // lods[LODIndex].fadeTransitionWidth = 0.5f;
                        }
                        //  LODG.fadeMode = LODFadeMode.CrossFade;
                        LODG.SetLODs(lods);
                    }
                }
                PWT.quadsizeBiasIndex = priorBiasIndex;
                if (PWT.disableConfirmation == false)
                {
                    EditorUtility.DisplayDialog("Success!", "PolyWorld Terrain has been generated and linked to the current Unity Terrain.", "OK");
                }
                else
                {
                    Debug.Log("PolyWorld Terrain generated and linked to Gameobject: " + Selection.activeGameObject.name);
                }

                if (previousPWT)
                {
                    PrefabUtility.ReplacePrefab(PWTParent, previousPWT);
                }
                else
                {
                    PrefabUtility.CreatePrefab("Assets" + PWT.prefabPath + "/" + PWTParent.gameObject.name + ".prefab", PWTParent);
                }
            }
        }
        #endregion

        GUILayout.EndVertical();
        EditorGUILayout.Space();
        GUILayout.BeginVertical(GUI.skin.box);
        PWT.quadsizeBiasIndex = EditorGUILayout.IntSlider("Quad Size Multiplier:", PWT.quadsizeBiasIndex, 0, 4);
        PWT.chunkIndex        = EditorGUILayout.IntSlider("Chunk Size Choice:", PWT.chunkIndex, 0, PWT.chunkSizes.Length - 1);
        GUILayout.EndVertical();
        GUILayout.BeginVertical(GUI.skin.box);
        EditorGUILayout.BeginHorizontal();
        if (PWT.chunkIndex != PWT.chunkSizes.Length - 1)
        {
            GUILayout.Label("Chunk Size: " + PWT.chunkSizes[PWT.chunkIndex].x + "m X " + PWT.chunkSizes[PWT.chunkIndex].y + "m");
        }
        else
        {
            GUILayout.Label("No chunk pass!");
        }
        float numMeshes = (PWT.TWidth / PWT.chunkSizes[PWT.chunkIndex].x) * (PWT.TLength / PWT.chunkSizes[PWT.chunkIndex].y);
        if (numMeshes > 300)
        {
            GUI.color = new Color(1f, 1f, 0f);
        }
        else
        {
            GUI.color = new Color(1f, 1f, 1f);
        }
        GUILayout.Label("Meshes Generated: " + numMeshes);
        EditorGUILayout.EndHorizontal();
        GUILayout.Label("Quad Size: " + PWT.quadWidth + " x " + PWT.quadLength);

        int numQuadsX = (int)(PWT.chunkSizes[PWT.chunkIndex].x / PWT.quadWidth);
        int numQuadsZ = (int)(PWT.chunkSizes[PWT.chunkIndex].y / PWT.quadLength);
        int triCount  = (numQuadsX * numQuadsZ) * 2;
        int vertCount = triCount * 3;

        GUI.color = new Color(1f, 1f, 1f);
        GUILayout.Label("Triangles per Chunk: " + triCount);
        if (vertCount > 65536)
        {
            GUI.color = new Color(1f, 0f, 0f);
        }
        else
        {
            GUI.color = new Color(1f, 1f, 1f);
        }
        GUILayout.Label("Vertices per Chunk: " + vertCount);

        GUI.color = new Color(1f, 1f, 1f);
        GUILayout.EndVertical();

        GUILayout.Space(10);
        GUILayout.BeginVertical(GUI.skin.box);
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Material to Apply:");
        PWT.PWTMat = (Material)EditorGUILayout.ObjectField(PWT.PWTMat, typeof(Material), false);
        EditorGUILayout.EndHorizontal();
        GUI.color = new Color(1f, 1f, 1f);
        PWT.CV    = (QT_PolyWorldTerrain.ColorVariety)EditorGUILayout.EnumPopup("Color Variety: ", PWT.CV);
        EditorGUILayout.BeginHorizontal();
        PWT.BaseMapMip = PWT.GetTilingValue(PWT.CV);
        PWT.blurPasses = EditorGUILayout.IntSlider("Blur Amount:", PWT.blurPasses, 0, 8);

        PWT.quadColor = GUILayout.Toggle(PWT.quadColor, "Color by Quad");
        EditorGUILayout.EndHorizontal();
        GUILayout.EndVertical();
        GUILayout.Space(10);


        GUILayout.BeginVertical(GUI.skin.box);
        EditorGUILayout.BeginHorizontal();
        if (PWT.quadsizeBiasIndex == PWT.quadsizeBias.Length - 1)
        {
            GUI.color = new Color(1f, 0f, 0f);
        }
        else
        {
            GUI.color = new Color(1f, 1f, 1f);
        }
        PWT.GenerateLODs = GUILayout.Toggle(PWT.GenerateLODs, "Generate LODs");
        //PWT.Average = EditorGUILayout.Toggle("Average Vertices", PWT.Average);
        GUI.color = new Color(1f, 1f, 1f);
        if (PWT.quadsizeBiasIndex == PWT.quadsizeBias.Length - 1)
        {
            PWT.GenerateLODs = false;
            GUILayout.Label("No Valid LODS with Current Settings");
        }
        EditorGUILayout.EndHorizontal();
        if (PWT.GenerateLODs)
        {
            GUILayout.Label("Transition Distances:");
            EditorGUILayout.BeginHorizontal();

            //PWT.LODSizes[0] = Mathf.Clamp01(EditorGUILayout.FloatField("LOD1 %: ", PWT.LODSizes[0]));
            // PWT.LODSizes[1] = Mathf.Clamp(EditorGUILayout.FloatField("Culled %: ", PWT.LODSizes[1]),0,PWT.LODSizes[0]-.01f);
            GUILayout.Label("LOD 1:");
            PWT.LODSizes[0] = EditorGUILayout.Slider(PWT.LODSizes[0], PWT.LODSizes[1], 1);

            GUILayout.Label("Cull:");
            PWT.LODSizes[1] = EditorGUILayout.Slider(PWT.LODSizes[1], 0, PWT.LODSizes[0]);
            EditorGUILayout.EndHorizontal();
            if (Selection.activeGameObject.transform.childCount > 0)
            {
                if (GUILayout.Button("Update LOD Sizes"))
                {
                    PWT.UpdateLODSizes();
                }
            }
        }

        //override this so we don't get multiple terrains in a hierarchy for when we render vertex colors
        PWT.deletePWTerrain     = GUILayout.Toggle(PWT.deletePWTerrain, "Delete Polyworld Terrains on Update");
        PWT.disableConfirmation = GUILayout.Toggle(PWT.disableConfirmation, "Disable Confirmation");

        GUILayout.EndVertical();
        if (GUILayout.Button("Help"))
        {
            Application.OpenURL("http://qt-ent.com/PolyWorld/scripts/");
        }



        for (int x = 0; x < PWT.terrainData.splatPrototypes.Length; x++)
        {
            SetTextureImporterFormat(true, PWT.terrainData.splatPrototypes[x].texture);
        }
    }
Esempio n. 26
0
    private void OnGUI()
    {
        GUILayout.Label("Surreal Grass Creator", EditorStyles.boldLabel);

        scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false);
        //camera = (Camera)EditorGUILayout.ObjectField(new GUIContent("1. Camera"), camera, typeof(Camera));
        targetObject = (GameObject)EditorGUILayout.ObjectField(new GUIContent("1. Target GameObject"), targetObject, typeof(GameObject));
        if (GUILayout.Button("Auto-Assign Cell Division and Grass Density"))
        {
            if (targetObject == null)
            {
                ShowNotification(new GUIContent("You must select a Target Object before auto-assigning cell division and grass density."));
                return;
            }
            else
            {
                Bounds objectBounds = new Bounds();
                if (targetObject.GetComponent <Terrain>() != null)
                {
                    objectBounds = targetObject.GetComponent <Terrain>().terrainData.bounds;
                }
                else if (targetObject.GetComponent <MeshRenderer>() != null)
                {
                    objectBounds = targetObject.GetComponent <MeshRenderer>().bounds;
                }
                else
                {
                    ShowNotification(new GUIContent("Please select a valid Target GameObject"));
                    return;
                }

                float boundX = objectBounds.extents.x * 2;
                float boundZ = objectBounds.extents.z * 2;

                float cellDivSuggestion = 0;
                if (boundX < boundZ)
                {
                    cellDivSuggestion = boundX / 10;
                }
                else
                {
                    cellDivSuggestion = boundZ / 10;
                }

                //if (cellDivSuggestion < 1f)
                //    cellDivisions = 1f;
                //else
                cellDivisions = Convert.ToInt32(Math.Ceiling(cellDivSuggestion));

                float size = objectBounds.extents.x > objectBounds.extents.z ? objectBounds.extents.x * 2 / (float)cellDivisions : objectBounds.extents.z * 2 / (float)cellDivisions;
                if (size >= 10)
                {
                    grassSamples = 60000;
                }
                else
                {
                    grassSamples = Convert.ToInt32(Math.Ceiling(size / (float)10 * (float)60000));
                }
            }
        }

        List <GUIContent> tempLayerList = new List <GUIContent>();

        for (int i = 0; i <= 31; i++)
        {
            var layer = LayerMask.LayerToName(i);
            if (layer.Length > 0)
            {
                if (FindGameObjectsWithLayer(layer) == null)
                {
                    tempLayerList.Add(new GUIContent(layer));
                }
            }
        }
        layers = tempLayerList.ToArray();

        selectedLayer = EditorGUILayout.Popup(new GUIContent("2. Empty Layer"), selectedLayer, layers);
        densityMap    = (Texture2D)EditorGUILayout.ObjectField(new GUIContent("3. Grass Density Map"), densityMap, typeof(Texture2D));
        cellDivisions = EditorGUILayout.IntSlider(new GUIContent("4. Cell Divisions"), cellDivisions, 1, 1000);
        grassSamples  = EditorGUILayout.IntSlider(new GUIContent("5. Cell Grass Density"), grassSamples, 0, 60000);
        //cullDistance = EditorGUILayout.FloatField(new GUIContent("7. Cull Distance"), cullDistance);
        grassMaterial = (Material)EditorGUILayout.ObjectField(new GUIContent("6. Grass Material"), grassMaterial, typeof(Material));

        GUILayout.Space(15.0f);
        GUILayout.Label("How To Use", EditorStyles.boldLabel);
        string descriptionString = "Surreal Grass works by creating a grid of cells over your entire target terrain or mesh, each cell then gets populated with " +
                                   "a specified number of grass blades.  This editor will generate all of the cells for you and pack them into one object " +
                                   " in your scene.";

        GUILayout.Label(descriptionString, EditorStyles.wordWrappedLabel);

        GUILayout.Label("*** Disclaimer ***", EditorStyles.boldLabel);
        GUILayout.Label("Surreal Grass will create a new layer in your scene and temporarily move the Target Object to that layer.  After the tools runs, it will move your Target Object back to its original layer.", EditorStyles.wordWrappedLabel);
        GUILayout.Space(15.0f);
        GUILayout.Label("Step 1:  You can run this tool multiple times to have grass spawn on different objects, just select a new Target GameObject each time you run the tool. (this setting cannot be changed after creating Grass objects)", EditorStyles.wordWrappedLabel);
        GUILayout.Space(15.0f);
        GUILayout.Label("Step 2:  You must create and assign an empty layer to the Surreal Grass Creator to do it's thing on.  This layer can be deleted after the tool runs or it can be reused for running the tool multiple times as long as it stays empty.", EditorStyles.wordWrappedLabel);
        GUILayout.Space(15.0f);
        GUILayout.Label("Step 3:  This is the density map that will be applied to your target object to determine where grass is rendered.  BLACK = rendered, WHITE = not rendered (this setting cannot be changed after creating Grass objects)", EditorStyles.wordWrappedLabel);
        GUILayout.Space(15.0f);
        GUILayout.Label("Step 4:  This figure determines the size of each cell.  e.g. A value of \"10\" will calculate 10 divisions in the X direction and 10 divisions in the Z direction resulting in 100 total cells.  A good grass density is about 60,000 blades per 10m square.  So it's good to make sure that your cell divisions figure results in a cell size of around 10m.  If your mesh/terrain is smaller than 10m square, then just use a division of \"1\".  The higher the number of divisions, the longer this tool takes to run.  (this setting cannot be changed after creating Grass objects)", EditorStyles.wordWrappedLabel);
        GUILayout.Space(15.0f);
        GUILayout.Label("Step 5:  Surreal Grass allows up to 60,000 blades of grass per cell. (this setting cannot be changed after creating Grass objects)", EditorStyles.wordWrappedLabel);
        GUILayout.Space(15.0f);
        GUILayout.Label("Step 6:  Multiple grass materials can be created using the SurrealGrassShader, select the grass material you want to use for this Target object.  The selected material DOES NOT replace the material on the object itself.  If none is selected, the creator will use the \"SurrealDefaultGrassMat\" material", EditorStyles.wordWrappedLabel);



        GUILayout.EndScrollView();

        if (GUILayout.Button("Generate Grass Objects"))
        {
            if (targetObject == null)
            {
                ShowNotification(new GUIContent("You must select a Target Object before generating grass objects."));
                return;
            }
            else
            {
                Bounds objectBounds = new Bounds();

                int targetObjectType = 0;
                if (targetObject.GetComponent <Terrain>() != null)
                {
                    objectBounds     = targetObject.GetComponent <Terrain>().terrainData.bounds;
                    targetObjectType = 1;
                }
                else if (targetObject.GetComponent <MeshRenderer>() != null)
                {
                    objectBounds     = targetObject.GetComponent <MeshRenderer>().bounds;
                    targetObjectType = 2;
                }
                else
                {
                    ShowNotification(new GUIContent("Please select a valid Target GameObject"));
                    return;
                }

                float size = objectBounds.extents.x > objectBounds.extents.z ? objectBounds.extents.x * 2 / cellDivisions : objectBounds.extents.z * 2 / cellDivisions;

                float destYPosition = (objectBounds.extents.y * 2) + 100f;

                float srcXPosition = targetObject.transform.position.x - (targetObjectType == 2 ? objectBounds.extents.x : 0f);
                float srcZPosition = targetObject.transform.position.z - (targetObjectType == 2 ? objectBounds.extents.z : 0f);

                float destXorigin   = srcXPosition;
                float destZorigin   = srcZPosition;
                float destXPosition = srcXPosition;
                float destZPosition = srcZPosition;

                LayerMask layerMask = new LayerMask();
                layerMask.value = LayerMask.NameToLayer(layers[selectedLayer].text);

                originalLayer      = targetObject.layer;
                targetObject.layer = layerMask.value;

                GameObject parentEmpty = new GameObject(targetObject.name + "_SGRenderer");
                parentEmpty.transform.position = new Vector3(srcXPosition, targetObject.transform.position.y, srcZPosition);



                for (int x = 0; x < cellDivisions; x++)
                {
                    destZPosition = destZorigin;
                    destXPosition = destXorigin + (x * size);
                    for (int z = 0; z < cellDivisions; z++)
                    {
                        destZPosition = destZorigin + (z * size);
                        GameObject   lod      = new GameObject(targetObject.name + "_SGRendererLOD_" + x.ToString() + "_" + z.ToString());
                        GameObject   empty    = new GameObject(targetObject.name + "_SGRenderer_" + x.ToString() + "_" + z.ToString());
                        MeshFilter   filter   = empty.AddComponent <MeshFilter>();
                        MeshRenderer renderer = empty.AddComponent <MeshRenderer>();
                        //filter.name = targetObject.name + "_SGMeshFilter";
                        Mesh mesh = new Mesh();
                        empty.layer = layerMask.value;

                        empty.transform.position = new Vector3(srcXPosition, targetObject.transform.position.y, srcZPosition);

                        List <Vector3> positions = new List <Vector3>();
                        List <int>     indicies  = new List <int>();
                        List <Vector3> normals   = new List <Vector3>();
                        int            hitCount  = 0;
                        for (int i = 0; i < grassSamples; i++)
                        {
                            Vector3 origin = new Vector3(destXPosition, destYPosition, destZPosition);
                            origin.x += size * UnityEngine.Random.Range(0.0f, 1f);
                            origin.z += size * UnityEngine.Random.Range(0.0f, 1f);
                            Ray ray = new Ray(origin, Vector3.down);

                            RaycastHit hit;
                            if (Physics.Raycast(ray, out hit, 1000f, 1 << layerMask.value))
                            {
                                bool record = true;
                                if (densityMap != null)
                                {
                                    record = false;
                                    Vector2 uvCoord = hit.textureCoord;
                                    Color   color   = densityMap.GetPixel(Convert.ToInt32(uvCoord.x * densityMap.width), Convert.ToInt32(uvCoord.y * densityMap.height));
                                    if (color.grayscale < 0.5f)
                                    {
                                        record = true;
                                    }
                                }

                                if (record)
                                {
                                    origin.x -= empty.transform.position.x;
                                    origin.z -= empty.transform.position.z;
                                    positions.Add(hit.point);
                                    indicies.Add(hitCount);
                                    normals.Add(hit.normal);
                                    hitCount += 1;
                                }
                            }
                        }
                        if (hitCount > 1)
                        {
                            mesh.SetVertices(positions);
                            mesh.SetIndices(indicies.ToArray(), MeshTopology.Points, 0);
                            mesh.SetNormals(normals);
                            filter.mesh = mesh;
                            filter.transform.position = new Vector3(0, 0, 0);

                            if (grassMaterial != null)
                            {
                                renderer.material = grassMaterial;
                            }

                            parentEmpty.layer = layerMask.value;
                            empty.layer       = layerMask.value;
                            lod.transform.SetParent(parentEmpty.transform, true);
                            empty.transform.SetParent(lod.transform, true);
                            lod.AddComponent <LODGroup>();
                            LODGroup   lodGroup  = lod.GetComponent <LODGroup>();
                            LOD[]      lods      = new LOD[1];
                            Renderer[] rendArray = new Renderer[1];
                            rendArray[0] = empty.GetComponent <Renderer>();
                            lods[0]      = new LOD(0.14f, rendArray);
                            //lods[1] = new LOD(0.27f, new Renderer[0]);
                            lodGroup.SetLODs(lods);
                        }
                        else
                        {
                            DestroyImmediate(empty);
                        }
                    }
                }
                targetObject.layer = originalLayer;
            }
        }
    }
Esempio n. 27
0
        public static GameObject LoadOBJFile(string fn)
        {
            Debug.Log("Loading map....");
            Debug.Log(fn);
            MaterialLoader.LoadAlphaMaterial();
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fn);

            if (fileNameWithoutExtension.Contains("alpha"))
            {
                alphaIsEnabledOld = true;
            }
            else
            {
                alphaIsEnabledOld = false;
            }
            bool                     flag2      = false;
            List <Vector3>           list       = new List <Vector3>();
            List <Vector3>           list2      = new List <Vector3>();
            List <Vector2>           list3      = new List <Vector2>();
            List <Vector3>           list4      = new List <Vector3>();
            List <Vector3>           list5      = new List <Vector3>();
            List <Vector2>           list6      = new List <Vector2>();
            List <string>            list7      = new List <string>();
            List <string>            list8      = new List <string>();
            Dictionary <string, int> dictionary = new Dictionary <string, int>();
            List <OBJFace>           list9      = new List <OBJFace>();
            string                   text       = "";
            string                   text2      = "default";

            Material[] array    = null;
            FileInfo   fileInfo = new FileInfo(fn);

            string[] text3 = File.ReadAllLines(fn);

            for (int e = 0; e < text3.Length; e++)
            {
                if (text3[e].Length > 0 && text3[e][0] != '#')
                {
                    string   text4  = text3[e].Trim().Replace("  ", " ");
                    string[] array2 = text4.Split(new char[]
                    {
                        ' '
                    });
                    string text5 = text4.Remove(0, text4.IndexOf(' ') + 1);
                    switch (array2[0])
                    {
                    case "o":
                        text2 = text5;
                        if (!list8.Contains(text2))
                        {
                            list8.Add(text2);
                        }
                        break;

                    case "mtllib":
                        string text6 = Search.OBJGetFilePath(text5, fileInfo.Directory.FullName + Path.DirectorySeparatorChar.ToString(), fileNameWithoutExtension);
                        if (text6 != null)
                        {
                            array = MaterialLoader.LoadMTLFile(text6, alphaIsEnabledOld);
                        }
                        break;

                    case "usemtl":
                        text = text5;
                        if (!list7.Contains(text))
                        {
                            list7.Add(text);
                        }
                        if (splitByMaterial && !list8.Contains(text))
                        {
                            list8.Add(text);
                        }
                        break;

                    case "v":
                        list.Add(ParseVectorFromCMPS(array2));
                        break;

                    case "vn":
                        list2.Add(ParseVectorFromCMPS(array2));
                        break;

                    case "vt":
                        list3.Add(ParseVectorFromCMPS(array2));
                        break;

                    case "f":
                        int[] array3 = new int[array2.Length - 1];
                        for (int i = 1; i < array2.Length; i++)
                        {
                            string text7 = array2[i];
                            int    num   = -1;
                            int    num2  = -1;
                            int    num3;
                            if (text7.Contains("//"))
                            {
                                string[] array8 = text7.Split(new char[]
                                {
                                    '/'
                                });
                                num3 = int.Parse(array8[0]) - 1;
                                num  = int.Parse(array8[2]) - 1;
                            }
                            else if (text7.Count(new Func <char, bool>(OBJLoader.Func1)) == 2)
                            {
                                string[] array9 = text7.Split(new char[]
                                {
                                    '/'
                                });
                                num3 = int.Parse(array9[0]) - 1;
                                num2 = int.Parse(array9[1]) - 1;
                                num  = int.Parse(array9[2]) - 1;
                            }
                            else if (!text7.Contains("/"))
                            {
                                num3 = int.Parse(text7) - 1;
                            }
                            else
                            {
                                string[] array10 = text7.Split(new char[]
                                {
                                    '/'
                                });
                                num3 = int.Parse(array10[0]) - 1;
                                num2 = int.Parse(array10[1]) - 1;
                            }
                            string key = string.Concat(new object[]
                            {
                                num3,
                                "|",
                                num,
                                "|",
                                num2
                            });
                            if (dictionary.ContainsKey(key))
                            {
                                array3[i - 1] = dictionary[key];
                            }
                            else
                            {
                                array3[i - 1]   = dictionary.Count;
                                dictionary[key] = dictionary.Count;
                                list4.Add(list[num3]);
                                if (num < 0 || num > list2.Count - 1)
                                {
                                    list5.Add(Vector3.zero);
                                }
                                else
                                {
                                    flag2 = true;
                                    list5.Add(list2[num]);
                                }
                                if (num2 < 0 || num2 > list3.Count - 1)
                                {
                                    list6.Add(Vector2.zero);
                                }
                                else
                                {
                                    list6.Add(list3[num2]);
                                }
                            }
                        }
                        if (array3.Length < 5 && array3.Length >= 3)
                        {
                            List <OBJFace> list10   = list9;
                            OBJFace        objface3 = new OBJFace
                            {
                                materialName = text,
                                indexes      = new int[]
                                {
                                    array3[0],
                                    array3[1],
                                    array3[2]
                                },
                                meshName = (splitByMaterial ? text : text2)
                            };
                            OBJFace item = objface3;
                            list10.Add(item);
                            if (array3.Length > 3)
                            {
                                List <OBJFace> list11 = list9;
                                objface3 = new OBJFace
                                {
                                    materialName = text,
                                    meshName     = (splitByMaterial ? text : text2),
                                    indexes      = new int[]
                                    {
                                        array3[2],
                                        array3[3],
                                        array3[0]
                                    }
                                };
                                item = objface3;
                                list11.Add(item);
                            }
                        }
                        break;
                    }
                }
            }
            if (list8.Count == 0)
            {
                list8.Add("default");
            }
            GameObject gameObject = new GameObject("ModdedMap");

            using (List <string> .Enumerator enumerator = list8.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    string     obj         = enumerator.Current;
                    GameObject gameObject2 = new GameObject(obj);
                    gameObject2.transform.parent     = gameObject.transform;
                    gameObject2.transform.localScale = new Vector3(-1f, 1f, 1f);
                    Mesh mesh = new Mesh();
                    mesh.name = obj;
                    List <Vector3>        list12      = new List <Vector3>();
                    List <Vector3>        list13      = new List <Vector3>();
                    List <Vector2>        list14      = new List <Vector2>();
                    List <int[]>          list15      = new List <int[]>();
                    Dictionary <int, int> dictionary2 = new Dictionary <int, int>();
                    OBJLoader.meshMaterialNames = new List <string>();
                    OBJFace[] source = list9.Where(x => x.meshName == obj).ToArray <OBJFace>();
                    using (List <string> .Enumerator enumerator2 = list7.GetEnumerator())
                    {
                        while (enumerator2.MoveNext())
                        {
                            mn = enumerator2.Current;
                            OBJFace[] array4 = source.Where(x => x.materialName == mn).ToArray <OBJFace>();
                            if (array4.Length != 0)
                            {
                                int[] array5 = new int[0];
                                foreach (OBJFace objface2 in array4)
                                {
                                    int num4 = array5.Length;
                                    Array.Resize <int>(ref array5, num4 + objface2.indexes.Length);
                                    Array.Copy(objface2.indexes, 0, array5, num4, objface2.indexes.Length);
                                }
                                meshMaterialNames.Add(mn);
                                if (mesh.subMeshCount != meshMaterialNames.Count)
                                {
                                    mesh.subMeshCount = meshMaterialNames.Count;
                                }
                                for (int j = 0; j < array5.Length; j++)
                                {
                                    int num5 = array5[j];
                                    if (dictionary2.ContainsKey(num5))
                                    {
                                        array5[j] = dictionary2[num5];
                                    }
                                    else
                                    {
                                        list12.Add(list4[num5]);
                                        list13.Add(list5[num5]);
                                        list14.Add(list6[num5]);
                                        dictionary2[num5] = list12.Count - 1;
                                        array5[j]         = dictionary2[num5];
                                    }
                                }
                                list15.Add(array5);
                            }
                        }
                    }
                    mesh.SetVertices(list12);
                    mesh.SetNormals(list13);
                    mesh.SetUVs(0, list14);
                    for (int k = 0; k < list15.Count; k++)
                    {
                        mesh.SetIndices(list15[k], MeshTopology.Triangles, k);
                    }
                    if (!flag2)
                    {
                        mesh.RecalculateNormals();
                    }
                    mesh.RecalculateBounds();
                    Material[] array6 = new Material[meshMaterialNames.Count];
                    counter = 0;
                    while (counter < meshMaterialNames.Count)
                    {
                        if (array == null)
                        {
                            Debug.Log("array null");
                            array6[counter] = new Material(Shader.Find("HDRP/Lit"));
                        }
                        else
                        {
                            Material[]           array12 = array;
                            Predicate <Material> match;
                            if ((match = haha3) == null)
                            {
                                match = haha3 = new Predicate <Material>(LoadOBJFile3);
                            }
                            Material material = Array.Find(array12, match);
                            Debug.Log(material);
                            if (material == null)
                            {
                                Debug.Log("material null");
                                array6[counter] = new Material(Shader.Find("HDRP/Lit"));
                            }
                            else
                            {
                                array6[counter] = material;
                            }
                        }
                        array6[counter].name = meshMaterialNames[counter];
                        int i2 = counter;
                        counter = i2 + 1;
                    }
                    meshFilter   = gameObject2.AddComponent <MeshFilter>();
                    meshRenderer = gameObject2.AddComponent <MeshRenderer>();
                    meshRenderer.receiveShadows = true;
                    meshFilter.mesh             = mesh;
                    meshRenderer.materials      = array6;
                    if (MaterialLoader.alphaIsEnabled || alphaIsEnabledOld)
                    {
                        Renderer[] newRenderer = new Renderer[1];
                        newRenderer[0] = meshRenderer;
                        LODGroup lods = gameObject2.AddComponent <LODGroup>();
                        LOD[]    lod  = new LOD[1];
                        lod[0].renderers = newRenderer;
                        lod[0].screenRelativeTransitionHeight = 0.8f;
                        lods.SetLODs(lod);
                        lods.RecalculateBounds();
                    }
                    if (!alphaIsEnabledOld)
                    {
                        meshCollider            = gameObject2.AddComponent <MeshCollider>();
                        meshCollider.convex     = false;
                        meshCollider.sharedMesh = mesh;
                        CarX.Material carXMaterial = gameObject2.AddComponent <CarX.Material>();
                        string        objectParams = gameObject2.name.Split('_')[0].ToLower();
                        switch (objectParams)
                        {
                        case "road":
                            Debug.Log("road set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.01f, 0f, 0f, 100f, 0f, 0f, 100f);
                            gameObject2.isStatic = true;
                            break;

                        case "kerb":
                            Debug.Log("kerb set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.015f, -0.007f, 0f, 12f, -0.007f, 0f, 12f);
                            gameObject2.isStatic = true;
                            break;

                        case "sand":
                            Debug.Log("sand set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Sand, 1, 0.13f, 0.06f, 0.05f, 25f, 0.06f, 0.05f, 25f);
                            gameObject2.isStatic = true;
                            break;

                        case "snow":
                            Debug.Log("snow set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Snow, 2, 0.1f, -0.01f, -0.01f, 30f, -0.01f, -0.01f, 30f);
                            gameObject2.isStatic = true;
                            break;

                        case "grass":
                            Debug.Log("grass set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Grass, 1, 0f, 0.05f, 0.04f, 25f, 0.05f, 0.04f, 25f);
                            gameObject2.isStatic = true;
                            break;

                        case "gravel":
                            Debug.Log("gravel set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Sand, 2, 0.1f, -0.01f, -0.01f, 30f, -0.01f, -0.01f, 30f);
                            gameObject2.isStatic = true;
                            break;

                        case "icyroad":
                            Debug.Log("icyroad set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 0.73f, 0.025f, 0f, 0f, 30f, 0f, 0f, 30f);
                            gameObject2.isStatic = true;
                            break;

                        case "dirt":
                            Debug.Log("dirt set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Earth, 1, 0.025f, -0.007f, 0f, 12f, -0.007f, 0f, 12f);
                            gameObject2.isStatic = true;
                            break;

                        case "nocol":
                            Debug.Log("nocol set");
                            meshCollider.enabled = false;
                            gameObject2.isStatic = true;
                            break;

                        case "rb":
                            Debug.Log("rb set");
                            gameObject2.transform.SetParent(null);
                            meshCollider.convex = true;
                            Rigidbody rb = gameObject2.AddComponent <Rigidbody>();
                            rbGos.Add(gameObject2);
                            gameObject2.isStatic = false;
                            break;

                        default:
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.01f, 0f, 0f, 100f, 0f, 0f, 100f);
                            gameObject2.isStatic = true;
                            Debug.Log("Surface not set for this object");
                            break;
                        }
                    }
                    gameObject2.layer = 11;
                }
            }
            return(gameObject);
        }