Beispiel #1
0
    /// <summary>
    /// Recalculate peak to make ground flat
    /// </summary>
    /// <param name="groundMesh">GroundMesh</param>
    protected void RecalculatePeak(GroundMesh groundMesh, Vector3 origin)
    {
        int nbVertex = groundMesh.computedVertex.Length;

        Vector3[] planPoints = new Vector3[3];
        int       ite        = 0;

        for (int i = 0; i < nbVertex; i++)
        {
            if (groundMesh.computedVertex[i] != groundMesh.centerPosition)
            {
                planPoints[ite] = groundMesh.computedVertex[i];
                ite++;
                if (ite >= 3)
                {
                    break;
                }
            }
        }

        Vector4 groundPlan        = MathCustom.GetPlaneValues(planPoints[0], planPoints[1], planPoints[2]);
        Vector3 newCenterPosition = MathCustom.LineCutPlaneCoordinates(origin, groundMesh.centerPosition * int.MaxValue, groundPlan);

        for (int i = 0; i < nbVertex; i++)
        {
            if (groundMesh.computedVertex[i] == groundMesh.centerPosition)
            {
                groundMesh.centerPosition    = newCenterPosition;
                groundMesh.computedVertex[i] = newCenterPosition;
            }
        }
    }
Beispiel #2
0
    private void MakeGroundMesh()
    {
        Vector3    startPos = new Vector3(-0.5f * CellSide, 0, -0.5f * CellSide);
        GroundMesh mesh     = new GroundMesh(startPos, Length, Width, xVertices, zVertices, Seed);

        groundMesh.mesh.vertices  = mesh.Vertices;
        groundMesh.mesh.triangles = mesh.Triangles;
        groundMesh.mesh.RecalculateNormals();
        GetComponent <MeshCollider>().sharedMesh = groundMesh.mesh;
    }
Beispiel #3
0
        /// <summary>
        /// Apply a new cell state
        /// </summary>
        /// <param name="groundMesh"></param>
        /// <param name="state"></param>
        public void SetCellState(GroundMesh groundMesh, CellState state)
        {
            _state = state;
            InitColor();
            int length = groundMesh.smoothVertex.Length;

            for (int i = 0; i < length; i++)
            {
                SetVertexColors();
            }
        }
Beispiel #4
0
    /// <summary>
    /// Create the GameObject and the mesh of a DatagroundList
    /// </summary>
    /// <param name="groundMeshs">DataGround list</param>
    protected void CreateGroundMesh(List <DataGround> groundMeshs)
    {
        Vector3 origin = gameObject.transform.position;
        int     index  = 0;

        foreach (DataGround ground in groundMeshs)
        {
            GroundMesh newGround = TrianglesToGroundMesh(ground);
            DualTransformation(newGround);
            RecalculatePeak(newGround, origin);
            allGroundMesh.Add(newGround);
            index++;
        }
    }
Beispiel #5
0
    /// <summary>
    /// Convert a GroundMesh from a DataGround
    /// </summary>
    /// <param name="dataMesh">Dataground</param>
    /// <returns></returns>
    protected GroundMesh TrianglesToGroundMesh(DataGround dataMesh)
    {
        int        nbTriangle = dataMesh.triangles.Length;
        GroundMesh groundMesh = new GroundMesh(nbTriangle * 3, nbTriangle + 1, dataMesh.center);

        groundMesh.refTriangles = dataMesh.triangles;

        int[]     lTriangles = new int[groundMesh.triangles.Length];
        Vector3[] lVertex    = new Vector3[nbTriangle + 1];
        Vector3[] lNormals   = new Vector3[nbTriangle + 1];
        Vector2[] lUvs       = new Vector2[nbTriangle + 1];

        int ite = 0;

        for (int i = 0; i < nbTriangle; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                int index = CustomGeneric.ArrayContain(lVertex, refVertices[dataMesh.triangles[i].verticesindex[j]]);
                if (index < 0)
                {
                    lVertex[ite]  = refVertices[dataMesh.triangles[i].verticesindex[j]];
                    lNormals[ite] = refNormals[dataMesh.triangles[i].verticesindex[j]];
                    ite++;
                }
            }
        }

        for (int i = 0; i < nbTriangle; i++)
        {
            Vector3 center = groundMesh.centerPosition;
            for (int j = 0; j < 3; j++)
            {
                lTriangles[i * 3 + j] = CustomGeneric.ArrayContain(lVertex, refVertices[dataMesh.triangles[i].verticesindex[j]]);
            }
        }

        groundMesh.vertex    = lVertex;
        groundMesh.normals   = lNormals;
        groundMesh.triangles = lTriangles;

        return(groundMesh);
    }
