public Dictionary <int, TerrainWeldUvs> Process(WeldRegenerationOrder order)
        {
            int biggerTerrainIndex = order.GetBiggerTerrainIndex();
            var biggerTerrain      = order.GetTerrainOfIndex(biggerTerrainIndex);

            var         biggerTerrainId   = biggerTerrain.Terrain.WeldingInputTerrainId;
            TerrainSide biggerTerrainSide = new TerrainSide()
            {
                SideType  = biggerTerrain.SideType,
                TerrainId = biggerTerrainId
            };

            var outWeldModificationsDict = new Dictionary <int, TerrainWeldUvs>();

            if (!_terrainSideToStripPositions.ContainsKey(biggerTerrainSide))
            {
                var registrationResult =
                    _level2Manager.RegisterStrip(CreateStripSide(biggerTerrain, new Vector2(0, 1)));

                outWeldModificationsDict[biggerTerrainId]       = registrationResult.WeldUvs;
                _terrainSideToStripPositions[biggerTerrainSide] = registrationResult.StripPosition;
            }

            var weldPosition = _terrainSideToStripPositions[biggerTerrainSide];

            var smallerTerrain = order.GetTerrainOfIndex(1 - biggerTerrainIndex);
            var smallerSide    = new TerrainSide()
            {
                SideType  = smallerTerrain.SideType,
                TerrainId = smallerTerrain.Terrain.WeldingInputTerrainId
            };

            _followerStripPositions[smallerSide] = weldPosition;

            var followerSide = CreateStripSide(smallerTerrain,
                                               CalculateFollowerMarginUv(biggerTerrain, smallerTerrain));
            var followerWeldUv = _level2Manager.AddStipSegment(weldPosition, followerSide);

            outWeldModificationsDict[smallerTerrain.Terrain.WeldingInputTerrainId] = followerWeldUv;
            return(outWeldModificationsDict);
        }
