private void buildFairing()
        {
            fairingBase.clearProfile();

            UVMap uvs = UVMap.GetUVMapGlobal(uvMap);

            fairingBase.outsideUV = uvs.getArea("outside");
            fairingBase.insideUV  = uvs.getArea("inside");
            fairingBase.edgesUV   = uvs.getArea("edges");

            float halfHeight = currentHeight * 0.5f;

            fairingBase.addRing(-halfHeight, currentBottomDiameter * 0.5f);
            if (currentTopDiameter != currentBottomDiameter)
            {
                fairingBase.addRing(-halfHeight + currentTaperHeight, currentBottomDiameter * 0.5f);
            }
            if (currentHeight != currentTaperHeight || currentTopDiameter == currentBottomDiameter)
            {
                fairingBase.addRing(halfHeight, currentTopDiameter * 0.5f);
            }
            fairingBase.generateColliders = this.generateColliders;
            fairingBase.generateFairing();
            fairingBase.setMaterial(fairingMaterial);
            fairingBase.setOpacity(HighLogic.LoadedSceneIsEditor && editorTransparency ? 0.25f : 1.0f);

            updateEnginePositionAndScale();
            SSTUModInterop.onPartGeometryUpdate(part, true);
            SSTUStockInterop.fireEditorUpdate();
        }
示例#2
0
    private void Awake()
    {
        TransparentRenderer = GetComponent <ITransparentRenderer>();
        _uvMap        = GetComponent <UVMap>();
        _currentSpeed = InitialSpeed;

        Root = Root == null ? gameObject : Root;
    }
    public Block(string BlockName, bool IsTransparent, string name)
    {
        this.BlockName     = BlockName;
        this.IsTransparent = IsTransparent;
        this.name          = name;

        _UVMap = UVMap.GetUvMap(name)._UVMap;
        REGISTER();
    }
示例#4
0
    // Creates Texture Atlas from all terrain textures
    public void CreateAtlas(string _path)
    {
        // Get all terrain texture names
        string[] imageNames = Directory.GetFiles($@"Assets/Textures/{_path}/", "*.png");
        // Default tile pixel size
        int tilePixelWidth  = 32;
        int tilePixelHeight = 32;
        // Create an atlas big enough to hold all images
        int       atlasWidth  = Mathf.CeilToInt((Mathf.Sqrt(imageNames.Length) + 1) * tilePixelWidth);
        int       atlasHeight = Mathf.CeilToInt((Mathf.Sqrt(imageNames.Length) + 1) * tilePixelHeight);
        Texture2D tempAtlas   = new Texture2D(atlasWidth, atlasHeight);
        // Initialize image count
        int count = 0;

        // Loop through image slots for textures in atlas
        for (int x = 0; x < atlasWidth / tilePixelWidth; x++)
        {
            for (int y = 0; y < atlasHeight / tilePixelHeight; y++)
            {
                // If completed all images go to end
                if (count > imageNames.Length - 1)
                {
                    goto end;
                }
                // Load image into temporary texture
                Texture2D tempTexture = new Texture2D(0, 0, TextureFormat.ARGB32, false);
                tempTexture.LoadImage(File.ReadAllBytes(imageNames[count]));
                // Write image to temporary atlas
                tempAtlas.SetPixels(x * tilePixelWidth, y * tilePixelHeight, tilePixelWidth, tilePixelHeight, tempTexture.GetPixels());
                // Get UV coords for image in atlas
                float startx         = x * tilePixelWidth;
                float starty         = y * tilePixelHeight;
                float perPixelRatiox = 1.0f / tempAtlas.width;
                float perPixelRatioy = 1.0f / tempAtlas.height;
                startx *= perPixelRatiox;
                starty *= perPixelRatioy;
                float endx = startx + (perPixelRatiox * tilePixelWidth);
                float endy = starty + (perPixelRatioy * tilePixelHeight);
                // Get image name for UV map
                Match imageName = Regex.Match(imageNames[count], @"([ \w-]+?)(?=\.)");
                // Create a new UV map with coords for named texture on atlas
                UVMap map = new UVMap(imageName.Value, new Vector2[]
                {
                    new Vector2(startx, starty),
                    new Vector2(startx, endy),
                    new Vector2(endx, starty),
                    new Vector2(endx, endy)
                });
                count++;
            }
        }
        end :;
        this.Atlas = tempAtlas;
        File.WriteAllBytes($@"Assets/Textures/Atlas/{_path} Atlas.png", tempAtlas.EncodeToPNG());
    }
示例#5
0
    public void CreateAtlas()
    {
        string[] _Images = Directory.GetFiles("Assets/Textures/blocks/");
        foreach (string s in _Images)
        {
            Debug.Log("Image found for atlas" + s);
        }
        int       PixelWidth  = 16;
        int       PixelHeight = 16;
        int       AtlasWidth  = Mathf.CeilToInt((Mathf.Sqrt(_Images.Length) + 1) * PixelWidth);
        int       AtlasHeight = Mathf.CeilToInt((Mathf.Sqrt(_Images.Length) + 1) * PixelHeight);
        Texture2D Atlas       = new Texture2D(AtlasWidth, AtlasHeight);
        int       count       = 0;

        for (int x = 0; x < AtlasWidth / PixelWidth; x++)
        {
            for (int y = 0; y < AtlasWidth / PixelWidth; y++)
            {
                if (count >= _Images.Length)
                {
                    goto end;
                }
                Texture2D temp = new Texture2D(0, 0);
                temp.LoadImage(File.ReadAllBytes(_Images[count]));
                Atlas.SetPixels(x * PixelWidth, y * PixelHeight, PixelWidth, PixelHeight, temp.GetPixels());

                float startx         = x * PixelWidth;
                float starty         = y * PixelHeight;
                float perpixelratiox = 1.0f / (float)Atlas.width;
                float perpixelratioy = 1.0f / (float)Atlas.height;
                startx *= perpixelratiox;
                starty *= perpixelratioy;
                float endx = startx + (perpixelratiox * PixelWidth);
                float endy = starty + (perpixelratioy * PixelHeight);

                UVMap m = new UVMap(_Images[count], new Vector2[]
                {
                    new Vector2(startx, starty),
                    new Vector2(startx, endy),
                    new Vector2(endx, starty),
                    new Vector2(endx, endy)
                });
                m.Register();

                count++;
            }
        }
        end :;
        _ATLAS = Atlas;
        File.WriteAllBytes("Atlas.png", Atlas.EncodeToPNG());
    }
示例#6
0
        protected UVMap GetTextureUVMap(ResourceManager resources,
                                        string texture,
                                        float x1,
                                        float x2,
                                        float y1,
                                        float y2,
                                        int rot,
                                        Color color)
        {
            if (resources == null)
            {
                x1 = 0;
                x2 = 1 / 32f;
                y1 = 0;
                y2 = 1 / 32f;

                return(new UVMap(
                           new Microsoft.Xna.Framework.Vector2(x1, y1), new Microsoft.Xna.Framework.Vector2(x2, y1),
                           new Microsoft.Xna.Framework.Vector2(x1, y2), new Microsoft.Xna.Framework.Vector2(x2, y2), color,
                           color, color));
            }

            var textureInfo     = resources.Atlas.GetAtlasLocation(texture, out var uvSize);
            var textureLocation = textureInfo.Position;

            var xw = (textureInfo.Width / 16f) / uvSize.X;
            var yh = (textureInfo.Height / 16f) / uvSize.Y;

            textureLocation.X /= uvSize.X;
            textureLocation.Y /= uvSize.Y;

            x1 = textureLocation.X + (x1 * xw);
            x2 = textureLocation.X + (x2 * xw);
            y1 = textureLocation.Y + (y1 * yh);
            y2 = textureLocation.Y + (y2 * yh);

            var map = new UVMap(
                new Microsoft.Xna.Framework.Vector2(x1, y1), new Microsoft.Xna.Framework.Vector2(x2, y1),
                new Microsoft.Xna.Framework.Vector2(x1, y2), new Microsoft.Xna.Framework.Vector2(x2, y2), color, color,
                color, textureInfo.Animated);

            if (rot > 0)
            {
                map.Rotate(rot);
            }

            return(map);
        }