Beispiel #6
0
 /// <summary>
 /// First init
 /// </summary>
 public void Init(GroundMesh meshObject)
 {
     meshObject.centerIndex = CustomGeneric.ArrayContain(meshObject.smoothVertex, meshObject.centerPosition);
     _indexes             = meshObject.indexes;
     _stateHealth         = 1;
     _walkable            = true;
     _elevation           = 1f;
     _isElevating         = false;
     _neighborElevationID = -1;
     _groundMesh          = meshObject;
     _poluted             = false;
     _deforested          = false;
     _axis              = GetCenterPosition();
     _personnalMesh     = GetComponent <MeshFilter>().mesh;
     _personnalCollider = GetComponents <MeshCollider>();
     _state             = CellState.MOSS;
     UpdateHeight(0);
     InitColor();
 }
Beispiel #7
0
    /// <summary>
    /// Generate UV mapping
    /// </summary>
    /// <param name="groundMesh"></param>
    protected void GenerateTextureMap(GroundMesh groundMesh)
    {
        Vector3 cross    = Vector3.Cross(Vector3.up, groundMesh.centerPosition);
        Vector3 py       = groundMesh.centerPosition + cross;
        Vector3 pz       = groundMesh.centerPosition + Vector3.Cross(cross, groundMesh.centerPosition);
        Vector4 cellPlan = MathCustom.GetPlaneValues(groundMesh.centerPosition, py, pz);

        for (int i = 0; i < groundMesh.smoothVertex.Length; i++)
        {
            Vector3 vertex = groundMesh.smoothVertex[i];
            if (vertex == groundMesh.centerPosition)
            {
                groundMesh.UVs[i] = new Vector2(0.5f, 0.5f);
            }
            else
            {
                Vector3 planeCoord   = MathCustom.LineCutPlaneCoordinates(Vector3.zero, vertex, cellPlan);
                Vector3 cartesianPos = Quaternion.FromToRotation(groundMesh.centerPosition, Vector3.up) * planeCoord;
                float   lRadius;
                float   lPolar;
                float   lElevation;
                MathCustom.CartesianToSpherical(cartesianPos, out lRadius, out lPolar, out lElevation);
                float xAngle = Vector3.SignedAngle(groundMesh.centerPosition, vertex, groundMesh.centerPosition);
                float yAngle = Vector3.SignedAngle(Vector3.Cross(groundMesh.centerPosition, -Vector3.up), vertex, groundMesh.centerPosition);

                if (CustomGeneric.IntArrayContain(groundMesh.indexes.internVertexIndex, i) != -1)
                {
                    groundMesh.UVs[i] = new Vector2(0.5f + (Mathf.Cos(lPolar) * 0.9f), 0.5f + (Mathf.Sin(lPolar) * 0.9f));
                }
                else
                {
                    groundMesh.UVs[i] = new Vector2(0.5f + Mathf.Cos(lPolar), 0.5f + Mathf.Sin(lPolar));
                }
            }
        }
    }