Example #2
0
        // TODO SIMPLIFY CODE
        private void BuildTerrainMesh(TerrainSide side)
        {
            int  index = (int)side;
            Mesh mesh  = _meshFilters[index].sharedMesh;

            Vector3[] vertices;
            int[]     triangles;
            int       triIndex = 0;

            int i;

            switch (side)
            {
            case TerrainSide.Top:
                vertices  = new Vector3[resolution * resolution];
                triangles = new int[(resolution - 1) * (resolution - 1) * 6];

                for (int y = 0; y < resolution; y++)
                {
                    for (int x = 0; x < resolution; x++)
                    {
                        i = x + y * resolution;
                        Vector2 percent = new Vector2(x, y) / (resolution - 1);
                        Vector3 point   = new Vector3((percent.x - .5f) * TerrainGrid.Width,
                                                      0f,
                                                      -(percent.y - .5f) * TerrainGrid.Height);
                        point.y     = CalculateHeight(point);
                        vertices[i] = point;

                        if (x != resolution - 1 && y != resolution - 1)
                        {
                            triangles[triIndex]     = i;
                            triangles[triIndex + 1] = i + resolution + 1;
                            triangles[triIndex + 2] = i + resolution;

                            triangles[triIndex + 3] = i;
                            triangles[triIndex + 4] = i + 1;
                            triangles[triIndex + 5] = i + resolution + 1;
                            triIndex += 6;
                        }
                    }
                }

                break;

            case TerrainSide.Bottom:
                vertices  = new Vector3[resolution * resolution];
                triangles = new int[(resolution - 1) * (resolution - 1) * 6];

                for (int y = 0; y < resolution; y++)
                {
                    for (int x = 0; x < resolution; x++)
                    {
                        i = x + y * resolution;
                        Vector2 percent = new Vector2(x, y) / (resolution - 1);
                        Vector3 point   = new Vector3((percent.x - .5f) * TerrainGrid.Width,
                                                      -1f,
                                                      -(percent.y - .5f) * TerrainGrid.Height);
                        vertices[i] = point;

                        if (x != resolution - 1 && y != resolution - 1)
                        {
                            triangles[triIndex]     = i + resolution;
                            triangles[triIndex + 1] = i + resolution + 1;
                            triangles[triIndex + 2] = i;

                            triangles[triIndex + 3] = i + resolution + 1;
                            triangles[triIndex + 4] = i + 1;
                            triangles[triIndex + 5] = i;
                            triIndex += 6;
                        }
                    }
                }

                break;

            default:
                vertices  = new Vector3[resolution * 2];
                triangles = new int[(resolution - 1) * 6];
                float semiWidth  = terrainOptions.width / 2f;
                float semiHeight = terrainOptions.height / 2f;
                i = 0;

                switch (side)
                {
                case TerrainSide.Back:
                    for (int x = 0; x < resolution; x++)
                    {
                        for (int y = -1; y <= 0; y++)
                        {
                            float scaledX = (x / (resolution - 1f) - 0.5f) * TerrainGrid.Width;
                            vertices[i] = new Vector3(scaledX, y, semiWidth);
                            if (vertices[i].y > -1f)
                            {
                                vertices[i].y = CalculateHeight(vertices[i]);
                            }

                            if (x != resolution - 1 && y != 0)
                            {
                                triangles[triIndex]     = i;
                                triangles[triIndex + 1] = i + 2;
                                triangles[triIndex + 2] = i + 1;

                                triangles[triIndex + 3] = i + 1;
                                triangles[triIndex + 4] = i + 2;
                                triangles[triIndex + 5] = i + 3;
                                triIndex += 6;
                            }

                            i++;
                        }
                    }

                    break;

                case TerrainSide.Front:
                    for (int x = 0; x < resolution; x++)
                    {
                        for (int y = -1; y <= 0; y++)
                        {
                            float scaledX = (x / (resolution - 1f) - 0.5f) * TerrainGrid.Width;
                            vertices[i] = new Vector3(scaledX, y, -semiWidth);
                            if (vertices[i].y > -1f)
                            {
                                vertices[i].y = CalculateHeight(vertices[i]);
                            }

                            if (x != resolution - 1 && y != 0)
                            {
                                triangles[triIndex]     = i;
                                triangles[triIndex + 1] = i + 1;
                                triangles[triIndex + 2] = i + 2;

                                triangles[triIndex + 3] = i + 1;
                                triangles[triIndex + 4] = i + 3;
                                triangles[triIndex + 5] = i + 2;
                                triIndex += 6;
                            }

                            i++;
                        }
                    }

                    break;

                case TerrainSide.Left:
                    for (int z = 0; z < resolution; z++)
                    {
                        for (int y = -1; y <= 0; y++)
                        {
                            float scaledZ = (z / (resolution - 1f) - 0.5f) * TerrainGrid.Height;
                            vertices[i] = new Vector3(-semiHeight, y, scaledZ);
                            if (vertices[i].y > -1f)
                            {
                                vertices[i].y = CalculateHeight(vertices[i]);
                            }

                            if (y != 0 && z != resolution - 1)
                            {
                                triangles[triIndex]     = i;
                                triangles[triIndex + 1] = i + 2;
                                triangles[triIndex + 2] = i + 1;

                                triangles[triIndex + 3] = i + 1;
                                triangles[triIndex + 4] = i + 2;
                                triangles[triIndex + 5] = i + 3;
                                triIndex += 6;
                            }

                            i++;
                        }
                    }

                    break;

                case TerrainSide.Right:
                    for (int z = 0; z < resolution; z++)
                    {
                        for (int y = -1; y <= 0; y++)
                        {
                            float scaledZ = (z / (resolution - 1f) - 0.5f) * TerrainGrid.Height;
                            vertices[i] = new Vector3(semiHeight, y, scaledZ);
                            if (vertices[i].y > -1f)
                            {
                                vertices[i].y = CalculateHeight(vertices[i]);
                            }

                            if (y != 0 && z != resolution - 1)
                            {
                                triangles[triIndex]     = i;
                                triangles[triIndex + 1] = i + 1;
                                triangles[triIndex + 2] = i + 2;

                                triangles[triIndex + 3] = i + 1;
                                triangles[triIndex + 4] = i + 3;
                                triangles[triIndex + 5] = i + 2;
                                triIndex += 6;
                            }

                            i++;
                        }
                    }

                    break;
                }

                int verticesCount = vertices.Length;
                for (i = 0; i < verticesCount; i++)
                {
                    if (vertices[i].y > 0.01f)
                    {
                        vertices[i].y = CalculateHeight(vertices[i]);
                    }
                }
                break;
            }

            mesh.Clear();
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.RecalculateNormals();
        }