示例#7
0
    /// <summary>
    /// Creates an atlas of all block textures and sets up the UVMaps to point to the UVs of each texture.
    /// </summary>
    public static void CreateAtlas()
    {
        string[] texturePaths            = Directory.GetFiles(GameManager.OpaqueBlockTexturePath, "*?.png");
        int      textureResolutionPixels = 32;
        int      atlasResolutionPixels   = Mathf.CeilToInt((Mathf.Sqrt(texturePaths.Length) + 1) * textureResolutionPixels);

        AtlasTexture = new Texture2D(atlasResolutionPixels, atlasResolutionPixels, TextureFormat.RGBA32, false)
        {
            filterMode = FilterMode.Point,
            wrapMode   = TextureWrapMode.Clamp,
        };
        int x = 0;
        int y = 0;

        foreach (string texturePath in texturePaths)
        {
            Texture2D texture = new Texture2D(0, 0, TextureFormat.ARGB32, false);
            texture.LoadImage(File.ReadAllBytes(texturePath));
            AtlasTexture.SetPixels(x * textureResolutionPixels, y * textureResolutionPixels, textureResolutionPixels, textureResolutionPixels, texture.GetPixels());
            float startX        = x * textureResolutionPixels;
            float startY        = y * textureResolutionPixels;
            float perPixelRatio = 1.0f / AtlasTexture.width;
            startX *= perPixelRatio;
            startY *= perPixelRatio;
            float  endX    = startX + (perPixelRatio * textureResolutionPixels);
            float  endY    = startY + (perPixelRatio * textureResolutionPixels);
            string texName = texturePath.Substring(GameManager.OpaqueBlockTexturePath.Length);
            texName = texName.Substring(0, texName.Length - 4);
            _       = new UVMap(texName, new Vector2[]
            {
                new Vector2(startX, startY),
                new Vector2(startX, endY),
                new Vector2(endX, startY),
                new Vector2(endX, endY)
            });
            x++;
            if (x >= atlasResolutionPixels / textureResolutionPixels)
            {
                x = 0;
                y++;
            }
        }
        AtlasTexture.Apply();
        File.WriteAllBytes(GameManager.TextureAtlasPath, AtlasTexture.EncodeToPNG());
        GameManager.Instance.ChunkMaterial.SetTexture("_BaseColorMap", AtlasTexture);
    }
示例#8
0
    private void Awake()
    {
        TransparentRenderer = GetComponent <ITransparentRenderer>();
        _uvMap        = GetComponent <UVMap>();
        _currentSpeed = InitialSpeed;

        Root           = Root == null ? gameObject : Root;
        _originalScale = transform.localScale;

        if (gameObject.scene.name == "Tutorial")
        {
            _isSpawned = true;
            return;
        }

        transform.localScale = Vector3.zero;
        StartCoroutine(SpawnBlock());
    }
示例#9
0
    /// <summary>
    /// Creates the mesh data for the block at the given internal position within the chunk at the given chunk position.
    /// </summary>
    /// <param name="block">The block to create mesh for.</param>
    /// <param name="internalPos">The internal position of the block to create a mesh for.</param>
    /// <param name="chunkPos">The chunk position of the block to create a mesh for.</param>
    /// <returns>Returns the mesh data created for the block.</returns>
    public static MeshData CreateMesh(Block block, Vector3Int internalPos, Vector3Int chunkPos)
    {
        MeshData meshData  = new MeshData();
        bool     bottomVis = CheckFaceVisibility(internalPos, chunkPos, Side.Bottom, out _);
        bool     topVis    = CheckFaceVisibility(internalPos, chunkPos, Side.Top, out _);
        bool     frontVis  = CheckFaceVisibility(internalPos, chunkPos, Side.Front, out _);
        bool     backVis   = CheckFaceVisibility(internalPos, chunkPos, Side.Back, out _);
        bool     leftVis   = CheckFaceVisibility(internalPos, chunkPos, Side.Left, out _);
        bool     rightVis  = CheckFaceVisibility(internalPos, chunkPos, Side.Right, out _);

        // Bottom Face
        if (bottomVis)
        {
            meshData.Merge(new MeshData(bottomFaceVerts, bottomFaceTriangles, UVMap.GetUVs(block.BlockName), defaultUVs));
        }
        // Top Face
        if (topVis)
        {
            meshData.Merge(new MeshData(topFaceVerts, topFaceTriangles, UVMap.GetUVs(block.BlockName), defaultUVs));
        }
        // Front Face
        if (frontVis)
        {
            meshData.Merge(new MeshData(frontFaceVerts, frontFaceTriangles, UVMap.GetUVs(block.BlockName), defaultUVs));
        }
        // Back Face
        if (backVis)
        {
            meshData.Merge(new MeshData(backFaceVerts, backFaceTriangles, UVMap.GetUVs(block.BlockName), defaultUVs));
        }
        // Left Face
        if (leftVis)
        {
            meshData.Merge(new MeshData(leftFaceVerts, leftFaceTriangles, UVMap.GetUVs(block.BlockName), defaultUVs));
        }
        // Right Face
        if (rightVis)
        {
            meshData.Merge(new MeshData(rightFaceVerts, rightFaceTriangles, UVMap.GetUVs(block.BlockName), defaultUVs));
        }
        meshData.OffsetPosition(new Vector3(internalPos.x - 0.5f, internalPos.y - 0.5f, internalPos.z - 0.5f));
        return(meshData);
    }
示例#10
0
        private void ExecuteButton_Click(object sender, EventArgs e)
        {
            List <IPXFace> errorFaces = new List <IPXFace>();
            string         savename = "", savePath = "";

            foreach (object obj in this.materialListBox.SelectedIndices)
            {
                int    i           = (int)obj;
                string texturePath = this.pmx.Material[i].Tex;
                if (string.Compare(Path.GetExtension(texturePath), ".dds", true) == 0)
                {
                    if (radioBgTex.Checked)
                    {
                        MessageBox.Show("ddsファイルは未対応です" + Environment.NewLine + "背景テクスチャは透明で出力します。");
                    }
                    texturePath = "";
                }

                int      width;
                int      height;
                Bitmap   UVMap;
                Graphics gra;
                if (texturePath == "")
                {
                    width  = 1024 * (int)this.numericScale.Value;
                    height = 1024 * (int)this.numericScale.Value;
                    UVMap  = new Bitmap(width + (this.checkBoxWeightMode.Checked ? 1 : 0), height + (this.checkBoxWeightMode.Checked ? 1 : 0));
                    gra    = Graphics.FromImage(UVMap);
                }
                else
                {
                    using (Image texture = (string.Compare(Path.GetExtension(texturePath), ".tga", true) == 0) ? TgaDecoder.TgaDecoder.FromFile(texturePath) : Image.FromFile(texturePath))
                    {
                        width  = texture.Width * (int)this.numericScale.Value;
                        height = texture.Width * (int)this.numericScale.Value;
                        UVMap  = new Bitmap(width + (this.checkBoxWeightMode.Checked ? 1 : 0), height + (this.checkBoxWeightMode.Checked ? 1 : 0));
                        gra    = Graphics.FromImage(UVMap);
                        if (this.radioBgTex.Checked)
                        {
                            gra.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            gra.DrawImage(texture, 0, 0, width, height);
                        }
                    }
                }

                if (this.radioBgWhite.Checked)
                {
                    gra.FillRectangle(Brushes.White, gra.VisibleClipBounds);
                }


                if (this.checkBoxWeightMode.Checked && (this.checkBoxWPoint.Checked || this.checkBoxWFace.Checked || this.checkBoxWLine.Checked))
                {
                    bool           pointOnly    = this.checkBoxWPoint.Checked && !this.checkBoxWFace.Checked && !this.checkBoxWLine.Checked;
                    var            drawer       = new PixelDrawer.PixelDrawer(width, height);
                    List <Color[]> weightColors = new List <Color[]>();
                    List <V2[]>    UVs          = new List <V2[]>();
                    foreach (IPXFace f in this.pmx.Material[i].Faces)
                    {
                        (IPXBone bone, float weight)? weight1 = Utility.GetWeights(f.Vertex1).Find(w => w.bone == pmx.Bone[comboBoxWeightBone.SelectedIndex]);
                        (IPXBone bone, float weight)? weight2 = Utility.GetWeights(f.Vertex2).Find(w => w.bone == pmx.Bone[comboBoxWeightBone.SelectedIndex]);
                        (IPXBone bone, float weight)? weight3 = Utility.GetWeights(f.Vertex3).Find(w => w.bone == pmx.Bone[comboBoxWeightBone.SelectedIndex]);

                        var weight = new float[] { (weight1?.weight) ?? 0, (weight2?.weight) ?? 0, (weight3?.weight) ?? 0 };
                        weightColors.Add((from w in weight select Color.FromArgb((w * 255f).Round(), 0, 0)).ToArray());
                        UVs.Add(f.ExtructUV());
                        try
                        {
                            if (pointOnly)
                            {
                                drawer.Plot(weightColors.Last(), UVs.Last(), (int)this.lineWidth.Value);
                            }
                            else
                            {
                                if (this.checkBoxWFace.Checked)
                                {
                                    drawer.FillPolygon(weightColors.Last(), UVs.Last());
                                }
                                if (this.checkBoxWLine.Checked)
                                {
                                    drawer.DrawPolygon(weightColors.Last(), UVs.Last(), (float)lineWidth.Value);
                                }
                            }
                        }
                        catch (OutOfMemoryException)
                        {
                            errorFaces.Add(f);
                        }
                    }
                    if (this.checkBoxWPoint.Checked && !pointOnly)
                    {
                        for (int j = 0; j < this.pmx.Material[i].Faces.Count; j++)
                        {
                            drawer.Plot(weightColors[j], UVs[j], (int)this.lineWidth.Value);
                        }
                    }

                    drawer.Write();
                    gra.DrawImage(drawer.Canvas, 0, 0);
                }
                else
                {
                    foreach (PXSide side in new PXMesh(this.pmx.Material[i]).Sides)
                    {
                        using (Pen pen = new Pen(this.cDialog.Color))
                        {
                            pen.Width = (float)this.lineWidth.Value;
                            gra.DrawLine(pen, side.VertexPair[0].UV.ToPoint(width, height), side.VertexPair[1].UV.ToPoint(width, height));
                        }
                    }
                }
                savePath = texturePath == ""
                                                 ? $"{Path.GetDirectoryName(pmx.FilePath)}\\{Path.GetFileNameWithoutExtension(pmx.FilePath)}_{pmx.Material[i].Name}"
                                                 : $"{Path.GetDirectoryName(pmx.FilePath)}\\{Path.GetDirectoryName(texturePath)}\\{Path.GetFileNameWithoutExtension(pmx.FilePath)}_{pmx.Material[i].Name}";
                savename = savePath + (checkBoxWeightMode.Checked ? "_WeightMap.png" : "_UVMap.png");
                UVMap.Save(savename, ImageFormat.Png);
                gra.Dispose();
                UVMap.Dispose();
            }
            string message = $"完了しました。{Environment.NewLine}{savename}を出力しました。";

            if (errorFaces.Count > 0)
            {
                savename = savePath + "_ErrorLog.txt";
                using (StreamWriter writer = new StreamWriter(savename))
                {
                    foreach (var f in errorFaces)
                    {
                        writer.WriteLine(f.PrintUV());
                    }
                }
                message += $"{Environment.NewLine}{errorFaces.Count}枚の面の描画に失敗しました。{Environment.NewLine}エラーログを{Path.GetDirectoryName(savename)}に出力しました。";
            }
            MessageBox.Show(message);
        }