Beispiel #8
0
        /// <summary>
        /// Return a list containing the internvertex linked to an edgevertex
        /// </summary>
        /// <param name="groundMesh"></param>
        /// <param name="edgeIndex"></param>
        /// <returns></returns>
        public static List <int> GetLinkedInternVertexIndexes(GroundMesh groundMesh, int edgeIndex)
        {
            int        nbTriangle         = groundMesh.smoothTriangles.Length / 3;
            List <int> linkedInternVertex = new List <int>();

            for (int i = 0; i < nbTriangle; i++)
            {
                Vector3 v1 = groundMesh.smoothVertex[groundMesh.smoothTriangles[i * 3]];
                Vector3 v2 = groundMesh.smoothVertex[groundMesh.smoothTriangles[i * 3 + 1]];
                Vector3 v3 = groundMesh.smoothVertex[groundMesh.smoothTriangles[i * 3 + 2]];

                if (v1 == groundMesh.smoothVertex[edgeIndex] || v2 == groundMesh.smoothVertex[edgeIndex] || v3 == groundMesh.smoothVertex[edgeIndex])
                {
                    foreach (int finternIndex in groundMesh.indexes.internVertexIndex)
                    {
                        if (groundMesh.smoothVertex[finternIndex] == v1 || groundMesh.smoothVertex[finternIndex] == v2 || groundMesh.smoothVertex[finternIndex] == v3)
                        {
                            linkedInternVertex.Add(finternIndex);
                        }
                    }
                }
            }
            return(linkedInternVertex);
        }
