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(); }
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(); }
// 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()); }
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()); }
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); }
/// <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); }
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()); }
/// <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); }
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); }
//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); }
private void Start() { _block = GetComponent <BlockBehaviour>(); _uvMap = GetComponent <UVMap>(); }
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()); }
/// <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); }
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]); }
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); }
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()); }
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())); }
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); }
// 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); }