示例#11
0
 //Reset - Variant 2
 //Changes the vertices' texture coordinates with a given 'Texture Fit' method (i.e. a UVMap object)
 public void ResetVertices(UVMap map)
 {
     map.FitOverVB(this._VB);
 }
示例#12
0
 private void Start()
 {
     _block = GetComponent <BlockBehaviour>();
     _uvMap = GetComponent <UVMap>();
 }
示例#13
0
        public override (VertexPositionNormalTextureColor[] vertices, int[] indexes) GetVertices(IWorld world, Vector3 vectorPos, IBlock baseBlock)
        {
            var position = new BlockCoordinates(vectorPos);
            List <VertexPositionNormalTextureColor> result = new List <VertexPositionNormalTextureColor>(36);
            var indexResult = new List <int>();

            int tl = 0, tr = 0, bl = 0, br = 0;

            Level = baseBlock.BlockState.GetTypedValue(LEVEL);

            string b1, b2;

            if (IsLava)
            {
                b1 = "minecraft:lava";
                b2 = "minecraft:lava";
            }
            else
            {
                b1 = "minecraft:water";
                b2 = "minecraft:water";
            }

            int lowestFound = 999;
            BlockCoordinates lowestBlock = BlockCoordinates.Up;

            bool isFlowing          = isFlowing = Check(world, position);;
            int  rot                = 0;
            bool calculateDirection = false;
            var  bc = world.GetBlock(position + BlockCoordinates.Up);               //.GetType();

            if ((!IsLava && bc.IsWater) || (IsLava && bc.Name == "minecraft:lava")) //.Name == b1 || bc.Name == b2)
            {
                tl = 8;
                tr = 8;
                bl = 8;
                br = 8;

                rot = 180;
            }
            else
            {
                if (isFlowing)
                {
                    calculateDirection = true;

                    tl = GetAverageLiquidLevels(world, position, out lowestBlock, out lowestFound);

                    tr = GetAverageLiquidLevels(world, position + BlockCoordinates.Right, out var trl, out var trv);
                    if (trv < lowestFound)
                    {
                        lowestBlock = trl;
                        lowestFound = trv;
                    }

                    bl = GetAverageLiquidLevels(world, position + BlockCoordinates.Forwards, out var bll, out var blv);
                    if (blv < lowestFound)
                    {
                        lowestBlock = bll;
                        lowestFound = blv;
                    }

                    br = GetAverageLiquidLevels(world, position + new BlockCoordinates(1, 0, 1), out var brl,
                                                out var brv);
                }
                else
                {
                    tl = 8;
                    tr = 8;
                    bl = 8;
                    br = 8;
                }

                //if (brv < lowestFound)
                //	lowestBlock = brl;
            }

            double lowestDistance = 9999;

            if (lowestBlock.Y <= position.Y && calculateDirection)
            {
                for (int i = 0; i < 4; i++)
                {
                    var rotation            = 0;
                    BlockCoordinates offset = BlockCoordinates.Zero;
                    switch (i)
                    {
                    case 0:
                        offset   = BlockCoordinates.North;
                        rotation = 180;
                        break;

                    case 1:
                        offset   = BlockCoordinates.South;
                        rotation = 0;
                        break;

                    case 2:
                        offset   = BlockCoordinates.East;
                        rotation = 90;
                        break;

                    case 3:
                        offset   = BlockCoordinates.West;
                        rotation = 270;
                        break;

                    case 4:
                        //NorthWest
                        offset   = new BlockCoordinates(-1, 0, -1);
                        rotation = 0;
                        break;

                    case 5:
                        //SouthWest
                        offset   = new BlockCoordinates(-1, 0, 1);
                        rotation = 180;
                        break;

                    case 6:
                        //SouthEast
                        offset   = new BlockCoordinates(1, 0, 1);
                        rotation = 270;
                        break;

                    case 7:                             //NorthEast
                        offset   = new BlockCoordinates(1, 0, -1);
                        rotation = 0;
                        break;
                    }

                    if (i == 8)
                    {
                        rot = 0;
                    }

                    var distance = Math.Abs(
                        (position + offset).DistanceTo(lowestBlock));
                    if (distance < lowestDistance)
                    {
                        lowestDistance = distance;
                        rot            = rotation;
                    }
                }
            }

            /*if (difference == BlockCoordinates.North)
             * {
             *
             * }
             * else if (difference == BlockCoordinates.South)
             * {
             *      rot = 180;
             * }
             * else if (difference == BlockCoordinates.East)
             * {
             *      rot = 270;
             * }
             * else if (difference == BlockCoordinates.West)
             * {
             *      rot = 90;
             * }*/

            string texture = "";

            if (IsLava)
            {
                texture = "block/lava";
            }
            else
            {
                texture = "block/water";
            }
            //texture = texture + "_flow";
            if (isFlowing || (tl < 8 || tr < 8 || bl < 8 || br < 8))
            {
                texture += "_flow";
            }
            else
            {
                texture += "_still";
            }

            //float frameX
            UVMap map = GetTextureUVMap(Alex.Instance.Resources, texture, 0, 16, 0, 16, 0);

            var originalMap = new UVMap(map.TopLeft, map.TopRight, map.BottomLeft, map.BottomRight, map.ColorLeft, map.ColorTop, map.ColorBottom);

            originalMap.Rotate(180);

            map.Rotate(rot);

            foreach (var f in Enum.GetValues(typeof(BlockFace)).Cast <BlockFace>())
            {
                BlockCoordinates d = BlockCoordinates.Zero;
                d = f.GetBlockCoordinates();

                float height  = 0;
                bool  special = f == BlockFace.Up && (tl < 8 || tr < 8 || bl < 8 || br < 8);

                var modPos         = position + d;
                var b              = (BlockState)world.GetBlockState(modPos.X, modPos.Y, modPos.Z);
                LiquidBlockModel m = b.Model as LiquidBlockModel;
                var secondSpecial  = m != null && (m.Level > Level);

                float s     = 1f - Scale;
                var   start = Vector3.One * s;
                var   end   = Vector3.One * Scale;

                if (special || (secondSpecial) || (!string.IsNullOrWhiteSpace(b.Name) && (!b.Name.Equals(b1) && !b.Name.Equals(b2))))
                {
                    //if (b.BlockModel is LiquidBlockModel m && m.Level > Level && f != BlockFace.Up) continue;

                    var faceMap = map;
                    if (f != BlockFace.Up)
                    {
                        faceMap = originalMap;
                    }

                    var vertices = GetFaceVertices(f, start, end, faceMap, out int[] indexes);

                    var initialIndex = result.Count;
                    for (var index = 0; index < vertices.Length; index++)
                    {
                        var vert = vertices[index];
                        if (vert.Position.Y > start.Y)
                        {
                            const float modifier = 2f;
                            if (vert.Position.X == start.X && vert.Position.Z == start.Z)
                            {
                                height = (modifier * (tl));
                                rot    = 0;
                            }
                            else if (vert.Position.X != start.X && vert.Position.Z == start.Z)
                            {
                                height = (modifier * (tr));
                                rot    = 270;
                            }
                            else if (vert.Position.X == start.X && vert.Position.Z != start.Z)
                            {
                                height = (modifier * (bl));
                                rot    = 90;
                            }
                            else
                            {
                                height = (modifier * (br));
                                rot    = 270;
                            }

                            vert.Position.Y = height / 16.0f;                             //; + (position.Y);
                        }

                        vert.Position.Y += position.Y - s;
                        vert.Position.X += position.X;
                        vert.Position.Z += position.Z;

                        if (IsWater)
                        {
                            vert.Color = new Color(68, 175, 245);
                        }
                        //vert.Color = AdjustColor(new Color(68, 175, 245), f,
                        //	GetLight(world, position + d), false);

                        result.Add(vert);
                    }

                    for (var index = 0; index < indexes.Length; index++)
                    {
                        //var vert = vertices[index];
                        //var vert = vertices[indexes[index]];
                        indexResult.Add(initialIndex + indexes[index]);
                    }
                }
            }

            return(result.ToArray(), indexResult.ToArray());
        }