Beispiel #9
0
    /// <summary>
    /// Get the dual transformation of a GroundMesh
    /// </summary>
    /// <param name="groundMesh">GroundMesh</param>
    protected void DualTransformation(GroundMesh groundMesh)
    {
        Vector3[] computedVertices = new Vector3[groundMesh.computedVertex.Length];
        Vector3[] computedNormals  = new Vector3[groundMesh.computedVertex.Length];

        for (int i = 0; i < groundMesh.triangles.Length / 3; i++)
        {
            Vector3 addVector = Vector3.zero + groundMesh.centerPosition;
            if (groundMesh.vertex[groundMesh.triangles[i * 3]] != groundMesh.centerPosition)
            {
                addVector += groundMesh.vertex[groundMesh.triangles[i * 3]];
            }
            if (groundMesh.vertex[groundMesh.triangles[i * 3 + 1]] != groundMesh.centerPosition)
            {
                addVector += groundMesh.vertex[groundMesh.triangles[i * 3 + 1]];
            }
            if (groundMesh.vertex[groundMesh.triangles[i * 3 + 2]] != groundMesh.centerPosition)
            {
                addVector += groundMesh.vertex[groundMesh.triangles[i * 3 + 2]];
            }

            computedVertices[i] = addVector.normalized * radius;
            computedNormals[i]  = computedVertices[i].normalized;
        }

        computedVertices[computedVertices.Length - 2] = Vector3.zero;
        computedNormals[computedNormals.Length - 2]   = -groundMesh.centerPosition.normalized;

        computedVertices[computedVertices.Length - 1] = groundMesh.centerPosition;
        computedNormals[computedNormals.Length - 1]   = groundMesh.centerPosition.normalized;

        groundMesh.computedVertex  = computedVertices;
        groundMesh.computedNormals = computedNormals;

        // Creation of the dual triangles array

        int nbTriangle = groundMesh.triangles.Length / 3;

        VertexCouple[] couples = new VertexCouple[nbTriangle];

        for (int i = 0; i < nbTriangle; i++)
        {
            couples[i] = new VertexCouple(Vector3.zero, Vector3.zero);
        }

        int ite = 0;

        for (int j = 0; j < groundMesh.computedVertex.Length; j++)
        {
            for (int k = 0; k < groundMesh.computedVertex.Length; k++)
            {
                if (groundMesh.computedVertex[j] != groundMesh.centerPosition &&
                    groundMesh.computedVertex[k] != groundMesh.centerPosition &&
                    groundMesh.computedVertex[j] != Vector3.zero &&
                    groundMesh.computedVertex[k] != Vector3.zero)
                {
                    float angle = Vector3.Angle(groundMesh.centerPosition - groundMesh.computedVertex[j], groundMesh.centerPosition - groundMesh.computedVertex[k]);
                    if (angle > 2 && angle < 70)
                    {
                        VertexCouple newCouple = new VertexCouple(groundMesh.computedVertex[j], groundMesh.computedVertex[k]);
                        if (!CoupleExist(couples, newCouple))
                        {
                            couples[ite] = newCouple;
                            ite++;
                        }
                    }
                }
            }
        }

        int[] lTriangles = new int[groundMesh.triangles.Length * 2];
        for (int i = 0; i < couples.Length; i++)
        {
            Vector3 surfaceNormal = Vector3.Cross(groundMesh.centerPosition + couples[i].vertices[0], groundMesh.centerPosition + couples[i].vertices[1]);
            float   angle         = Vector3.Angle(gameObject.transform.position + groundMesh.centerPosition, surfaceNormal);

            if (angle < 90)
            {
                lTriangles[i * 3]     = ArrayContain(groundMesh.computedVertex, groundMesh.centerPosition);
                lTriangles[i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
                lTriangles[i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
            }
            else
            {
                lTriangles[i * 3]     = ArrayContain(groundMesh.computedVertex, groundMesh.centerPosition);
                lTriangles[i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
                lTriangles[i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
            }

            Vector4 face = MathCustom.GetPlaneValues(Vector3.zero, couples[i].vertices[1], couples[i].vertices[0]);
            if (MathCustom.GetDistanceToPlane(groundMesh.centerPosition, face) > 0)
            {
                lTriangles[groundMesh.triangles.Length + i * 3]     = ArrayContain(groundMesh.computedVertex, Vector3.zero);
                lTriangles[groundMesh.triangles.Length + i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
                lTriangles[groundMesh.triangles.Length + i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
            }
            else
            {
                lTriangles[groundMesh.triangles.Length + i * 3]     = ArrayContain(groundMesh.computedVertex, Vector3.zero);
                lTriangles[groundMesh.triangles.Length + i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
                lTriangles[groundMesh.triangles.Length + i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
            }
        }

        groundMesh.computedTriangles = lTriangles;
    }
Beispiel #10
0
        private void Update()
        {
            if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1))
            {
                GameManager.Instance.Map.CommandManager.FinishAction();
            }

            RaycastHit raycast = LayoutManager.Instance.CurrentCamera.CurrentRaycast;

            if (!raycast.transform)
            {
                return;
            }

            OverlayMesh overlayMesh = raycast.transform.GetComponent <OverlayMesh>();
            GroundMesh  groundMesh  = raycast.transform.GetComponent <GroundMesh>();
            TileEntity  tileEntity  = raycast.transform.GetComponent <TileEntity>();
            Wall        wallEntity  = tileEntity as Wall;

            bool automaticReverse = automaticReverseToggle.isOn;
            bool reverse          = reverseToggle.isOn;
            int  floor            = 0;
            int  x          = -1;
            int  y          = -1;
            bool horizontal = false;

            bool propertiesNeedSaving = false;

            if (automaticReverse != Properties.Instance.WallAutomaticReverse)
            {
                Properties.Instance.WallAutomaticReverse = automaticReverse;
                propertiesNeedSaving = true;
            }
            if (reverse != Properties.Instance.WallReverse)
            {
                Properties.Instance.WallReverse = reverse;
                propertiesNeedSaving            = true;
            }

            if (propertiesNeedSaving)
            {
                Properties.Instance.SaveProperties();
            }

            if (wallEntity && wallEntity.Valid)
            {
                floor = tileEntity.Floor;
                if (LayoutManager.Instance.CurrentCamera.Floor == floor + 1)
                {
                    floor++;
                }
                x = tileEntity.Tile.X;
                y = tileEntity.Tile.Y;
                EntityType type = tileEntity.Type;
                horizontal = (type == EntityType.Hwall || type == EntityType.Hfence);
            }
            else if (overlayMesh || groundMesh)
            {
                if (overlayMesh)
                {
                    floor = LayoutManager.Instance.CurrentCamera.Floor;
                }
                else if (groundMesh)
                {
                    floor = 0;
                }
                TileSelectionHit    tileSelectionHit = TileSelection.PositionToTileSelectionHit(raycast.point, TileSelectionMode.Borders);
                TileSelectionTarget target           = tileSelectionHit.Target;
                if (target == TileSelectionTarget.Nothing)
                {
                    return;
                }
                x          = tileSelectionHit.X;
                y          = tileSelectionHit.Y;
                horizontal = (target == TileSelectionTarget.BottomBorder);
            }

            if (Input.GetMouseButton(0))
            {
                Floor currentFloor  = GameManager.Instance.Map[x, y].GetTileContent(floor) as Floor;
                bool  shouldReverse = false;
                if (automaticReverse && horizontal)
                {
                    Floor nearFloor = GameManager.Instance.Map[x, y - 1].GetTileContent(floor) as Floor;
                    shouldReverse = currentFloor && !nearFloor;
                }
                else if (automaticReverse && !horizontal)
                {
                    Floor nearFloor = GameManager.Instance.Map[x - 1, y].GetTileContent(floor) as Floor;
                    shouldReverse = !currentFloor && nearFloor;
                }

                if (reverse)
                {
                    shouldReverse = !shouldReverse;
                }

                WallData data = GuiManager.Instance.WallsTree.SelectedValue as WallData;
                if (horizontal)
                {
                    GameManager.Instance.Map[x, y].SetHorizontalWall(data, shouldReverse, floor);
                }
                else
                {
                    GameManager.Instance.Map[x, y].SetVerticalWall(data, shouldReverse, floor);
                }
            }
            else if (Input.GetMouseButton(1))
            {
                if (floor != LayoutManager.Instance.CurrentCamera.Floor)
                {
                    return;
                }
                if (horizontal)
                {
                    GameManager.Instance.Map[x, y].SetHorizontalWall(null, false, floor);
                }
                else
                {
                    GameManager.Instance.Map[x, y].SetVerticalWall(null, false, floor);
                }
            }
        }
Beispiel #11
0
    /// <summary>
    /// Cut the mesh to create a smoothable cell
    /// </summary>
    /// <param name="groundMesh">GroundMesh</param>
    protected void PrepareMeshForSmooth(GroundMesh groundMesh)
    {
        Vector3[] internVertex  = new Vector3[2];
        Vector3   midEdgeVertex = Vector3.zero;

        Vector3[] edgeVertex = new Vector3[2];

        Vector3[] smoothVertex = new Vector3[(groundMesh.triangles.Length * 4) + groundMesh.triangles.Length];
        int       iterator     = 0;

        for (int i = 0; i < groundMesh.computedTriangles.Length / 3; i++)
        {
            if (groundMesh.computedVertex[groundMesh.computedTriangles[i * 3]] == Vector3.zero)
            {
                continue;
            }

            Vector3 ver1 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 1]];
            Vector3 ver2 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 2]];
            internVertex[0] = (groundMesh.centerPosition + ver1) / 2f;
            internVertex[1] = (groundMesh.centerPosition + ver2) / 2f;

            Vector3 vDir1 = (internVertex[0] - groundMesh.centerPosition);
            Vector3 vDir2 = (internVertex[1] - groundMesh.centerPosition);
            internVertex[0] = internVertex[0] + (vDir1 * CellWidth);
            internVertex[1] = internVertex[1] + (vDir2 * CellWidth);

            float d = Vector3.Distance(internVertex[0], internVertex[1]) / 2f;
            midEdgeVertex = (ver1 + ver2) / 2f;
            edgeVertex[0] = midEdgeVertex + (midEdgeVertex - ver1).normalized * d;
            edgeVertex[1] = midEdgeVertex + (midEdgeVertex - ver2).normalized * d;

            for (int j = 0; j < 5; j++)
            {
                switch (j)
                {
                case 0:
                    smoothVertex[iterator * 3]       = groundMesh.centerPosition;
                    smoothVertex[(iterator * 3) + 1] = internVertex[0];
                    smoothVertex[(iterator * 3) + 2] = internVertex[1];
                    break;

                case 1:
                    smoothVertex[iterator * 3] = internVertex[0];
                    if (Vector3.Distance(ver1, internVertex[0]) > Vector3.Distance(ver2, internVertex[0]))
                    {
                        smoothVertex[iterator * 3 + 1] = ver2;
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 1] = ver1;
                    }
                    if (Vector3.Distance(edgeVertex[0], internVertex[0]) > Vector3.Distance(edgeVertex[1], internVertex[0]))
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[1];
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[0];
                    }
                    break;

                case 2:
                    smoothVertex[iterator * 3] = internVertex[1];
                    if (Vector3.Distance(edgeVertex[0], internVertex[1]) > Vector3.Distance(edgeVertex[1], internVertex[1]))
                    {
                        smoothVertex[iterator * 3 + 1] = edgeVertex[1];
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 1] = edgeVertex[0];
                    }
                    if (Vector3.Distance(ver1, internVertex[1]) > Vector3.Distance(ver2, internVertex[1]))
                    {
                        smoothVertex[iterator * 3 + 2] = ver2;
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 2] = ver1;
                    }
                    break;

                case 3:
                    smoothVertex[iterator * 3]     = internVertex[1];
                    smoothVertex[iterator * 3 + 1] = internVertex[0];
                    if (Vector3.Distance(edgeVertex[0], internVertex[1]) > Vector3.Distance(edgeVertex[1], internVertex[1]))
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[1];
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[0];
                    }
                    break;

                case 4:
                    smoothVertex[iterator * 3]     = internVertex[0];
                    smoothVertex[iterator * 3 + 1] = edgeVertex[1];
                    smoothVertex[iterator * 3 + 2] = edgeVertex[0];
                    break;
                }

                iterator++;
            }
        }

        iterator = 0;
        int coordNumber = smoothVertex.Length;

        for (int i = 0; i < coordNumber; i++)
        {
            int found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, smoothVertex[i]);
            if (found == -1)
            {
                groundMesh.smoothVertex[iterator]  = smoothVertex[i];
                groundMesh.smoothNormals[iterator] = smoothVertex[i].normalized;
                groundMesh.smoothTriangles[i]      = CustomGeneric.ArrayContain(groundMesh.smoothVertex, smoothVertex[i]);
                iterator++;
            }
            else
            {
                groundMesh.smoothTriangles[i] = found;
            }
        }

        for (int i = 0; i < groundMesh.computedTriangles.Length / 3; i++)
        {
            if (groundMesh.computedVertex[groundMesh.computedTriangles[i * 3]] == Vector3.zero)
            {
                continue;
            }

            Vector3 ver1 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 1]];
            Vector3 ver2 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 2]];
            internVertex[0] = (groundMesh.centerPosition + ver1) / 2f;
            internVertex[1] = (groundMesh.centerPosition + ver2) / 2f;

            Vector3 vDir1 = (internVertex[0] - groundMesh.centerPosition);
            Vector3 vDir2 = (internVertex[1] - groundMesh.centerPosition);
            internVertex[0] = internVertex[0] + (vDir1 * CellWidth);
            internVertex[1] = internVertex[1] + (vDir2 * CellWidth);

            float d = Vector3.Distance(internVertex[0], internVertex[1]) / 2f;
            midEdgeVertex = (ver1 + ver2) / 2f;
            edgeVertex[0] = midEdgeVertex + (midEdgeVertex - ver1).normalized * d;
            edgeVertex[1] = midEdgeVertex + (midEdgeVertex - ver2).normalized * d;

            int found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, edgeVertex[0]);
            if (found != -1)
            {
                groundMesh.indexes.edgeVertexIndex[i * 2] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, edgeVertex[1]);
            if (found != -1)
            {
                groundMesh.indexes.edgeVertexIndex[i * 2 + 1] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, ver1);
            if (found != -1)
            {
                groundMesh.indexes.cornerVertexIndex[i] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, ver2);
            if (found != -1)
            {
                groundMesh.indexes.cornerVertexIndex[i] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, internVertex[0]);
            if (found != -1)
            {
                groundMesh.indexes.internVertexIndex[i] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, internVertex[1]);
            if (found != -1)
            {
                groundMesh.indexes.internVertexIndex[i] = found;
            }
        }
    }