Example #3
0
        public override void Serialize(BinaryWriter w, MapItem item)
        {
            var t = item as Terrain;

            w.Write(t.Uid);

            WriteKdopBounds(w, t);

            byte kflag1 = 0;

            kflag1 |= (byte)(t.WaterReflection.ToByte() << 7);
            kflag1 |= (byte)(t.Right.VegetationCollision.ToByte() << 6);
            kflag1 |= (byte)((byte)t.StepSize << 4);
            kflag1 |= (byte)((byte)t.Right.Terrain.Transition << 2);
            kflag1 |= (byte)t.Right.Terrain.Noise;
            w.Write(kflag1);

            byte kflag2 = 0;

            kflag2 |= (byte)(t.IgnoreCutPlanes.ToByte() << 6);
            kflag2 |= (byte)(t.LowPolyVegetation.ToByte() << 5);
            kflag2 |= (byte)(t.StretchTerrain.ToByte() << 4);
            kflag2 |= (byte)((!t.Right.DetailVegetation).ToByte() << 3);
            kflag2 |= (byte)((!t.Boundary).ToByte() << 2);
            kflag2 |= (byte)((!t.Collision).ToByte() << 1);
            kflag2 |= t.Railings.InvertRailing.ToByte();
            w.Write(kflag2);

            byte kflag3 = 0;

            kflag3 |= (byte)(t.SmoothDetailVegetation.ToByte() << 2);
            kflag3 |= (!t.TerrainShadows).ToByte();
            w.Write(kflag3);

            byte kflag4 = 0;

            kflag4 |= (byte)(t.Left.VegetationCollision.ToByte() << 5);
            kflag4 |= (byte)((!t.Left.DetailVegetation).ToByte() << 4);
            kflag4 |= (byte)((byte)t.Left.Terrain.Transition << 2);
            kflag4 |= (byte)t.Left.Terrain.Noise;
            w.Write(kflag4);

            w.Write((byte)(t.ViewDistance / distFactor));

            w.Write(t.Node.Uid);
            w.Write(t.ForwardNode.Uid);

            w.Write(t.NodeOffset);
            w.Write(t.ForwardNodeOffset);

            w.Write(t.Length);

            w.Write(t.RandomSeed);

            foreach (var railing in t.Railings.Models)
            {
                w.Write(railing.Model);
                w.Write((short)(railing.Offset * modelOffsetFactor));
            }

            TerrainSide bwRight = null;
            TerrainSide bwLeft  = null;

            if (t.BackwardItem is Terrain bwTerrain)
            {
                bwRight = bwTerrain.Right;
                bwLeft  = bwTerrain.Left;
            }
            WriteThatTerrainAndVegetationPart(t.Right, bwRight);
            WriteThatTerrainAndVegetationPart(t.Left, bwLeft);

            WriteObjectList(w, t.VegetationSpheres);

            t.Right.Terrain.QuadData.Serialize(w);
            t.Left.Terrain.QuadData.Serialize(w);

            w.Write(t.Right.Edge);
            w.Write(t.Right.EdgeLook);
            w.Write(t.Left.Edge);
            w.Write(t.Left.EdgeLook);

            void WriteThatTerrainAndVegetationPart(TerrainSide side, TerrainSide bwTerrainSide)
            {
                w.Write((ushort)(side.Terrain.Size * terrainSizeFactor));
                w.Write(side.Terrain.Profile);
                w.Write(side.Terrain.Coefficient);

                if (bwTerrainSide is null)
                {
                    // prev profile
                    w.Write(0UL);
                    // prev coef
                    w.Write(0f);
                }
                else
                {
                    // prev profile
                    w.Write(bwTerrainSide.Terrain.Profile);
                    // prev coef
                    w.Write(bwTerrainSide.Terrain.Coefficient);
                }

                foreach (var veg in side.Vegetation)
                {
                    veg.Serialize(w);
                }

                w.Write((ushort)(side.NoDetailVegetationFrom * noDetVegFromToFactor));
                w.Write((ushort)(side.NoDetailVegetationTo * noDetVegFromToFactor));
            }
        }