示例#14
0
    /// <summary>
    /// Creates the mesh data for the block at the given internal position within the chunk at the given chunk position.
    /// </summary>
    /// <param name="block">The block type to create mesh for.</param>
    /// <param name="internalPos">The internal position of the block to create a mesh for.</param>
    /// <param name="chunkPos">The chunk position of the block to create a mesh for.</param>
    /// <returns>Returns the mesh data created for the block.</returns>
    public static MeshData CreateMesh(Block block, Vector3Int internalPos, Vector3Int chunkPos)
    {
        // TODO: Add support for block rotation so blocks with different faces can be placed in any orientation, or at least additional orientations.
        // TODO: Add lighting data into UV2 for mesh and use it in shader to determine brightness of texture.
        MeshData   meshData  = new MeshData();
        bool       topVis    = CheckFaceVisibility(internalPos, chunkPos, Side.Top, out _);
        bool       bottomVis = CheckFaceVisibility(internalPos, chunkPos, Side.Bottom, out _);
        bool       frontVis  = CheckFaceVisibility(internalPos, chunkPos, Side.Front, out _);
        bool       backVis   = CheckFaceVisibility(internalPos, chunkPos, Side.Back, out _);
        bool       rightVis  = CheckFaceVisibility(internalPos, chunkPos, Side.Right, out _);
        bool       leftVis   = CheckFaceVisibility(internalPos, chunkPos, Side.Left, out _);
        Vector3Int worldPos  = internalPos.InternalPosToWorldPos(chunkPos);
        int        rotation  = Mathf.RoundToInt(GameManager.Instance.CaveWormPositionNoiseGenerator.GetNoise(worldPos.x, worldPos.y, worldPos.z).Remap(-1, 1, 0, 3));
        BlockType  blockType = BlockType.BlockTypes[block.ID];

        // Top Face
        if (topVis)
        {
            string    uvName = ((blockType.UniqueFaces & BlockType.UniqueFacesEnum.Top) == BlockType.UniqueFacesEnum.Top) ? blockType.BlockName + "_" + blockType.TopTextureName : blockType.BlockName;
            Vector2[] uvs    = ((blockType.RandomFaces & BlockType.RandomFacesEnum.Top) == BlockType.RandomFacesEnum.Top) ? UVMap.GetUVs(uvName).RotateUVs(rotation) : UVMap.GetUVs(uvName);
            meshData.Merge(new MeshData(topFaceVerts, topFaceTriangles, uvs, defaultUVs));
        }
        // Bottom Face
        if (bottomVis)
        {
            string    uvName = ((blockType.UniqueFaces & BlockType.UniqueFacesEnum.Bottom) == BlockType.UniqueFacesEnum.Bottom) ?  blockType.BlockName + "_" + blockType.BottomTextureName : blockType.BlockName;
            Vector2[] uvs    = ((blockType.RandomFaces & BlockType.RandomFacesEnum.Bottom) == BlockType.RandomFacesEnum.Bottom) ? UVMap.GetUVs(uvName).RotateUVs(rotation) : UVMap.GetUVs(uvName);
            meshData.Merge(new MeshData(bottomFaceVerts, bottomFaceTriangles, uvs, defaultUVs));
        }
        // Front Face
        if (frontVis)
        {
            if (blockType.BlockName == "Grass" && World.TryGetBlockFromWorldPos(internalPos.InternalPosToWorldPos(chunkPos) + new Vector3Int(0, -1, 1), out Block neighborBlock) == true && BlockType.BlockTypes[neighborBlock.ID].BlockName == "Grass")
            {
                string    uvName = blockType.BlockName;
                Vector2[] uvs    = UVMap.GetUVs(uvName).RotateUVs(rotation);
                meshData.Merge(new MeshData(frontFaceVerts, frontFaceTriangles, uvs, defaultUVs));
            }
            else
            {
                string    uvName = ((blockType.UniqueFaces & BlockType.UniqueFacesEnum.Front) == BlockType.UniqueFacesEnum.Front) ? blockType.BlockName + "_" + blockType.FrontTextureName : blockType.BlockName;
                Vector2[] uvs    = ((blockType.RandomFaces & BlockType.RandomFacesEnum.Front) == BlockType.RandomFacesEnum.Front) ? UVMap.GetUVs(uvName).RotateUVs(rotation) : UVMap.GetUVs(uvName).RotateUVs(3);
                meshData.Merge(new MeshData(frontFaceVerts, frontFaceTriangles, uvs, defaultUVs));
            }
        }
        // Back Face
        if (backVis)
        {
            if (blockType.BlockName == "Grass" && World.TryGetBlockFromWorldPos(internalPos.InternalPosToWorldPos(chunkPos) + new Vector3Int(0, -1, -1), out Block neighborBlock) == true && BlockType.BlockTypes[neighborBlock.ID].BlockName == "Grass")
            {
                string    uvName = blockType.BlockName;
                Vector2[] uvs    = UVMap.GetUVs(uvName).RotateUVs(rotation);
                meshData.Merge(new MeshData(backFaceVerts, backFaceTriangles, uvs, defaultUVs));
            }
            else
            {
                string    uvName = ((blockType.UniqueFaces & BlockType.UniqueFacesEnum.Back) == BlockType.UniqueFacesEnum.Back) ? blockType.BlockName + "_" + blockType.BackTextureName : blockType.BlockName;
                Vector2[] uvs    = ((blockType.RandomFaces & BlockType.RandomFacesEnum.Back) == BlockType.RandomFacesEnum.Back) ? UVMap.GetUVs(uvName).RotateUVs(rotation) : UVMap.GetUVs(uvName).RotateUVs(3);
                meshData.Merge(new MeshData(backFaceVerts, backFaceTriangles, uvs, defaultUVs));
            }
        }
        // Right Face
        if (rightVis)
        {
            if (blockType.BlockName == "Grass" && World.TryGetBlockFromWorldPos(internalPos.InternalPosToWorldPos(chunkPos) + new Vector3Int(1, -1, 0), out Block neighborBlock) == true && BlockType.BlockTypes[neighborBlock.ID].BlockName == "Grass")
            {
                string    uvName = blockType.BlockName;
                Vector2[] uvs    = UVMap.GetUVs(uvName).RotateUVs(rotation);
                meshData.Merge(new MeshData(rightFaceVerts, rightFaceTriangles, uvs, defaultUVs));
            }
            else
            {
                string    uvName = ((blockType.UniqueFaces & BlockType.UniqueFacesEnum.Right) == BlockType.UniqueFacesEnum.Right) ? blockType.BlockName + "_" + blockType.RightTextureName : blockType.BlockName;
                Vector2[] uvs    = ((blockType.RandomFaces & BlockType.RandomFacesEnum.Right) == BlockType.RandomFacesEnum.Right) ? UVMap.GetUVs(uvName).RotateUVs(rotation) : UVMap.GetUVs(uvName).RotateUVs(3);
                meshData.Merge(new MeshData(rightFaceVerts, rightFaceTriangles, uvs, defaultUVs));
            }
        }
        // Left Face
        if (leftVis)
        {
            if (blockType.BlockName == "Grass" && World.TryGetBlockFromWorldPos(internalPos.InternalPosToWorldPos(chunkPos) + new Vector3Int(-1, -1, 0), out Block neighborBlock) == true && BlockType.BlockTypes[neighborBlock.ID].BlockName == "Grass")
            {
                string    uvName = blockType.BlockName;
                Vector2[] uvs    = UVMap.GetUVs(uvName).RotateUVs(rotation);
                meshData.Merge(new MeshData(leftFaceVerts, leftFaceTriangles, uvs, defaultUVs));
            }
            else
            {
                string    uvName = ((blockType.UniqueFaces & BlockType.UniqueFacesEnum.Left) == BlockType.UniqueFacesEnum.Left) ? blockType.BlockName + "_" + blockType.LeftTextureName : blockType.BlockName;
                Vector2[] uvs    = ((blockType.RandomFaces & BlockType.RandomFacesEnum.Left) == BlockType.RandomFacesEnum.Left) ? UVMap.GetUVs(uvName).RotateUVs(rotation) : UVMap.GetUVs(uvName).RotateUVs(3);
                meshData.Merge(new MeshData(leftFaceVerts, leftFaceTriangles, uvs, defaultUVs));
            }
        }
        meshData.OffsetPosition(new Vector3(internalPos.x - 0.5f, internalPos.y - 0.5f, internalPos.z - 0.5f));
        return(meshData);
    }