Beispiel #12
0
        /// <summary>
        /// Get all the typed vertex link to a vertex
        /// </summary>
        /// <param name="indexArray">custom vertex type array</param>
        /// <param name="testPos"></param>
        /// <returns></returns>
        public static Vector3 GetNearestTypedVertex(int[] indexArray, Vector3 testPos, GroundMesh pGroundMesh)
        {
            Vector3 nearest = Vector3.zero;
            float   dist    = float.PositiveInfinity;

            foreach (int index in indexArray)
            {
                Vector3 vertex = pGroundMesh.smoothVertex[index];
                if (vertex != pGroundMesh.centerPosition)
                {
                    float lDist = Math.Abs(Vector3.Distance(testPos, vertex));
                    if (lDist < dist)
                    {
                        nearest = vertex;
                        dist    = lDist;
                    }
                }
            }
            return(nearest);
        }
        private void Update()
        {
            bool  snapToGrid              = snapToGridToggle.isOn;
            bool  rotationSnapping        = rotationSnappingToggle.isOn;
            float rotationEditSensitivity = 1;

            float.TryParse(rotationSensitivityInput.text, NumberStyles.Any, CultureInfo.InvariantCulture, out rotationEditSensitivity);

            bool propertiesNeedSaving = false;

            if (Math.Abs(rotationEditSensitivity - Properties.Instance.DecorationRotationSensitivity) > float.Epsilon)
            {
                Properties.Instance.DecorationRotationSensitivity = rotationEditSensitivity;
                propertiesNeedSaving = true;
            }
            if (snapToGrid != Properties.Instance.DecorationSnapToGrid)
            {
                Properties.Instance.DecorationSnapToGrid = snapToGrid;
                propertiesNeedSaving = true;
            }
            if (rotationSnapping != Properties.Instance.DecorationRotationSnapping)
            {
                Properties.Instance.DecorationRotationSnapping = rotationSnapping;
                propertiesNeedSaving = true;
            }

            if (propertiesNeedSaving)
            {
                Properties.Instance.SaveProperties();
            }

            RaycastHit raycast = LayoutManager.Instance.CurrentCamera.CurrentRaycast;

            if (!raycast.transform)
            {
                if (ghostObject)
                {
                    ghostObject.SetActive(false);
                }
                return;
            }

            DecorationData data        = (DecorationData)GuiManager.Instance.ObjectsTree.SelectedValue;
            bool           dataChanged = data != lastFrameData;

            lastFrameData = data;
            if (!data)
            {
                return;
            }

            OverlayMesh overlayMesh = raycast.transform.GetComponent <OverlayMesh>();
            GroundMesh  groundMesh  = raycast.transform.GetComponent <GroundMesh>();
            TileEntity  tileEntity  = raycast.transform.GetComponent <TileEntity>();

            Material ghostMaterial = GraphicsManager.Instance.GhostMaterial;

            if (dataChanged)
            {
                CoroutineManager.Instance.QueueCoroutine(data.Model.CreateOrGetModel(ghostMaterial, OnGhostCreated));
                return;
            }

            if (!ghostObject)
            {
                return;
            }

            int targetFloor = LayoutManager.Instance.CurrentCamera.Floor;

            if (tileEntity && tileEntity.Valid && tileEntity.GetType() == typeof(Floor))
            {
                targetFloor = tileEntity.Floor;
            }

            if (data.CenterOnly || data.Tree || data.Bush)
            {
                targetFloor = 0;
            }

            Map map = GameManager.Instance.Map;

            if (!placingDecoration)
            {
                position     = CalculateCorrectedPosition(raycast.point, data, snapToGrid);
                targetedTile = null;
                if (overlayMesh)
                {
                    int tileX = Mathf.FloorToInt(position.x / 4f);
                    int tileY = Mathf.FloorToInt(position.z / 4f);
                    targetedTile = map[tileX, tileY];
                    position.y   = map.GetInterpolatedHeight(position.x, position.z);
                    if (data.Floating)
                    {
                        position.y = Mathf.Max(position.y, 0);
                    }
                    else
                    {
                        float floorHeight = 3f;
                        position.y += targetFloor * floorHeight;
                    }
                }
                else if (tileEntity && tileEntity.Valid)
                {
                    targetedTile = tileEntity.Tile;
                }
            }

            bool canPlaceNewObject = overlayMesh || groundMesh || (tileEntity && tileEntity.Valid && tileEntity.GetType() == typeof(Floor));

            if (canPlaceNewObject || placingDecoration)
            {
                ghostObject.gameObject.SetActive(true);
                ghostObject.transform.position = position;
            }
            else
            {
                ghostObject.gameObject.SetActive(false);
            }

            bool    placementAllowed = true;
            Vector2 position2d       = new Vector2(position.x, position.z);
            IEnumerable <Decoration> nearbyDecorations = GetAllNearbyDecorations(targetedTile);

            foreach (Decoration decoration in nearbyDecorations)
            {
                Vector3 decorationPosition3d = decoration.transform.position;
                Vector2 decorationPosition2d = new Vector2(decorationPosition3d.x, decorationPosition3d.z);
                float   distance             = Vector2.Distance(position2d, decorationPosition2d);
                if (distance < minimumPlacementGap)
                {
                    placementAllowed = false;
                    break;
                }
            }

            ToggleGhostPropertyBlock(placementAllowed ? allowedGhostPropertyBlock : disabledGhostPropertyBlock);

            if (Input.GetMouseButtonDown(0) && placementAllowed)
            {
                placingDecoration = true;
                dragStartPos      = LayoutManager.Instance.CurrentCamera.MousePosition;
            }

            if (Input.GetMouseButton(0) && placingDecoration)
            {
                Vector2 dragEndPos = LayoutManager.Instance.CurrentCamera.MousePosition;
                Vector2 difference = dragEndPos - dragStartPos;
                rotation = -difference.x * rotationEditSensitivity;
                if (rotationSnapping)
                {
                    rotation = Mathf.Round(rotation / 45f) * 45f;
                }
                ghostObject.transform.localRotation = Quaternion.Euler(0, rotation, 0);
            }

            if (Input.GetMouseButtonUp(0) && placingDecoration)
            {
                float   decorationPositionX = position.x - targetedTile.X * 4f;
                float   decorationPositionY = position.z - targetedTile.Y * 4f;
                Vector2 decorationPosition  = new Vector2(decorationPositionX, decorationPositionY);
                targetedTile.SetDecoration(data, decorationPosition, rotation * Mathf.Deg2Rad, targetFloor, data.Floating);
                map.CommandManager.FinishAction();

                placingDecoration = false;
                ghostObject.transform.localRotation = Quaternion.identity;
            }

            if (Input.GetMouseButtonDown(1))
            {
                placingDecoration = false;
                ghostObject.transform.localRotation = Quaternion.identity;
            }

            if (Input.GetMouseButtonDown(1) && !placingDecoration)
            {
                IEnumerable <Decoration> decorationsOnTile = targetedTile.GetDecorations();
                foreach (Decoration decoration in decorationsOnTile)
                {
                    targetedTile.SetDecoration(null, decoration.Position, decoration.Rotation, targetFloor);
                }
                map.CommandManager.FinishAction();
            }
        }