private static void conformSelection(ProceduralObject obj, List <int> editingVertexIndex, Vertex[] buffer, bool andNetBuildings)
        {
            obj.historyEditionBuffer.InitializeNewStep(EditingStep.StepType.vertices, buffer);
            var bounds   = new Bounds(ProceduralUtils.VertexWorldPosition(buffer.First(v => v.Index == editingVertexIndex[0]).Position, obj), Vector3.zero);
            var vertices = buffer.Where(v => (editingVertexIndex.Contains(v.Index) || (v.IsDependent && editingVertexIndex.Contains(v.DependencyIndex))));

            foreach (Vertex v in vertices)
            {
                bounds.Encapsulate(ProceduralUtils.VertexWorldPosition(v.Position, obj));
            }

            Vector3 bottomPoint = bounds.center;

            bottomPoint.y -= bounds.extents.y;
            var boundsOffset = new Vector3(0, bounds.size.y, 0);

            foreach (Vertex v in vertices)
            {
                var worldPos = ProceduralUtils.VertexWorldPosition(v, obj);
                var yDiff    = worldPos.y - bottomPoint.y;
                worldPos    = ProceduralUtils.NearestGroundPointVertical(worldPos + boundsOffset, andNetBuildings);
                worldPos.y += yDiff;
                v.Position  = Quaternion.Inverse(obj.m_rotation) * (worldPos - obj.m_position);
                if (obj.isPloppableAsphalt)
                {
                    v.Position = v.Position.RevertPloppableAsphaltPosition();
                }
            }
            obj.historyEditionBuffer.ConfirmNewStep(buffer);
        }
        public static void SnapEachToGround(ProceduralObject obj, List <int> editingVertexIndex, Vertex[] buffer)
        {
            obj.historyEditionBuffer.InitializeNewStep(EditingStep.StepType.vertices, buffer);
            var vertices = buffer.Where(v => (editingVertexIndex.Contains(v.Index) || (v.IsDependent && editingVertexIndex.Contains(v.DependencyIndex))));

            foreach (Vertex v in vertices)
            {
                var worldPos = ProceduralUtils.NearestGroundPointVertical(ProceduralUtils.VertexWorldPosition(v, obj));
                v.Position = Quaternion.Inverse(obj.m_rotation) * (worldPos - obj.m_position);
                if (obj.isPloppableAsphalt)
                {
                    v.Position = v.Position.RevertPloppableAsphaltPosition();
                }
            }

            obj.historyEditionBuffer.ConfirmNewStep(buffer);
        }
 public static void SplitSelectedVertex(ProceduralObject obj, List <int> editingVertexIndex, Vertex[] buffer)
 {
     foreach (Vertex v in buffer)
     {
         if (!v.IsDependent)
         {
             continue;
         }
         if (!editingVertexIndex.Contains(v.DependencyIndex))
         {
             continue;
         }
         v.DependencyIndex = 0;
         v.IsDependent     = false;
         ProceduralObjectsLogic.instance.editingVertexIndex.Add(v.Index);
     }
     ProceduralUtils.UpdateVertexSelectedState(ProceduralObjectsLogic.instance.editingVertexIndex, obj);
 }
        public static void InvertSelection(ProceduralObject obj, List <int> editingVertexIndex, Vertex[] buffer)
        {
            var logic = ProceduralObjectsLogic.instance;

            foreach (Vertex v in buffer)
            {
                if (v.IsDependent)
                {
                    continue;
                }
                if (editingVertexIndex.Contains(v.Index))
                {
                    editingVertexIndex.Remove(v.Index);
                }
                else
                {
                    editingVertexIndex.Add(v.Index);
                }
            }
            ProceduralUtils.UpdateVertexSelectedState(editingVertexIndex, obj);
        }
        public ProceduralObject(ProceduralObjectContainer container, LayerManager layerManager, PropInfo[] props, BuildingInfo[] buildings)
        {
            if (container.objectType == "PROP")
            {
                PropInfo sourceProp = props.FirstOrDefault(info => info.name == container.basePrefabName);
                this._baseProp          = sourceProp;
                this.id                 = container.id;
                this.basePrefabName     = container.basePrefabName;
                this.baseInfoType       = "PROP";
                this.isPloppableAsphalt = sourceProp.IsPloppableAsphalt();
                m_position              = container.position.ToVector3();
                m_rotation              = container.rotation.ToQuaternion();
                m_material              = GameObject.Instantiate(sourceProp.m_material); // overkil ??
                if (container.meshStatus == 0 && container.vertices != null)
                {
                    // CHECK FOR MESH REPETITION
                    if (ProceduralUtils.CheckMeshEquivalence(container.vertices, sourceProp.m_mesh.vertices))
                    {
                        meshStatus = 1;
                        m_mesh     = sourceProp.m_mesh;
                        vertices   = Vertex.CreateVertexList(sourceProp);
                    }
                    else
                    {
                        meshStatus = 2;
                        m_mesh     = sourceProp.m_mesh.InstantiateMesh();
                        var vert = SerializableVector3.ToStandardVector3Array(container.vertices);
                        if (container.scale != 0)
                        {
                            for (int i = 0; i < vert.Count(); i++)
                            {
                                vert[i] = new Vector3(vert[i].x * container.scale, vert[i].y * container.scale, vert[i].z * container.scale);
                            }
                        }
                        m_mesh.SetVertices(new List <Vector3>(vert));
                        vertices = Vertex.CreateVertexList(this);
                    }
                }
                else if (container.meshStatus == 1)
                {
                    meshStatus = 1;
                    m_mesh     = sourceProp.m_mesh;
                    vertices   = Vertex.CreateVertexList(sourceProp);
                }
                else // meshstatus2
                {
                    meshStatus = 2;
                    m_mesh     = sourceProp.m_mesh.InstantiateMesh();
                    if (container.serializedMeshData != null)
                    {
                        container.serializedMeshData.ApplyDataToObject(this);
                    }
                    else if (container.vertices != null)
                    {
                        var vert = SerializableVector3.ToStandardVector3Array(container.vertices);
                        if (container.scale != 0)
                        {
                            for (int i = 0; i < vert.Count(); i++)
                            {
                                vert[i] = new Vector3(vert[i].x * container.scale, vert[i].y * container.scale, vert[i].z * container.scale);
                            }
                        }
                        m_mesh.SetVertices(new List <Vector3>(vert));
                    }
                    else
                    {
                        throw new Exception("[ProceduralObjects] Loading failure : Missing mesh data !");
                    }
                    vertices = Vertex.CreateVertexList(this);
                }
                if (sourceProp.m_mesh.name == "ploppableasphalt-prop" || sourceProp.m_mesh.name == "ploppableasphalt-decal")
                {
                    m_color = m_material.ApplyPloppableColor();
                }
                if (container.hasCustomTexture && TextureManager.instance != null)
                {
                    var customTex = TextureManager.instance.FindTexture(container.customTextureName);
                    m_material.mainTexture = customTex as Texture;
                    customTexture          = customTex;
                }
            }
            else if (container.objectType == "BUILDING")// building
            {
                BuildingInfo sourceProp = buildings.FirstOrDefault(info => info.name == container.basePrefabName);
                this._baseBuilding      = sourceProp;
                this.id                 = container.id;
                this.basePrefabName     = container.basePrefabName;
                this.baseInfoType       = "BUILDING";
                this.isPloppableAsphalt = false;
                m_position              = container.position.ToVector3();
                m_rotation              = container.rotation.ToQuaternion();
                meshStatus              = 2;
                m_material              = GameObject.Instantiate(sourceProp.m_material); // overkill ??
                m_mesh = sourceProp.m_mesh.InstantiateMesh();
                if (container.serializedMeshData != null)
                {
                    container.serializedMeshData.ApplyDataToObject(this);
                }
                else if (container.vertices != null)
                {
                    var vert = SerializableVector3.ToStandardVector3Array(container.vertices);
                    if (container.scale != 0)
                    {
                        for (int i = 0; i < vert.Count(); i++)
                        {
                            vert[i] = new Vector3(vert[i].x * container.scale, vert[i].y * container.scale, vert[i].z * container.scale);
                        }
                    }
                    m_mesh.SetVertices(new List <Vector3>(vert));
                }
                else
                {
                    throw new Exception("[ProceduralObjects] Loading failure : Missing mesh data !");
                }
                vertices        = Vertex.CreateVertexList(this);
                m_mesh.colors   = new Color[] { };
                m_mesh.colors32 = new Color32[] { };

                if (container.hasCustomTexture && TextureManager.instance != null)
                {
                    var customTex = TextureManager.instance.FindTexture(container.customTextureName);
                    m_material.mainTexture = customTex as Texture;
                    customTexture          = customTex;
                }
            }
            m_visibility   = container.visibility;
            renderDistance = container.renderDistance;
            MaterialOptions.FixDecalRenderDist(this);
            renderDistLocked = container.renderDistLocked;
            if (container.textParam != null)
            {
                m_textParameters = TextParameters.Clone(container.textParam, true);
                for (int i = 0; i < m_textParameters.Count(); i++)
                {
                    if (m_textParameters[i].m_fontColor == null)
                    {
                        if (m_textParameters[i].serializableColor != null)
                        {
                            m_textParameters[i].m_fontColor = m_textParameters[i].serializableColor.ToColor();
                        }
                        else
                        {
                            m_textParameters[i].m_fontColor = Color.white;
                        }
                    }
                }
                //  m_textParameters.SetFonts();
                var originalTex = new Texture2D(m_material.mainTexture.width, m_material.mainTexture.height, TextureFormat.RGBA32, false);
                originalTex.SetPixels(((Texture2D)m_material.mainTexture).GetPixels());
                originalTex.Apply();
                m_material.mainTexture = m_textParameters.ApplyParameters(originalTex) as Texture;
            }
            else
            {
                m_textParameters = null;
            }
            if (container.belongsToGroup)
            {
                if (container.groupRootId == -1)
                {
                    isRootOfGroup    = true;
                    _groupRootIdData = -1;
                }
                else
                {
                    _groupRootIdData = container.groupRootId;
                    isRootOfGroup    = false;
                }
            }
            else
            {
                _groupRootIdData = -2;
                group            = null;
                isRootOfGroup    = false;
            }

            disableRecalculation    = container.disableRecalculation;
            this.normalsRecalcMode  = container.normalsRecalculation;
            this.flipFaces          = container.flipFaces;
            this.disableCastShadows = container.disableCastShadows;
            if (this.flipFaces)
            {
                VertexUtils.flipFaces(this);
            }
            historyEditionBuffer = new HistoryBuffer(this);

            if (container.color == null)
            {
                if (!(m_mesh.name == "ploppableasphalt-prop" || m_mesh.name == "ploppableasphalt-decal"))
                {
                    m_color = Color.white;
                }
            }
            else
            {
                m_color          = container.color;
                m_material.color = m_color;
            }

            if (container.layerId != 0)
            {
                if (layerManager.m_layers.Any(l => l.m_id == container.layerId))
                {
                    layer = layerManager.m_layers.Single(l => l.m_id == container.layerId);
                }
                else
                {
                    Debug.LogError("[ProceduralObjects] Layer of an object not found !");
                }
            }
            else
            {
                layer = null;
            }
            if (container.tilingFactor == 0)
            {
                this.tilingFactor = 8;
            }
            else
            {
                this.tilingFactor = container.tilingFactor;
            }

            m_modules = ModuleManager.LoadModulesFromData(container.modulesData, true, this);
        }
        public void ExportSelection(string name, ExternalProceduralObjectsManager manager, bool staticImport)
        {
            if (selection_objects == null)
            {
                return;
            }
            if (selection_objects.Count <= 1)
            {
                return;
            }
            string path = ProceduralObjectsMod.ExternalsConfigPath + name.ToFileName() + ".pobj";

            if (File.Exists(path))
            {
                return;
            }

            TextWriter tw = new StreamWriter(path);

            tw.WriteLine("externaltype = " + (staticImport ? "static" : "selection"));
            tw.WriteLine("name = " + name);
            foreach (KeyValuePair <CacheProceduralObject, Vector3> kvp in selection_objects)
            {
                tw.WriteLine("OBJECT");
                tw.WriteLine("{");
                tw.WriteLine("baseInfoType = " + kvp.Key.baseInfoType);
                tw.WriteLine("basePrefabName = " + kvp.Key.basePrefabName);
                if (staticImport)
                {
                    tw.WriteLine("absPosition = " + kvp.Key._staticPos.ToStringUnrounded());
                }
                else
                {
                    tw.WriteLine("relativePosition = " + kvp.Value.ToStringUnrounded());
                }
                tw.WriteLine("isPloppableAsphalt = " + kvp.Key.isPloppableAsphalt.ToString());
                //  tw.WriteLine("scale = " + pobj.scale.ToString());
                tw.WriteLine("parenting = " + kvp.Key.temp_id + ";" + kvp.Key.parent);
                tw.WriteLine("customTexture = " + ((kvp.Key.customTexture == null) ? "null" : kvp.Key.customTexture.name));
                tw.WriteLine("renderDistance = " + kvp.Key.renderDistance.ToString());
                tw.WriteLine("renderDistLocked = " + kvp.Key.renderDistLocked.ToString());
                tw.WriteLine("rotation = " + kvp.Key.m_rotation.ToStringUnrounded());
                tw.WriteLine("disableRecalculation = " + kvp.Key.disableRecalculation.ToString());
                if (kvp.Key.tilingFactor != 8)
                {
                    tw.WriteLine("tilingFactor = " + kvp.Key.tilingFactor.ToString());
                }
                tw.WriteLine("color = " + ((SerializableColor)kvp.Key.m_color).ToString());
                tw.WriteLine("flipFaces = " + kvp.Key.flipFaces.ToString());
                tw.WriteLine("disableCastShadows = " + kvp.Key.disableCastShadows.ToString());
                tw.WriteLine("normalsRecalc = " + kvp.Key.normalsRecalculation.ToString());
                tw.WriteLine("visibility = " + kvp.Key.visibility.ToString());
                if (kvp.Key.textParam != null)
                {
                    if (kvp.Key.textParam.Count() > 0)
                    {
                        foreach (TextField field in kvp.Key.textParam.m_textFields)
                        {
                            tw.WriteLine(TextField.SaveString(field));
                        }
                    }
                }
                if (kvp.Key.modules != null)
                {
                    if (kvp.Key.modules.Count > 0)
                    {
                        ModuleManager.WriteModules(tw, kvp.Key.modules, false);
                    }
                }
                if (kvp.Key.meshStatus == 1)
                {
                    tw.WriteLine("ORIGINALMODEL");
                }
                else
                {
                    tw.WriteLine("VERTICES " + kvp.Key.allVertices.Count());
                    for (int i = 0; i < kvp.Key.allVertices.Count(); i++)
                    {
                        tw.WriteLine("vertex " + i.ToString() + " = " + kvp.Key.allVertices[i].ToStringUnrounded());
                    }
                }
                tw.WriteLine("}");
            }
            tw.Close();

            ProceduralUtils.ExportRequiredAssetsHTML(ProceduralObjectsMod.ExternalsConfigPath + name.ToFileName() + " - required assets.html", selection_objects.Keys.ToList());
        }