示例#15
0
        protected BlockShaderVertex[] GetFaceVertices(BlockFace blockFace, Vector3 startPosition, Vector3 endPosition, UVMap uvmap, out int[] indexes)
        {
            Color   faceColor = Color.White;
            Vector3 normal = Vector3.Zero;
            Vector3 positionTopLeft = Vector3.Zero, positionBottomLeft = Vector3.Zero, positionBottomRight = Vector3.Zero, positionTopRight = Vector3.Zero;

            switch (blockFace)
            {
            case BlockFace.Up:                     //Positive Y
                positionTopLeft  = new Vector3(startPosition.X, endPosition.Y, endPosition.Z);
                positionTopRight = new Vector3(endPosition.X, endPosition.Y, endPosition.Z);

                positionBottomLeft  = new Vector3(startPosition.X, endPosition.Y, startPosition.Z);
                positionBottomRight = new Vector3(endPosition.X, endPosition.Y, startPosition.Z);

                normal    = Vector3.Up;
                faceColor = uvmap.ColorTop;                         //new Color(0x00, 0x00, 0xFF);
                break;

            case BlockFace.Down:                     //Negative Y
                positionTopLeft  = new Vector3(startPosition.X, startPosition.Y, endPosition.Z);
                positionTopRight = new Vector3(endPosition.X, startPosition.Y, endPosition.Z);

                positionBottomLeft  = new Vector3(startPosition.X, startPosition.Y, startPosition.Z);
                positionBottomRight = new Vector3(endPosition.X, startPosition.Y, startPosition.Z);

                normal    = Vector3.Down;
                faceColor = uvmap.ColorBottom;                         //new Color(0xFF, 0xFF, 0x00);
                break;

            case BlockFace.West:                     //Negative X
                positionTopLeft  = new Vector3(startPosition.X, endPosition.Y, startPosition.Z);
                positionTopRight = new Vector3(startPosition.X, endPosition.Y, endPosition.Z);

                positionBottomLeft  = new Vector3(startPosition.X, startPosition.Y, startPosition.Z);
                positionBottomRight = new Vector3(startPosition.X, startPosition.Y, endPosition.Z);

                normal    = Vector3.Left;
                faceColor = uvmap.ColorLeft;                         // new Color(0xFF, 0x00, 0xFF);
                break;

            case BlockFace.East:                     //Positive X
                positionTopLeft  = new Vector3(endPosition.X, endPosition.Y, startPosition.Z);
                positionTopRight = new Vector3(endPosition.X, endPosition.Y, endPosition.Z);

                positionBottomLeft  = new Vector3(endPosition.X, startPosition.Y, startPosition.Z);
                positionBottomRight = new Vector3(endPosition.X, startPosition.Y, endPosition.Z);

                normal    = Vector3.Right;
                faceColor = uvmap.ColorRight;                         //new Color(0x00, 0xFF, 0xFF);
                break;

            case BlockFace.South:                     //Positive Z
                positionTopLeft  = new Vector3(startPosition.X, endPosition.Y, startPosition.Z);
                positionTopRight = new Vector3(endPosition.X, endPosition.Y, startPosition.Z);

                positionBottomLeft  = new Vector3(startPosition.X, startPosition.Y, startPosition.Z);
                positionBottomRight = new Vector3(endPosition.X, startPosition.Y, startPosition.Z);

                normal    = Vector3.Backward;
                faceColor = uvmap.ColorFront;                         // ew Color(0x00, 0xFF, 0x00);
                break;

            case BlockFace.North:                     //Negative Z
                positionTopLeft  = new Vector3(startPosition.X, endPosition.Y, endPosition.Z);
                positionTopRight = new Vector3(endPosition.X, endPosition.Y, endPosition.Z);

                positionBottomLeft  = new Vector3(startPosition.X, startPosition.Y, endPosition.Z);
                positionBottomRight = new Vector3(endPosition.X, startPosition.Y, endPosition.Z);

                normal    = Vector3.Forward;
                faceColor = uvmap.ColorBack;                         // new Color(0xFF, 0x00, 0x00);
                break;

            case BlockFace.None:
                break;
            }

            var topLeft    = new BlockShaderVertex(positionTopLeft, normal, uvmap.TopLeft, faceColor);
            var topRight   = new BlockShaderVertex(positionTopRight, normal, uvmap.TopRight, faceColor);
            var bottomLeft = new BlockShaderVertex(positionBottomLeft, normal, uvmap.BottomLeft,
                                                   faceColor);
            var bottomRight = new BlockShaderVertex(positionBottomRight, normal, uvmap.BottomRight,
                                                    faceColor);

            switch (blockFace)
            {
            case BlockFace.Up:
                indexes = new int[]
                {
                    2, 0, 1,
                    3, 2, 1
                };
                break;

            case BlockFace.Down:
                indexes = new[]
                {
                    0, 2, 1,
                    2, 3, 1
                };
                break;

            case BlockFace.North:
                indexes = new[]
                {
                    0, 2, 1,
                    2, 3, 1
                };
                break;

            case BlockFace.East:
                indexes = new[]
                {
                    2, 0, 1,
                    3, 2, 1
                };
                break;

            case BlockFace.South:
                indexes = new[]
                {
                    2, 0, 1,
                    3, 2, 1
                };
                break;

            case BlockFace.West:
                indexes = new[]
                {
                    0, 2, 1,
                    2, 3, 1
                };
                break;

            default:
                indexes = new int[0];
                break;
            }

            return(new[]
            {
                topLeft, topRight, bottomLeft, bottomRight
            });

            return(new BlockShaderVertex[0]);
        }
示例#16
0
        public Mesh CreateMesh()
        {
            List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>();

            for (int x = 0; x < SizeX; x++)
            {
                for (int y = 0; y < SizeY; y++)
                {
                    for (int z = 0; z < SizeZ; z++)
                    {
                        Vector3I Position = new Vector3I(x, y, z);

                        Vector3 realPos = new Vector3(Position.X, Position.Y, Position.Z) + ChunkPosition;
                        Vector3 cubePos = new Vector3(realPos.X + (realPos.X - 16), realPos.Z + (realPos.Z - 16), realPos.Y + (realPos.Y - 16));
                        if (this[Position].Visible)
                        {
                            Vector3 topLeftFront  = cubePos + new Vector3(-1.0f, 1.0f, -1.0f);
                            Vector3 topLeftBack   = cubePos + new Vector3(-1.0f, 1.0f, 1.0f);
                            Vector3 topRightFront = cubePos + new Vector3(1.0f, 1.0f, -1.0f);
                            Vector3 topRightBack  = cubePos + new Vector3(1.0f, 1.0f, 1.0f);

                            // Calculate the cubePos of the vertices on the bottom face.
                            Vector3 btmLeftFront  = cubePos + new Vector3(-1.0f, -1.0f, -1.0f);
                            Vector3 btmLeftBack   = cubePos + new Vector3(-1.0f, -1.0f, 1.0f);
                            Vector3 btmRightFront = cubePos + new Vector3(1.0f, -1.0f, -1.0f);
                            Vector3 btmRightBack  = cubePos + new Vector3(1.0f, -1.0f, 1.0f);

                            // Normal vectors for each face (needed for lighting / display)
                            Vector3 normalFront  = new Vector3(0.0f, 0.0f, 1.0f);
                            Vector3 normalBack   = new Vector3(0.0f, 0.0f, -1.0f);
                            Vector3 normalTop    = new Vector3(0.0f, 1.0f, 0.0f);
                            Vector3 normalBottom = new Vector3(0.0f, -1.0f, 0.0f);
                            Vector3 normalLeft   = new Vector3(-1.0f, 0.0f, 0.0f);
                            Vector3 normalRight  = new Vector3(1.0f, 0.0f, 0.0f);

                            if (!this[x, y, z + 1].Visible)
                            {
                                UVMap uv = this[x, y, z].CreateUVMapping(Direction.Top);
                                // Add the vertices for the TOP face.
                                vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uv.TopRight));
                                vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalTop, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(topRightFront, normalTop, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uv.TopRight));
                            }
                            //if (!this[x, y - 1, z).Visible)
                            if (!this[x, y, z - 1].Visible)
                            {
                                UVMap uv = this[x, y, z].CreateUVMapping(Direction.Bottom);
                                // Add the vertices for the BOTTOM face.
                                vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalBottom, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBottom, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBottom, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalBottom, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBottom, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalBottom, uv.TopRight));
                            }
                            //if (!this[x, y, z + 1).Visible)
                            if (!this[x, y + 1, z].Visible)
                            {
                                UVMap uv = this[x, y, z].CreateUVMapping(Direction.Back);
                                // Add the vertices for the BACK face.
                                vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalBack, uv.TopRight));
                                vertices.Add(new VertexPositionNormalTexture(topRightBack, normalBack, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBack, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBack, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(topRightBack, normalBack, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBack, uv.BottomLeft));
                            }
                            //if (!this[x, y, z - 1).Visible)
                            if (!this[x, y - 1, z].Visible)
                            {
                                UVMap uv = this[x, y, z].CreateUVMapping(Direction.Front);
                                // Add the vertices for the FRONT face.
                                vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalFront, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalFront, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(topRightFront, normalFront, uv.TopRight));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalFront, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalFront, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(topRightFront, normalFront, uv.TopRight));
                            }
                            if (!this[x - 1, y, z].Visible)
                            {
                                UVMap uv = this[x, y, z].CreateUVMapping(Direction.Left);
                                // Add the vertices for the LEFT face.
                                vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalLeft, uv.TopRight));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalLeft, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalLeft, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalLeft, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalLeft, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalLeft, uv.TopRight));
                            }
                            if (!this[x + 1, y, z].Visible)
                            {
                                UVMap uv = this[x, y, z].CreateUVMapping(Direction.Right);
                                // Add the vertices for the RIGHT face.
                                vertices.Add(new VertexPositionNormalTexture(topRightFront, normalRight, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalRight, uv.BottomLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalRight, uv.BottomRight));
                                vertices.Add(new VertexPositionNormalTexture(topRightBack, normalRight, uv.TopRight));
                                vertices.Add(new VertexPositionNormalTexture(topRightFront, normalRight, uv.TopLeft));
                                vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalRight, uv.BottomRight));
                            }
                        }
                    }
                }
            }
            Mesh ret = new Mesh()
            {
                Vertices = vertices.ToArray(),
            };

            vertices.Clear();
            return(ret);
        }