Example #4
0
        private static void StitchTerrains(Terrain terrain, Terrain second, TerrainSide side, bool smooth = true)
        {
            TerrainData terrainData = terrain.terrainData;
            TerrainData secondData  = second.terrainData;



            float[,] heights       = terrainData.GetHeights(0, 0, terrainData.heightmapWidth, terrainData.heightmapHeight);
            float[,] secondHeights = secondData.GetHeights(0, 0, secondData.heightmapWidth, secondData.heightmapHeight);



            if (side == TerrainSide.Right)
            {
                int y = heights.GetLength(0) - 1;
                int x = 0;

                int y2 = 0;

                for (x = 0; x < heights.GetLength(1); x++)
                {
                    heights[x, y] = average(heights[x, y], secondHeights[x, y2]);

                    if (smooth)
                    {
                        heights[x, y] += Mathf.Abs(heights[x, y - 1] - secondHeights[x, y2 + 1]) / Smoothlevel;
                    }

                    secondHeights[x, y2] = heights[x, y];

                    for (int i = 1; i < StitcheLength; i++)
                    {
                        heights[x, y - i]        = (average(heights[x, y - i], heights[x, y - i + 1]) + Mathf.Abs(heights[x, y - i] - heights[x, y - i + 1]) / Smoothlevel) * (StitcheLength - i) / StitcheLength + heights[x, y - i] * i / StitcheLength;
                        secondHeights[x, y2 + i] = (average(secondHeights[x, y2 + i], secondHeights[x, y2 + i - 1]) + Mathf.Abs(secondHeights[x, y2 + i] - secondHeights[x, y2 + i - 1]) / Smoothlevel) * (StitcheLength - i) / StitcheLength + secondHeights[x, y2 + i] * i / StitcheLength;
                    }
                }
            }
            else
            {
                if (side == TerrainSide.Top)
                {
                    int y = 0;
                    int x = heights.GetLength(0) - 1;

                    int x2 = 0;

                    for (y = 0; y < heights.GetLength(1); y++)
                    {
                        heights[x, y] = average(heights[x, y], secondHeights[x2, y]);

                        if (smooth)
                        {
                            heights[x, y] += Mathf.Abs(heights[x - 1, y] - secondHeights[x2 + 1, y]) / Smoothlevel;
                        }


                        secondHeights[x2, y] = heights[x, y];

                        for (int i = 1; i < StitcheLength; i++)
                        {
                            heights[x - i, y]        = (average(heights[x - i, y], heights[x - i + 1, y]) + Mathf.Abs(heights[x - i, y] - heights[x - i + 1, y]) / Smoothlevel) * (StitcheLength - i) / StitcheLength + heights[x - i, y] * i / StitcheLength;
                            secondHeights[x2 + i, y] = (average(secondHeights[x2 + i, y], secondHeights[x2 + i - 1, y]) + Mathf.Abs(secondHeights[x2 + i, y] - secondHeights[x2 + i - 1, y]) / Smoothlevel) * (StitcheLength - i) / StitcheLength + secondHeights[x2 + i, y] * i / StitcheLength;
                        }
                    }
                }
            }


            terrainData.SetHeights(0, 0, heights);
            terrain.terrainData = terrainData;

            secondData.SetHeights(0, 0, secondHeights);
            second.terrainData = secondData;

            terrain.Flush();
            second.Flush();
        }
 protected bool Equals(TerrainSide other)
 {
     return(TerrainId == other.TerrainId && SideType == other.SideType);
 }