示例#17
0
        public override (VertexPositionNormalTextureColor[] vertices, int[] indexes) GetVertices(IBlockAccess world, Vector3 vectorPos, Block baseBlock)
        {
            //Level = GetLevel(baseBlock.BlockState);

            var position = new BlockCoordinates(vectorPos);
            List <VertexPositionNormalTextureColor> result = new List <VertexPositionNormalTextureColor>(36);
            var indexResult = new List <int>();

            List <BlockFace> renderedFaces = new List <BlockFace>();

            foreach (var face in Enum.GetValues(typeof(BlockFace)).Cast <BlockFace>())
            {
                var pos = position + face.GetBlockCoordinates();

                bool shouldRenderFace = true;
                foreach (var blockState in world.GetBlockStates(pos.X, pos.Y, pos.Z))
                {
                    if (blockState.Storage != 0 && (blockState.State == null || (blockState.State.Block is Air)))
                    {
                        continue;
                    }

                    shouldRenderFace = baseBlock.ShouldRenderFace(face, blockState.State.Block);
                }

                if (shouldRenderFace)
                {
                    renderedFaces.Add(face);
                }
            }

            if (renderedFaces.Count == 0)
            {
                return(new VertexPositionNormalTextureColor[0], new int[0]);
            }

            int tl, tr, bl, br;

            //	var myLevel = GetLevel(baseBlock.BlockState);

            int lowestFound = 999;
            BlockCoordinates lowestBlock = BlockCoordinates.Up;

            bool isFlowing          = CheckFlowing(world, position);;
            int  rot                = 0;
            bool calculateDirection = false;

            var check    = position + BlockCoordinates.Up;
            var blocksUp = world.GetBlockStates(check.X, check.Y, check.Z).ToArray();            //.GetType();

            if ((IsWater && blocksUp.Any(
                     x => x.State.Block.Renderable && x.State.Block.BlockMaterial == Material.Water)) ||
                (IsLava && blocksUp.Any(
                     x => x.State.Block.Renderable && x.State.Block.BlockMaterial == Material.Lava))
                )
            {
                tl = 8;
                tr = 8;
                bl = 8;
                br = 8;

                rot       = 180;
                isFlowing = true;
            }
            else
            {
                if (isFlowing)
                {
                    calculateDirection = true;

                    tl = GetAverageLiquidLevels(world, position, out lowestBlock, out lowestFound);

                    tr = GetAverageLiquidLevels(world, position + BlockCoordinates.Right, out var trl, out var trv);
                    if (trv > lowestFound)
                    {
                        lowestBlock = trl;
                        lowestFound = trv;
                    }

                    bl = GetAverageLiquidLevels(world, position + BlockCoordinates.Forwards, out var bll, out var blv);
                    if (blv > lowestFound)
                    {
                        lowestBlock = bll;
                        lowestFound = blv;
                    }

                    br = GetAverageLiquidLevels(world, position + new BlockCoordinates(1, 0, 1), out var brl,
                                                out var brv);
                }
                else
                {
                    if (blocksUp.Any(x => x.State.Block.Solid && x.State.Block.Renderable))
                    {
                        tl = 8;
                        tr = 8;
                        bl = 8;
                        br = 8;
                    }
                    else
                    {
                        tl = 7;
                        tr = 7;
                        bl = 7;
                        br = 7;
                    }
                }

                //if (brv < lowestFound)
                //	lowestBlock = brl;
            }

            double lowestDistance = 9999;

            if (lowestBlock.Y <= position.Y && calculateDirection)
            {
                for (int i = 0; i < 4; i++)
                {
                    var rotation            = 0;
                    BlockCoordinates offset = BlockCoordinates.Zero;
                    switch (i)
                    {
                    case 0:
                        offset   = BlockCoordinates.North;
                        rotation = 180;
                        break;

                    case 1:
                        offset   = BlockCoordinates.South;
                        rotation = 0;
                        break;

                    case 2:
                        offset   = BlockCoordinates.East;
                        rotation = 270;
                        break;

                    case 3:
                        offset   = BlockCoordinates.West;
                        rotation = 90;
                        break;
                    }

                    var distance = Math.Abs(
                        (position + offset).DistanceTo(lowestBlock));
                    if (distance < lowestDistance)
                    {
                        lowestDistance = distance;
                        rot            = rotation;
                    }
                }
            }

            string texture = "";

            if (IsLava)
            {
                texture = "block/lava";
            }
            else
            {
                texture = "block/water";
            }
            //texture = texture + "_flow";
            if (isFlowing)
            {
                texture += "_flow";
            }
            else
            {
                texture += "_still";
            }

            //float frameX
            UVMap map = GetTextureUVMap(Alex.Instance.Resources, texture, 0, 16, 0, 16, 0, Color.White);

            var originalMap = new UVMap(map.TopLeft, map.TopRight, map.BottomLeft, map.BottomRight, map.ColorLeft, map.ColorTop, map.ColorBottom);

            //originalMap.Rotate(180);

            map.Rotate(rot);

            foreach (var face in renderedFaces)
            {
                float s     = 1f - Scale;
                var   start = Vector3.One * s;
                var   end   = Vector3.One * Scale;


                //if (b.BlockModel is LiquidBlockModel m && m.Level > Level && f != BlockFace.Up) continue;

                var faceMap = map;
                if (face != BlockFace.Up)
                {
                    faceMap = originalMap;
                }

                var vertices = GetFaceVertices(face, start, end, faceMap, out int[] indexes);

                float height       = 0;
                var   initialIndex = result.Count;
                for (var index = 0; index < vertices.Length; index++)
                {
                    var vert = vertices[index];
                    if (vert.Position.Y > start.Y)
                    {
                        const float modifier = 2f;
                        if (vert.Position.X == start.X && vert.Position.Z == start.Z)
                        {
                            height = (modifier * (tl));
                            rot    = 0;
                        }
                        else if (vert.Position.X != start.X && vert.Position.Z == start.Z)
                        {
                            height = (modifier * (tr));
                            rot    = 270;
                        }
                        else if (vert.Position.X == start.X && vert.Position.Z != start.Z)
                        {
                            height = (modifier * (bl));
                            rot    = 90;
                        }
                        else
                        {
                            height = (modifier * (br));
                            rot    = 270;
                        }

                        vert.Position.Y = height / 16.0f;                         //; + (position.Y);
                    }

                    vert.Position.Y += position.Y - s;
                    vert.Position.X += position.X;
                    vert.Position.Z += position.Z;

                    if (IsWater)
                    {
                        vert.Color = new Color(68, 175, 245);
                    }
                    else
                    {
                        vert.BlockLight = baseBlock.LightValue;
                    }
                    //vert.Color = AdjustColor(new Color(68, 175, 245), f,
                    //	GetLight(world, position + d), false);

                    result.Add(vert);
                }

                for (var index = 0; index < indexes.Length; index++)
                {
                    //var vert = vertices[index];
                    //var vert = vertices[indexes[index]];
                    indexResult.Add(initialIndex + indexes[index]);
                }
            }

            return(result.ToArray(), indexResult.ToArray());
        }
示例#18
0
        public override VerticesResult GetVertices(IBlockAccess world, Vector3 vectorPos, Block baseBlock)
        {
            //int myLevel =
            //var chunk = world.GetChunk(vectorPos);
            //Level = GetLevel(baseBlock.BlockState);

            var position = new BlockCoordinates(vectorPos);
            //var                      biome   = world.GetBiome(position);
            List <BlockShaderVertex> result = new List <BlockShaderVertex>(36);
            var indexResult = new List <int>();

            var blocksUp = world.GetBlockStates(position.X, position.Y + 1, position.Z).ToArray();            //.GetType();

            bool aboveIsLiquid =
                (IsWater && blocksUp.Any(
                     x => x.State.Block.Renderable && (x.State.Block.BlockMaterial == Material.Water || x.State.Block.BlockMaterial == Material.WaterPlant))) || (IsLava &&
                                                                                                                                                                  blocksUp.Any(x => x.State.Block.Renderable && x.State.Block.BlockMaterial == Material.Lava));

            List <BlockFace> renderedFaces = new List <BlockFace>();

            //List<BlockFace> liquidFaces = new List<BlockFace>();
            foreach (var face in Faces)
            {
                var pos = position + face.GetBlockCoordinates();

                bool shouldRenderFace = true;
                foreach (var blockState in world.GetBlockStates(pos.X, pos.Y, pos.Z))
                {
                    if (blockState.Storage != 0 && (blockState.State == null || (blockState.State.Block is Air)))
                    {
                        continue;
                    }

                    var neighbor = blockState.State.Block;

                    shouldRenderFace = baseBlock.ShouldRenderFace(face, neighbor);

                    //	if ((neighbor.BlockMaterial == Material.Water || neighbor.BlockMaterial == Material.WaterPlant) && IsWater)
                    //{
                    //		if (face != BlockFace.Up && face != BlockFace.Down)
                    //			liquidFaces.Add(face);
                    //	}
                }

                if (shouldRenderFace)
                {
                    renderedFaces.Add(face);
                }
            }

            if (renderedFaces.Count == 0 && !aboveIsLiquid)
            {
                return(new VerticesResult(new BlockShaderVertex[0], new int[0]));
            }

            int tl, tr, bl, br;

            //	var myLevel = GetLevel(baseBlock.BlockState);

            int lowestFound = 999;
            BlockCoordinates lowestBlock = BlockCoordinates.Up;

            bool isFlowing          = CheckFlowing(world, position);;
            int  rot                = 0;
            bool calculateDirection = false;

            //var avgLiquidLevel = GetAverageLiquidLevels(world, position, out lowestBlock, out lowestFound);

            if (aboveIsLiquid)
            {
                tl = 8;
                tr = 8;
                bl = 8;
                br = 8;

                rot       = 180;
                isFlowing = true;
            }
            else
            {
                if (isFlowing)
                {
                    calculateDirection = true;
                }

                tl = GetAverageLiquidLevels(world, position, out lowestBlock, out lowestFound);;
                //tl = GetAverageLiquidLevels(world, position, out lowestBlock, out lowestFound);

                tr = GetAverageLiquidLevels(world, position + BlockCoordinates.Right, out var trl, out var trv);
                if (trv > lowestFound)
                {
                    lowestBlock = trl;
                    lowestFound = trv;
                }

                bl = GetAverageLiquidLevels(world, position + BlockCoordinates.Forwards, out var bll, out var blv);
                if (blv > lowestFound)
                {
                    lowestBlock = bll;
                    lowestFound = blv;
                }

                br = GetAverageLiquidLevels(world, position + new BlockCoordinates(1, 0, 1), out var brl,
                                            out var brv);

                //if (brv < lowestFound)
                //	lowestBlock = brl;
            }

            double lowestDistance = 9999;

            if (lowestBlock.Y <= position.Y && calculateDirection)
            {
                for (int i = 0; i < 4; i++)
                {
                    var rotation            = 0;
                    BlockCoordinates offset = BlockCoordinates.Zero;
                    switch (i)
                    {
                    case 0:
                        offset   = BlockCoordinates.North;
                        rotation = 180;
                        break;

                    case 1:
                        offset   = BlockCoordinates.South;
                        rotation = 0;
                        break;

                    case 2:
                        offset   = BlockCoordinates.East;
                        rotation = 270;
                        break;

                    case 3:
                        offset   = BlockCoordinates.West;
                        rotation = 90;
                        break;
                    }

                    var distance = Math.Abs(
                        (position + offset).DistanceTo(lowestBlock));
                    if (distance < lowestDistance)
                    {
                        lowestDistance = distance;
                        rot            = rotation;
                    }
                }
            }

            string texture = "";

            if (IsLava)
            {
                texture = "block/lava";
            }
            else
            {
                texture = "block/water";
            }
            //texture = texture + "_flow";
            if (isFlowing)
            {
                texture += "_flow";
            }
            else
            {
                texture += "_still";
            }

            UVMap map = GetTextureUVMap(Alex.Instance.Resources, texture, 0, 16, 0, 16, 0, Color.White);

            var originalMap = new UVMap(map.TopLeft, map.TopRight, map.BottomLeft, map.BottomRight, map.ColorLeft, map.ColorTop, map.ColorBottom);

            map.Rotate(rot);

            foreach (var face in renderedFaces)
            {
                /*if (!renderedFaces.Contains(face))
                 * {
                 *
                 *      continue;
                 * }*/

                float s     = 1f - Scale;
                var   start = Vector3.One * s;
                var   end   = Vector3.One * Scale;

                var faceMap = map;
                if (face != BlockFace.Up)
                {
                    faceMap = originalMap;
                }

                var vertices = GetFaceVertices(face, start, end, faceMap, out int[] indexes);

                float height       = 0;
                var   initialIndex = result.Count;
                for (var index = 0; index < vertices.Length; index++)
                {
                    var vert = vertices[index];
                    if (vert.Position.Y > start.Y)
                    {
                        const float modifier = 2f;
                        if (vert.Position.X == start.X && vert.Position.Z == start.Z)
                        {
                            height = (modifier * (tl));
                            rot    = 0;
                        }
                        else if (vert.Position.X != start.X && vert.Position.Z == start.Z)
                        {
                            height = (modifier * (tr));
                            rot    = 270;
                        }
                        else if (vert.Position.X == start.X && vert.Position.Z != start.Z)
                        {
                            height = (modifier * (bl));
                            rot    = 90;
                        }
                        else
                        {
                            height = (modifier * (br));
                            rot    = 270;
                        }

                        vert.Position.Y = height / 16.0f;                         //; + (position.Y);
                    }

                    vert.Position.Y += position.Y - s;
                    vert.Position.X += position.X;
                    vert.Position.Z += position.Z;

                    if (IsWater)
                    {
                        var bx = position.X;
                        var y  = position.Y;
                        var bz = position.Z;

                        if (ResourcePackBlockModel.SmoothLighting)
                        {
                            vert.Color = CombineColors(
                                GetBiomeColor(world, bx, y, bz), GetBiomeColor(world, bx - 1, y, bz - 1), GetBiomeColor(world, bx - 1, y, bz),
                                GetBiomeColor(world, bx, y, bz - 1), GetBiomeColor(world, bx + 1, y, bz + 1), GetBiomeColor(world, bx + 1, y, bz),
                                GetBiomeColor(world, bx, y, bz + 1), GetBiomeColor(world, bx - 1, y, bz + 1), GetBiomeColor(world, bx + 1, y, bz - 1));
                        }
                        else
                        {
                            vert.Color = GetBiomeColor(world, bx, y, bz);
                        }
                    }
                    else
                    {
                        vert.BlockLight = baseBlock.LightValue;
                    }

                    result.Add(vert);
                }

                for (var index = 0; index < indexes.Length; index++)
                {
                    //var vert = vertices[index];
                    //var vert = vertices[indexes[index]];
                    indexResult.Add(initialIndex + indexes[index]);
                }
            }

            return(new VerticesResult(result.ToArray(), indexResult.ToArray()));
        }
示例#19
0
        public Mesh CreateMesh()
        {
            List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>();

            for (int x = 0; x < Size.X; x++)
            {
                for (int y = 0; y < Size.Y; y++)
                {
                    for (int z = 0; z < Size.Z; z++)
                    {
                        Vector3I Position = new Vector3I(x, y, z);

                        if (this[Position].Visible() ||
                            this[Position].Transparent())    // We still want to render them to see them.
                        {
                            Vector3 size = new Vector3(1, 1, 1);

                            Vector3 realPos = (Position + ChunkPosition).ToRenderCoords();
                            //Vector3 realPos = new Vector3(Position.X, Position.Y, Position.Z) + ChunkPosition; // Array position
                            Vector3 cubePos = new Vector3(realPos.X, realPos.Y, realPos.Z); // View position

                            // Top face
                            Vector3 topLeftFront  = cubePos + new Vector3(-1.0f, 1.0f, -1.0f) * size;
                            Vector3 topLeftBack   = cubePos + new Vector3(-1.0f, 1.0f, 1.0f) * size;
                            Vector3 topRightFront = cubePos + new Vector3(1.0f, 1.0f, -1.0f) * size;
                            Vector3 topRightBack  = cubePos + new Vector3(1.0f, 1.0f, 1.0f) * size;

                            // Calculate the cubePos of the vertices on the bottom face.
                            Vector3 btmLeftFront  = cubePos + new Vector3(-1.0f, -1.0f, -1.0f) * size;
                            Vector3 btmLeftBack   = cubePos + new Vector3(-1.0f, -1.0f, 1.0f) * size;
                            Vector3 btmRightFront = cubePos + new Vector3(1.0f, -1.0f, -1.0f) * size;
                            Vector3 btmRightBack  = cubePos + new Vector3(1.0f, -1.0f, 1.0f) * size;

                            /* Start of Vertices */
                            if (!this[x, y, z + 1].Visible())
                            {
                                UVMap?uvMap = this[x, y, z].CreateUVMapping(Direction.Top);
                                if (uvMap != null)
                                {
                                    UVMap uv = uvMap.GetValueOrDefault();
                                    // Add the vertices for the TOP face.
                                    vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uv.TopRight));
                                    vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalTop, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(topRightFront, normalTop, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uv.TopRight));
                                }
                            }
                            //if (!this[x, y - 1, z).Visible)
                            if (!this[x, y, z - 1].Visible())
                            {
                                UVMap?uvMap = this[x, y, z].CreateUVMapping(Direction.Bottom);
                                if (uvMap != null)
                                {
                                    UVMap uv = uvMap.GetValueOrDefault();
                                    // Add the vertices for the BOTTOM face.
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalBottom, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBottom, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBottom, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalBottom, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBottom, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalBottom, uv.TopRight));
                                }
                            }
                            //if (!this[x, y, z + 1).Visible)
                            if (!this[x, y + 1, z].Visible())
                            {
                                UVMap?uvMap = this[x, y, z].CreateUVMapping(Direction.Back);
                                if (uvMap != null)
                                {
                                    UVMap uv = uvMap.GetValueOrDefault();
                                    // Add the vertices for the BACK face.
                                    vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalBack, uv.TopRight));
                                    vertices.Add(new VertexPositionNormalTexture(topRightBack, normalBack, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBack, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBack, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(topRightBack, normalBack, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBack, uv.BottomLeft));
                                }
                            }
                            //if (!this[x, y, z - 1).Visible)
                            if (!this[x, y - 1, z].Visible())
                            {
                                UVMap?uvMap = this[x, y, z].CreateUVMapping(Direction.Front);
                                if (uvMap != null)
                                {
                                    UVMap uv = uvMap.GetValueOrDefault();
                                    // Add the vertices for the FRONT face.
                                    vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalFront, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalFront, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(topRightFront, normalFront, uv.TopRight));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalFront, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalFront, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(topRightFront, normalFront, uv.TopRight));
                                }
                            }
                            if (!this[x - 1, y, z].Visible())
                            {
                                UVMap?uvMap = this[x, y, z].CreateUVMapping(Direction.Left);
                                if (uvMap != null)
                                {
                                    UVMap uv = uvMap.GetValueOrDefault();
                                    // Add the vertices for the LEFT face.
                                    vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalLeft, uv.TopRight));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalLeft, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalLeft, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalLeft, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalLeft, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalLeft, uv.TopRight));
                                }
                            }
                            if (!this[x + 1, y, z].Visible())
                            {
                                UVMap?uvMap = this[x, y, z].CreateUVMapping(Direction.Right);
                                if (uvMap != null)
                                {
                                    UVMap uv = uvMap.GetValueOrDefault();
                                    // Add the vertices for the RIGHT face.
                                    vertices.Add(new VertexPositionNormalTexture(topRightFront, normalRight, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalRight, uv.BottomLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalRight, uv.BottomRight));
                                    vertices.Add(new VertexPositionNormalTexture(topRightBack, normalRight, uv.TopRight));
                                    vertices.Add(new VertexPositionNormalTexture(topRightFront, normalRight, uv.TopLeft));
                                    vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalRight, uv.BottomRight));
                                }
                            }
                            /* End of Vertices */
                        }
                    }
                }
            }
            Mesh ret = new Mesh()
            {
                Vertices = vertices.ToArray()
            };

            vertices.Clear();
            return(ret);
        }
示例#20
0
    // Creates a mesh
    public static Mesh CreateMesh(MeshTypeEnum _type)
    {
        // Set limits
        int worldSize          = gm.baseSettings.worldSize;
        int numRows            = worldSize * 2;
        int numQuadsPerRow     = numRows;
        int numVertsTotal      = numRows * numVertsPerQuad * numQuadsPerRow;
        int numTriIndicesTotal = numVertsTotal * 3 / 2;
        // Assign limits to arrays
        Mesh mesh = new Mesh();

        Vector3[] verts = new Vector3[numVertsTotal];
        Vector2[] uvs   = new Vector2[numVertsTotal];
        int[]     tris  = new int[numTriIndicesTotal];
        // Assign all verts, uvs, and tris to arrays
        // Loop through rows
        for (int rowIndex = 0; rowIndex < numRows; rowIndex++)
        {
            // Verts
            // Assign starting x and z values for vertices
            int vx = -worldSize;
            int vy = 0;
            int vz = -worldSize + rowIndex;
            // Loop through quads in row
            for (int quadIndex = rowIndex * numQuadsPerRow; quadIndex < (rowIndex + 1) * numQuadsPerRow; quadIndex++)
            {
                // Assign vertices
                int vertIndex = quadIndex * numVertsPerQuad;
                verts[vertIndex] = new Vector3(vx, vy, vz);
                vertIndex++;
                vx += 0;
                vz += 1;
                verts[vertIndex] = new Vector3(vx, vy, vz);
                vertIndex++;
                vx += 1;
                vz -= 1;
                verts[vertIndex] = new Vector3(vx, vy, vz);
                vertIndex++;
                vx += 0;
                vz += 1;
                verts[vertIndex] = new Vector3(vx, vy, vz);
                vz -= 1;
            }
            // UVs
            // Loop through quads in row
            for (int quadIndex = rowIndex * numQuadsPerRow; quadIndex < (rowIndex + 1) * numQuadsPerRow; quadIndex++)
            {
                // Assign UVs
                int uvIndex = quadIndex * numVertsPerQuad;
                {
                    Vector2Int tilePos = World.GetTilePosFromQuadIndex(quadIndex);
                    string     name;
                    if (_type == MeshTypeEnum.Terrain)
                    {
                        name = World.Tiles[tilePos].sedimentTileType.ToString();
                    }
                    else
                    {
                        name = World.Tiles[tilePos].heightmapTileType.ToString();
                        if (name != World.HeightmapTileTypeEnum.Shallows.ToString() && name != World.HeightmapTileTypeEnum.Ocean.ToString())
                        {
                            name = "Blank";
                        }
                    }
                    Vector2[] map = UVMap.GetUVMap(name).UVMaps;
                    uvs[uvIndex] = map[0];
                    uvIndex++;
                    uvs[uvIndex] = map[1];
                    uvIndex++;
                    uvs[uvIndex] = map[2];
                    uvIndex++;
                    uvs[uvIndex] = map[3];
                }
            }
            // Tris
            // Assign starting x, y, and z values for triangles
            int vertIndexStartForTris = rowIndex * numVertsPerQuad * numQuadsPerRow;
            int tx = vertIndexStartForTris;
            int ty = vertIndexStartForTris + 1;
            int tz = vertIndexStartForTris + 2;
            // Loop through quads in row
            for (int quadIndex = rowIndex * numQuadsPerRow; quadIndex < (rowIndex + 1) * numQuadsPerRow; quadIndex++)
            {
                // Assign triangles
                int triIndex = quadIndex * numTriIndicesPerQuad;
                tris[triIndex] = tx;
                triIndex++;
                tris[triIndex] = ty;
                triIndex++;
                tris[triIndex] = tz;
                triIndex++;
                tx++;
                ty            += 2;
                tris[triIndex] = tx;
                triIndex++;
                tris[triIndex] = ty;
                triIndex++;
                tris[triIndex] = tz;
                tx            += 3;
                ty            += 2;
                tz            += 4;
            }
        }
        // Assign mesh data to mesh
        mesh.vertices  = verts;
        mesh.uv        = uvs;
        mesh.triangles = tris;
        mesh.RecalculateBounds();
        mesh.Optimize();
        // Return mesh
        return(mesh);
    }