public virtual MeshData Blockdata(Chunk chunk, int x, int y, int z, MeshData meshData) { if (!chunk.GetBlock(x, y + 1, z).IsSolid(Direction.down)) { meshData = FaceDataUp(chunk, x, y, z, meshData); } if (!chunk.GetBlock(x, y - 1, z).IsSolid(Direction.up)) { meshData = FaceDataDown(chunk, x, y, z, meshData); } if (!chunk.GetBlock(x, y, z + 1).IsSolid(Direction.south)) { meshData = FaceDataNorth(chunk, x, y, z, meshData); } if (!chunk.GetBlock(x, y, z - 1).IsSolid(Direction.north)) { meshData = FaceDataSouth(chunk, x, y, z, meshData); } if (!chunk.GetBlock(x + 1, y, z).IsSolid(Direction.west)) { meshData = FaceDataEast(chunk, x, y, z, meshData); } if (!chunk.GetBlock(x - 1, y, z).IsSolid(Direction.east)) { meshData = FaceDataWest(chunk, x, y, z, meshData); } return meshData; }
public virtual MeshData AddQuadFlatBlend( Vector3[] points, MeshData meshData) { //Takes 4 points, calculates two normals for two faces //Adds the points and triangles to the mesh Vector3 flatnorm1 = new Vector3(); flatnorm1 = Vector3.Cross (points [1] - points [0], points [3] - points [0]); Vector3 flatnorm2 = new Vector3(); flatnorm2 = Vector3.Cross (points [3] - points [2], points [1] - points [2]); //set the vertices meshData.AddVertex(points [0], flatnorm1); meshData.AddVertex(points [1], flatnorm1); meshData.AddVertex(points [3], flatnorm1); meshData.AddBlendTriangle (); meshData.AddVertex(points [1], flatnorm2); meshData.AddVertex(points [2], flatnorm2); meshData.AddVertex(points [3], flatnorm2); meshData.AddBlendTriangle (); Color32[] vcolors = new Color32[6]; vcolors [2] = Color.clear; vcolors [4] = Color.clear; vcolors [5] = Color.clear; vcolors [0] = Color.white; vcolors [1] = Color.white; vcolors [3] = Color.white; meshData.colors.AddRange (vcolors); return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap) { int width = heightMap.GetLength (0); int height = heightMap.GetLength (1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; MeshData meshData = new MeshData (width, height); int vertexIndex = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { meshData.vertices [vertexIndex] = new Vector3 (topLeftX + x, heightMap [x, y], topLeftZ - y); meshData.uvs [vertexIndex] = new Vector2 (x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle (vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle (vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve (_heightCurve.keys); int meshSimplificationIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2; int borderedSize = heightMap.GetLength (0); int meshSize = borderedSize - 2*meshSimplificationIncrement; int meshSizeUnsimplified = borderedSize - 2; float topLeftX = (meshSizeUnsimplified - 1) / -2f; float topLeftZ = (meshSizeUnsimplified - 1) / 2f; int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData (verticesPerLine); int[,] vertexIndicesMap = new int[borderedSize,borderedSize]; int meshVertexIndex = 0; int borderVertexIndex = -1; for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1; if (isBorderVertex) { vertexIndicesMap [x, y] = borderVertexIndex; borderVertexIndex--; } else { vertexIndicesMap [x, y] = meshVertexIndex; meshVertexIndex++; } } } for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { int vertexIndex = vertexIndicesMap [x, y]; Vector2 percent = new Vector2 ((x-meshSimplificationIncrement) / (float)meshSize, (y-meshSimplificationIncrement) / (float)meshSize); float height = heightCurve.Evaluate (heightMap [x, y]) * heightMultiplier; Vector3 vertexPosition = new Vector3 (topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified); meshData.AddVertex (vertexPosition, percent, vertexIndex); if (x < borderedSize - 1 && y < borderedSize - 1) { int a = vertexIndicesMap [x, y]; int b = vertexIndicesMap [x + meshSimplificationIncrement, y]; int c = vertexIndicesMap [x, y + meshSimplificationIncrement]; int d = vertexIndicesMap [x + meshSimplificationIncrement, y + meshSimplificationIncrement]; meshData.AddTriangle (a,d,c); meshData.AddTriangle (d,a,b); } vertexIndex++; } } return meshData; }
public void DrawMesh(MeshData meshData, Texture2D texture) { // Mesh filter is used to proceduraly change mesh // It allow us to get to the mesh components meshFilter.sharedMesh = meshData.GenerateMesh(); meshRenderer.sharedMaterial.mainTexture = texture; }
public override MeshData blockData(Chunk chunk, int x, int y, int z, MeshData meshData) { meshData.useRenderDataForCol = false; if (!chunk.getBlock (x, y + 1, z).isSolid (Direction.up)) { meshData = FaceDataUp (chunk, x, y, z, meshData); } if (!chunk.getBlock (x, y - 1, z).isSolid (Direction.down)) { meshData = FaceDataDown (chunk, x, y, z, meshData); } if (!chunk.getBlock (x, y, z + 1).isSolid (Direction.north)) { meshData = FaceDataNorth (chunk, x, y, z, meshData); } if (!chunk.getBlock (x, y, z - 1).isSolid (Direction.south)) { meshData = FaceDataSouth (chunk, x, y, z, meshData); } if (!chunk.getBlock (x + 1, y, z).isSolid (Direction.east)) { meshData = FaceDataEast (chunk, x, y, z, meshData); } if (!chunk.getBlock (x - 1, y, z).isSolid (Direction.west)) { meshData = FaceDataWest (chunk, x, y, z, meshData); } return meshData; }
public bool AddMesh(GameObject go) { if (_lut.ContainsKey(go.GetInstanceID())) { return true; } // returns false if renderer is not available if (go.GetComponent<Renderer>() == null) { return false; } // returns false if not a mesh MeshFilter mf = (MeshFilter)go.GetComponent (typeof(MeshFilter)); if (mf == null) { return false; } MeshData md = new MeshData (); md._instID = go.GetInstanceID (); md._vertCount = mf.mesh.vertexCount; md._triCount = mf.mesh.triangles.Length / 3; md._materialCount = go.GetComponent<Renderer>().sharedMaterials.Length; md._boundSize = go.GetComponent<Renderer>().bounds.size.magnitude; _lut.Add (md._instID, md); return true; }
public void AddBounds(Bounds bounds, Color color) { MeshData meshData = null; for (int i = 0; i < datas.Count; ++i) { if (datas[i].vertexCount >= vertexBuffSize) continue; else meshData = datas[i]; } if (meshData == null) { meshData = new MeshData(); datas.Add(meshData); } Vector3 min = bounds.min; Vector3 max = bounds.max; meshData.vertices[meshData.vertexCount + 0] = min; meshData.vertices[meshData.vertexCount + 1].Set(min.x, min.y, max.z); meshData.vertices[meshData.vertexCount + 2].Set(min.x, max.y, min.z); meshData.vertices[meshData.vertexCount + 3].Set(min.x, max.y, max.z); meshData.vertices[meshData.vertexCount + 4].Set(max.x, min.y, min.z); meshData.vertices[meshData.vertexCount + 5].Set(max.x, min.y, max.z); meshData.vertices[meshData.vertexCount + 6].Set(max.x, max.y, min.z); meshData.vertices[meshData.vertexCount + 7] = max; for (int i = 0; i < 8; ++i) meshData.colors[meshData.vertexCount + i] = color; for (int i = 0; i < 24; ++i) meshData.indices[meshData.vertexCount * 3 + i] = gWireFrameIndex[i] + meshData.vertexCount; meshData.vertexCount += 8; }
public static void BuildRenderer(Chunk chunk, BlockPos pos, MeshData meshData, Direction direction, Vector3 ModelSize, Vector3 ConnMeshSizeX, Vector3 ConnMeshSizeY, Vector3 ConnMeshSizeZ, Direction[] Dir) { MakeStickFace(chunk, pos, meshData, direction, false, ModelSize); Debug.Log(Dir.Length); if (Dir.Length > 0) MakeFenceFace(chunk, pos, meshData, direction, false, ModelSize, ConnMeshSizeX, ConnMeshSizeY, ConnMeshSizeZ, Dir); }
//Update is called once per frame void Update() { if (update) { //HasUpdatedLights = false; if (!IsUpdating) { if (!CanUpdateRenderer) { IsUpdating = true; MyMeshData = new MeshData(); MyWaterMeshData = new MeshData(); if (IsUpdateOnThread) { UnityThreading.ActionThread NewThread = UnityThreadHelper.CreateThread(() => { // thread processing UpdateChunk(); CanUpdateRenderer = true; }); } else { UpdateChunk(); CanUpdateRenderer = true; } } } else { if (CanUpdateRenderer) { UpdateRender(); update = false; IsUpdating = false; CanUpdateRenderer = false; } } } //if (HasUpdatedLights) { //UpdateChunkLightsOnly(); // HasUpdatedLights = false; //} }
public virtual MeshData Blockdata(Chunk chunk, int x, int y, int z, MeshData meshData) { // Check if block on top has a solid down face if (!chunk.GetBlock(x, y + 1, z).IsSolid(Direction.down)) { meshData = FaceDataUp(chunk, x, y, z, meshData); } // Check if the block below has a solid up face if (!chunk.GetBlock(x, y - 1, z).IsSolid(Direction.up)) { meshData = FaceDataDown(chunk, x, y, z, meshData); } // Check if the block north has a solid south face if (!chunk.GetBlock(x, y, z + 1).IsSolid(Direction.south)) { meshData = FaceDataNorth(chunk, x, y, z, meshData); } // Check if the block south has a solid north face if (!chunk.GetBlock(x, y, z - 1).IsSolid(Direction.north)) { meshData = FaceDataSouth(chunk, x, y, z, meshData); } // Check if the block east has a solid west face if (!chunk.GetBlock(x + 1, y, z).IsSolid(Direction.west)) { meshData = FaceDataEast(chunk, x, y, z, meshData); } // Check if the block west has a solid east face if (!chunk.GetBlock(x - 1, y, z).IsSolid(Direction.east)) { meshData = FaceDataWest(chunk, x, y, z, meshData); } return meshData; }
public virtual MeshData getBeamMesh(Vector3 start, Vector3 end, float width, MeshData meshData) { Vector3[] points = new Vector3[3]; Vector2[] UVs = new Vector2[3]; Vector3 tip = end - start; float mag = tip.magnitude; Vector3 perp = new Vector3 (-tip.y, tip.x, tip.z) / mag; Vector3 base1 = (perp * width/4) + tip/mag; Vector3 base2 = (perp * -width/4) + tip/mag; //Vector3 base3 = Quaternion.Euler(300, 0, 0) * perp; UVs [2] = new Vector2 (0.0f, Math.Min (0.4f+width,1.0f)); UVs [1] = new Vector2 (0.0f, Math.Max (0.6f-width,0.0f)); UVs [0] = new Vector2 (0.1f, 0.5f); meshData.AddVertex(Vector3.zero); meshData.AddVertex(base1); meshData.AddVertex(base2); meshData.AddTriangle(); meshData.uv.AddRange(UVs); UVs [1] = new Vector2 (0.0f, Math.Min (0.4f+width,1.0f)); UVs [2] = new Vector2 (0.0f, Math.Max (0.6f-width,0.0f)); UVs [0] = new Vector2 (0.1f, 0.5f); meshData.AddVertex(tip); meshData.AddVertex(base2); meshData.AddVertex(base1); meshData.AddTriangle(); meshData.uv.AddRange(UVs); return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve (_heightCurve.keys); int width = heightMap.GetLength (0); int height = heightMap.GetLength (1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData (verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { meshData.vertices [vertexIndex] = new Vector3 (topLeftX + x, heightCurve.Evaluate (heightMap [x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs [vertexIndex] = new Vector2 (x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle (vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle (vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return meshData; }
public bool AddTypeElement(System.Xml.Linq.XElement elemtype) { XAttribute fileAtt = elemtype.Attribute("file"); if (fileAtt == null) { //Add error message here return false; } string filePath = Path.Combine(Path.GetDirectoryName(new Uri(elemtype.BaseUri).LocalPath), fileAtt.Value); filePath = Path.GetFullPath(filePath); // Load the OBJ in var lStream = new FileStream(filePath, FileMode.Open); var lOBJData = OBJLoader.LoadOBJ(lStream); lStream.Close(); meshData = new MeshData[(int)MeshLayer.Count]; Mesh tempMesh = new Mesh(); for (int i = 0; i < meshData.Length; i++) { tempMesh.LoadOBJ(lOBJData, ((MeshLayer)i).ToString()); meshData[i] = new MeshData(tempMesh); tempMesh.Clear(); } lStream = null; lOBJData = null; return true; }
public static void AddCircularPlane(float radius, int rings, int segments, Vector3 axis, MeshData meshData) { var vertices = meshData.Vertices; var triangles = meshData.Triangles; float radiusScalar = radius / rings; var ringPoints = Enumerable.Range(1, rings).Select(i => GetCircleOfPoints(i * radiusScalar, segments, axis)).ToArray(); int startingIndex = vertices.Count; vertices.Add(Vector3.zero); //add points to vertex list foreach (var circle in ringPoints) foreach (var point in circle) vertices.Add(point); //Add triangles from center point to the first ring for (int i = 2; i <= segments; i++) { triangles.AddRange(new int[] { startingIndex, startingIndex + i - 1, startingIndex + i }); } //Add the last triangle triangles.AddRange(new int[] { startingIndex, startingIndex + segments, startingIndex + 1 }); //Now add the rest of the rings for(int r=1;r<rings;r++) { int ringIndex = r * segments + 1 + startingIndex; int prevRingIndex = (r - 1) * segments + 1 + startingIndex; for(int s=1;s<segments;s++) { triangles.AddRange(new int[] { ringIndex + s - 1, ringIndex + s, prevRingIndex + s - 1 }); triangles.AddRange(new int[] { prevRingIndex + s - 1, ringIndex + s, prevRingIndex + s }); } //Add final quad triangles.AddRange(new int[] { ringIndex + segments-1, ringIndex + 0, prevRingIndex + segments-1 }); triangles.AddRange(new int[] { prevRingIndex + segments-1, ringIndex + 0, prevRingIndex + 0 }); } }
public void MeshUpdated(MeshData[] meshes) { if (meshes == null) return; this.meshes = meshes; this.meshUpdateCount++; }
protected override MeshData FaceDataWest (Chunk chunk, int x, int y, int z, MeshData meshData) { MeshData mD = base.FaceDataWest (chunk, x, y, z, meshData); mD.AddColor(color); mD.AddColor(color); mD.AddColor(color); mD.AddColor(color); return meshData; }
public void DrawMesh(MeshData meshData, Texture2D texture) { currentTexture = texture; //print (currentTexture.width + " " + currentTexture.height); meshFilter.sharedMesh = meshData.CreateMesh (); meshRenderer.sharedMaterial.mainTexture = texture; GetComponent<MeshCollider>().sharedMesh = meshFilter.sharedMesh; }
void Start() { filter = GetComponent<MeshFilter> (); data = new MeshData(); //indicees = new MeshIndices[Chunk.WIDTH,Chunk.HEIGHT,Chunk.WIDTH]; blockMesh = new BlockMesh(); myChunk = new Chunk (transform.position.x, transform.position.z); StartCoroutine ("completeDraw"); }
void DoInitMeshBuffer() { MeshData [] vertices = new MeshData[_mesh.vertices.Length]; for (int i = 0; i < _mesh.vertices.Length; ++i) { vertices[i].Position = _mesh.vertices[i]; // vertices[i].Color = _mesh.colors[i]; } _verticesBuffer.SetData(vertices); }
protected virtual MeshData FaceDataDown(Chunk chunk, int x, int y, int z, MeshData meshData) { meshData.vertices.Add(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f)); meshData.vertices.Add(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f)); meshData.vertices.Add(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f)); meshData.vertices.Add(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f)); meshData.AddQuadTriangles(); return meshData; }
public override void BuildFace(Chunk chunk, BlockPos pos, MeshData meshData, Direction direction, Block block) { BlockBuilder.BuildRenderer(chunk, pos, meshData, direction); BlockBuilder.BuildTexture(chunk, pos, meshData, direction, textures); BlockBuilder.BuildColors(chunk, pos, meshData, direction); if (Config.Toggle.UseCollisionMesh) { BlockBuilder.BuildCollider(chunk, pos, meshData, direction); } }
public static Mesh GenerateMesh(int _rows, int _columns, float _quadSegmentSize) { if (_rows < 0f || _columns < 0 || _quadSegmentSize < 0f) { throw new System.ArgumentException("Invalid water mesh data"); } rows = _rows + 1; // There are 2 rows between 3 points, so we need to add 1 columns = _columns + 1; // Same here quadSegmentSize = _quadSegmentSize; var mesh = new Mesh(); mesh.name = "Water Mesh"; MeshData meshData = new MeshData(); meshData.Vertices = new Vector3[rows * columns]; meshData.Normals = new Vector3[rows * columns]; meshData.UVs = new Vector2[rows * columns]; meshData.TriangleIndices = new int[rows * columns * 6]; int triangleIndex = 0; for (int r = 0; r < rows; r++) { for (int c = 0; c < columns; c++) { int index = GetIndex(r, c); // Set vertices, normals and UVs meshData.Vertices[index] = new Vector3(c * quadSegmentSize, 0f, r * quadSegmentSize); meshData.Normals[index] = Vector3.up; meshData.UVs[index] = new Vector2((float)c / columns, (float)r / rows); // Set triangles if (r < rows - 1 && c < columns - 1) { meshData.TriangleIndices[triangleIndex + 0] = GetIndex(r, c); meshData.TriangleIndices[triangleIndex + 1] = GetIndex(r + 1, c); meshData.TriangleIndices[triangleIndex + 2] = GetIndex(r, c + 1); meshData.TriangleIndices[triangleIndex + 3] = GetIndex(r + 1, c); meshData.TriangleIndices[triangleIndex + 4] = GetIndex(r + 1, c + 1); meshData.TriangleIndices[triangleIndex + 5] = GetIndex(r, c + 1); triangleIndex += 6; } } } mesh.vertices = meshData.Vertices; mesh.normals = meshData.Normals; mesh.uv = meshData.UVs; mesh.triangles = meshData.TriangleIndices; return mesh; }
public static MeshData CreateSphere(float radius, int sliceCount, int stackCount) { var ret = new MeshData(); ret.Vertices.Add(new Vertex(0,radius,0, 0,1,0, 1,0,0, 0,0)); var phiStep = MathF.PI/stackCount; var thetaStep = 2.0f*MathF.PI/sliceCount; for (int i = 1; i <= stackCount-1; i++) { var phi = i*phiStep; for (int j = 0; j <= sliceCount; j++) { var theta = j*thetaStep; var p = new Vector3( (radius*MathF.Sin(phi)*MathF.Cos(theta)), (radius*MathF.Cos(phi)), (radius* MathF.Sin(phi)*MathF.Sin(theta)) ); var t = new Vector3(-radius*MathF.Sin(phi)*MathF.Sin(theta), 0, radius*MathF.Sin(phi)*MathF.Cos(theta)); t.Normalize(); var n = Vector3.Normalize(p); var uv = new Vector2(theta/(MathF.PI*2), phi / MathF.PI); ret.Vertices.Add(new Vertex(p, n, t, uv)); } } ret.Vertices.Add(new Vertex(0,-radius, 0, 0, -1, 0, 1, 0, 0, 0, 1)); for (int i = 1; i <= sliceCount; i++) { ret.Indices.Add(0); ret.Indices.Add(i+1); ret.Indices.Add(i); } var baseIndex = 1; var ringVertexCount = sliceCount + 1; for (int i = 0; i < stackCount-2; i++) { for (int j = 0; j < sliceCount; j++) { ret.Indices.Add(baseIndex + i*ringVertexCount + j); ret.Indices.Add(baseIndex + i*ringVertexCount + j+1); ret.Indices.Add(baseIndex + (i+1)*ringVertexCount + j); ret.Indices.Add(baseIndex + (i+1)*ringVertexCount + j); ret.Indices.Add(baseIndex + i*ringVertexCount + j+1); ret.Indices.Add(baseIndex + (i+1)*ringVertexCount + j + 1); } } var southPoleIndex = ret.Vertices.Count - 1; baseIndex = southPoleIndex - ringVertexCount; for (int i = 0; i < sliceCount; i++) { ret.Indices.Add(southPoleIndex); ret.Indices.Add(baseIndex+i); ret.Indices.Add(baseIndex+i+1); } return ret; }
public static void CrossMeshRenderer(Chunk chunk, BlockPos pos, MeshData meshData, TextureCollection texture, Block block) { float halfBlock = (Config.Env.BlockSize / 2) + Config.Env.BlockFacePadding; float colliderOffest = 0.05f * Config.Env.BlockSize; float blockHeight = halfBlock * 2 * (block.data2 / 255f); float offsetX = (halfBlock * 2 * ((byte)(block.data3 & 0x0F) / 32f)) - (halfBlock/2); float offsetZ = (halfBlock * 2 * ((byte)((block.data3 & 0xF0) >> 4) / 32f)) - (halfBlock/2); //Converting the position to a vector adjusts it based on block size and gives us real world coordinates for x, y and z Vector3 vPos = pos; Vector3 vPosCollider = pos; vPos += new Vector3(offsetX, 0, offsetZ); float blockLight = ( (block.data1/255f) * Config.Env.BlockLightStrength) + (0.8f*Config.Env.AOStrength); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z + halfBlock)); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock)); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock)); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z - halfBlock)); meshData.AddQuadTriangles(); BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture); meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z - halfBlock)); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock)); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock)); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z + halfBlock)); meshData.AddQuadTriangles(); BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture); meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z + halfBlock)); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock)); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock)); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z - halfBlock)); meshData.AddQuadTriangles(); BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture); meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z - halfBlock)); meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock)); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock)); meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z + halfBlock)); meshData.AddQuadTriangles(); BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture); meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight); meshData.AddVertex(new Vector3(vPosCollider.x - halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z + halfBlock), collisionMesh: true); meshData.AddVertex(new Vector3(vPosCollider.x + halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z + halfBlock), collisionMesh: true); meshData.AddVertex(new Vector3(vPosCollider.x + halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z - halfBlock), collisionMesh: true); meshData.AddVertex(new Vector3(vPosCollider.x - halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z - halfBlock), collisionMesh: true); meshData.AddQuadTriangles(collisionMesh:true); }
void ScaleBlock(Block block, MeshData data) { //Position so it's in the center float minX = float.MaxValue; float maxX = float.MinValue; float minY = float.MaxValue; float maxY = float.MinValue; float minZ = float.MaxValue; float maxZ = float.MinValue; foreach (Vector3 v in data.vertices) { if (v.x < minX) { minX = v.x; } else if (v.x > maxX) { maxX = v.x; } if (v.y < minY) { minY = v.y; } else if (v.y > maxY) { maxY = v.y; } if (v.z < minZ) { minZ = v.z; } else if (v.z > maxZ) { maxZ = v.z; } } //Center position transform.position = new Vector3((minX + maxX) / -2f, (minY + maxY) / -2f, (minZ + maxZ) / -2f); //Find scale float maxDistance = float.MinValue; if (maxX + transform.position.x > maxDistance) { maxDistance = maxX + transform.position.x; } if (maxY + transform.position.y > maxDistance) { maxDistance = maxY + transform.position.y; } if (maxZ + transform.position.y > maxDistance) { maxDistance = maxZ + transform.position.z; } float scale = 1f / maxDistance; //Scale the parent so the position isn't affected parent.localScale = new Vector3(scale, scale, scale); //Adjust position for scale transform.position *= scale; }
protected override MeshData FaceDataSouth(Chunk chunk, int x, int y, int z, MeshData meshData) { meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f)); meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f)); meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f)); meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f)); meshData.AddQuadTempVertexTriangles(); meshData.uv.AddRange(FaceUVs(Direction.south)); return meshData; }
public override MeshData Execute(MeshData input) { MeshData output = new MeshData(); if (input.Vertices.Count < 2) return output; //Calculate rotations Quaternion[] rots = new Quaternion[input.Vertices.Count]; for (int i = 0; i < rots.Length-1;i++) { rots[i] = Quaternion.LookRotation(input.Vertices[i + 1] - input.Vertices[i]); } rots[rots.Length - 1] = rots[rots.Length - 2]; for (int i = 1; i < rots.Length-1;i++) { rots[i] = Quaternion.Slerp(rots[i], rots[i - 1], 0.5f); } //Add points for (int v = 0; v < rots.Length;v++) { for(int p=0;p<Profile.Vertices.Count;p++) { var point = rots[v] * Profile.Vertices[p] + input.Vertices[v]; output.Vertices.Add(point); //MeshHelper.addCubeAtPoint(point, Vector3.one * 0.1f, output); } } //Add triangles for (int s = 0; s < rots.Length-1;s++) { for(int p=0;p<Profile.Vertices.Count-1;p++) { MeshHelper.AddQuad( s * Profile.Vertices.Count + p, (s+1) * Profile.Vertices.Count + p, (s+1) * Profile.Vertices.Count + (p + 1), s * Profile.Vertices.Count + p + 1, output); } MeshHelper.AddQuad( s * Profile.Vertices.Count + Profile.Vertices.Count - 1, (s + 1) * Profile.Vertices.Count + Profile.Vertices.Count - 1, (s + 1) * Profile.Vertices.Count, s * Profile.Vertices.Count, output); } return output; }
protected virtual MeshData FaceDataUp (Chunk chunk, int x, int y, int z, MeshData meshData, int CycleNumber) { meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f)); meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f)); meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f)); meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f)); meshData.AddQuadTriangles(); meshData.uv.AddRange(FaceUVs(Direction.up)); return meshData; }
protected virtual MeshData FaceDataNorth (Chunk chunk, int x, int y, int z, MeshData meshData) { meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f)); meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f)); meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f)); meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f)); meshData.AddQuadTriangles(); meshData.uv.AddRange(FaceUVs(Direction.north)); return meshData; }
public void RegenMesh(ItemStack ingot, bool[,,] Voxels, SmithingRecipe recipeToOutline) { workItemMeshRef?.Dispose(); workItemMeshRef = null; if (ingot == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline); } this.ingot = ingot; MeshData workItemMesh = new MeshData(24, 36, false); TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("ingotpile")), ingot.Collectible.LastCodePart()); MeshData voxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); texId = tpos.atlasTextureId; for (int i = 0; i < voxelMesh.Uv.Length; i++) { voxelMesh.Uv[i] = (i % 2 > 0 ? tpos.y1 : tpos.x1) + voxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size; } voxelMesh.XyzFaces = (int[])CubeMeshUtil.CubeFaceIndices.Clone(); voxelMesh.XyzFacesCount = 6; voxelMesh.Tints = new int[6]; voxelMesh.Flags = new int[24]; voxelMesh.TintsCount = 6; for (int i = 0; i < voxelMesh.Rgba.Length; i++) { voxelMesh.Rgba[i] = 255; } voxelMesh.Rgba2 = null;// voxelMesh.Rgba; MeshData voxelMeshOffset = voxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int y = 10; y < 16; y++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, y, z]) { continue; } float px = x / 16f; float py = y / 16f; float pz = z / 16f; for (int i = 0; i < voxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + voxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = py + voxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + voxelMesh.xyz[i + 2]; } float offsetX = (px * 32f) / api.BlockTextureAtlas.Size; float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size; for (int i = 0; i < voxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = voxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = voxelMesh.Uv[i + 1] + offsetZ; } workItemMesh.AddMeshData(voxelMeshOffset); } } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
public static MeshData CreateSphere(float radius, int sliceCount, int stackCount) { var meshData = new MeshData(); // // Compute the vertices stating at the top pole and moving down the stacks. // // Poles: note that there will be texture coordinate distortion as there is // not a unique point on the texture map to assign to the pole when mapping // a rectangular texture onto a sphere. // Top vertex. meshData.Vertices.Add(new Vertex(new Vector3(0, radius, 0), new Vector3(0, 1, 0), new Vector3(1, 0, 0), Vector2.Zero)); float phiStep = MathUtil.Pi / stackCount; float thetaStep = 2f * MathUtil.Pi / sliceCount; for (int i = 1; i <= stackCount - 1; i++) { float phi = i * phiStep; for (int j = 0; j <= sliceCount; j++) { float theta = j * thetaStep; // Spherical to cartesian. var pos = new Vector3( radius * MathHelper.Sinf(phi) * MathHelper.Cosf(theta), radius * MathHelper.Cosf(phi), radius * MathHelper.Sinf(phi) * MathHelper.Sinf(theta)); // Partial derivative of P with respect to theta. var tan = new Vector3( -radius * MathHelper.Sinf(phi) * MathHelper.Sinf(theta), 0, radius * MathHelper.Sinf(phi) * MathHelper.Cosf(theta)); tan.Normalize(); Vector3 norm = pos; norm.Normalize(); var texCoord = new Vector2(theta / (MathUtil.Pi * 2), phi / MathUtil.Pi); meshData.Vertices.Add(new Vertex(pos, norm, tan, texCoord)); } } // Bottom vertex. meshData.Vertices.Add(new Vertex(0, -radius, 0, 0, -1, 0, 1, 0, 0, 0, 1)); // // Compute indices for top stack. The top stack was written first to the vertex buffer // and connects the top pole to the first ring. // for (int i = 1; i <= sliceCount; i++) { meshData.Indices32.Add(0); meshData.Indices32.Add(i + 1); meshData.Indices32.Add(i); } // // Compute indices for inner stacks (not connected to poles). // int baseIndex = 1; int ringVertexCount = sliceCount + 1; for (int i = 0; i < stackCount - 2; i++) { for (int j = 0; j < sliceCount; j++) { meshData.Indices32.Add(baseIndex + i * ringVertexCount + j); meshData.Indices32.Add(baseIndex + i * ringVertexCount + j + 1); meshData.Indices32.Add(baseIndex + (i + 1) * ringVertexCount + j); meshData.Indices32.Add(baseIndex + (i + 1) * ringVertexCount + j); meshData.Indices32.Add(baseIndex + i * ringVertexCount + j + 1); meshData.Indices32.Add(baseIndex + (i + 1) * ringVertexCount + j + 1); } } // // Compute indices for bottom stack. The bottom stack was written last to the vertex buffer // and connects the bottom pole to the bottom ring. // // South pole vertex was added last. int southPoleIndex = meshData.Vertices.Count - 1; // Offset the indices to the index of the first vertex in the last ring. baseIndex = southPoleIndex - ringVertexCount; for (int i = 0; i < sliceCount; i++) { meshData.Indices32.Add(southPoleIndex); meshData.Indices32.Add(baseIndex + i); meshData.Indices32.Add(baseIndex + i + 1); } return(meshData); }
public static MeshData CreateGeosphere(float radius, int numSubdivisions) { var meshData = new MeshData(); // Put a cap on the number of subdivisions. numSubdivisions = Math.Min(numSubdivisions, 6); // Approximate a sphere by tesselating an icosahedron. const float x = 0.525731f; const float z = 0.850651f; Vector3[] positions = { new Vector3(-x, 0, z), new Vector3(x, 0, z), new Vector3(-x, 0, -z), new Vector3(x, 0, -z), new Vector3(0, z, x), new Vector3(0, z, -x), new Vector3(0, -z, x), new Vector3(0, -z, -x), new Vector3(z, x, 0), new Vector3(-z, x, 0), new Vector3(z, -x, 0), new Vector3(-z, -x, 0) }; int[] indices = { 1, 4, 0, 4, 9, 0, 4, 5, 9, 8, 5, 4, 1, 8, 4, 1, 10, 8, 10, 3, 8, 8, 3, 5, 3, 2, 5, 3, 7, 2, 3, 10, 7, 10, 6, 7, 6, 11, 7, 6, 0, 11, 6, 1, 0, 10, 1, 6, 11, 0, 9, 2, 11, 9, 5, 2, 9, 11, 2, 7 }; meshData.Vertices.AddRange(positions.Select(position => new Vertex { Position = position })); meshData.Indices32.AddRange(indices); for (int i = 0; i < numSubdivisions; i++) { Subdivide(meshData); } // Project vertices onto sphere and scale. for (int i = 0; i < positions.Length; i++) { // Project onto unit sphere. Vector3 normal = Vector3.Normalize(positions[i]); // Project onto sphere. Vector3 position = radius * normal; // Derive texture coordinates from spherical coordinates. float theta = MathHelper.Atan2f(positions[i].Z, positions[i].X) + MathUtil.Pi; float phi = MathHelper.Acosf(positions[i].Y / radius); Vector2 texCoord = new Vector2( theta / MathUtil.TwoPi, phi / MathUtil.TwoPi); // Partial derivative of P with respect to theta. Vector3 tangentU = new Vector3( -radius * MathHelper.Sinf(phi) * MathHelper.Sinf(theta), 0.0f, radius * MathHelper.Sinf(phi) * MathHelper.Cosf(theta)); meshData.Vertices.Add(new Vertex(position, normal, tangentU, texCoord)); } return(meshData); }
private static void BuildCylinderSide(float bottomRadius, float topRadius, float height, int sliceCount, int stackCount, MeshData meshData) { float stackHeight = height / stackCount; // Amount to increment radius as we move up each stack level from bottom to top. float radiusStep = (topRadius - bottomRadius) / stackCount; int ringCount = stackCount + 1; // Compute vertices for each stack ring starting at the bottom and moving up. for (int i = 0; i < ringCount; i++) { float y = -0.5f * height + i * stackHeight; float r = bottomRadius + i * radiusStep; // Vertices of ring. float dTheta = 2.0f * MathUtil.Pi / sliceCount; for (int j = 0; j <= sliceCount; j++) { float c = MathHelper.Cosf(j * dTheta); float s = MathHelper.Sinf(j * dTheta); var pos = new Vector3(r * c, y, r * s); var uv = new Vector2((float)j / sliceCount, 1f - (float)i / stackCount); var tangent = new Vector3(-s, 0.0f, c); float dr = bottomRadius - topRadius; var bitangent = new Vector3(dr * c, -height, dr * s); var normal = Vector3.Cross(tangent, bitangent); normal.Normalize(); meshData.Vertices.Add(new Vertex(pos, normal, tangent, uv)); } } // Add one because we duplicate the first and last vertex per ring // since the texture coordinates are different. int ringVertexCount = sliceCount + 1; // Compute indices for each stack. for (int i = 0; i < stackCount; i++) { for (int j = 0; j < sliceCount; j++) { meshData.Indices32.Add(i * ringVertexCount + j); meshData.Indices32.Add((i + 1) * ringVertexCount + j); meshData.Indices32.Add((i + 1) * ringVertexCount + j + 1); meshData.Indices32.Add(i * ringVertexCount + j); meshData.Indices32.Add((i + 1) * ringVertexCount + j + 1); meshData.Indices32.Add(i * ringVertexCount + j + 1); } } }
/// <summary> /// Checkes all neighbours of the given tile and stitches the edges to achieve a smooth mesh surface. /// </summary> /// <param name="tileId"></param> /// <param name="mesh"></param> private void FixStitches(UnwrappedTileId tileId, MeshData mesh) { var meshVertCount = mesh.Vertices.Count; _stitchTarget = null; _meshData.TryGetValue(tileId.North, out _stitchTarget); var cap = _elevationOptions.modificationOptions.sampleCount - 1; if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); for (int i = 0; i < cap; i++) { mesh.Vertices[6 * i] = new Vector3( mesh.Vertices[6 * i].x, _stitchTargetMeshData.Vertices[6 * cap * (cap - 1) + 6 * i + 2].y, mesh.Vertices[6 * i].z); mesh.Vertices[6 * i + 1] = new Vector3( mesh.Vertices[6 * i + 1].x, _stitchTargetMeshData.Vertices[6 * cap * (cap - 1) + 6 * i + 4].y, mesh.Vertices[6 * i + 1].z); mesh.Vertices[6 * i + 3] = new Vector3( mesh.Vertices[6 * i + 3].x, _stitchTargetMeshData.Vertices[6 * cap * (cap - 1) + 6 * i + 4].y, mesh.Vertices[6 * i + 3].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.South, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); for (int i = 0; i < cap; i++) { mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 2] = new Vector3( mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 2].x, _stitchTargetMeshData.Vertices[6 * i].y, mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 2].z); mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 5] = new Vector3( mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 5].x, _stitchTargetMeshData.Vertices[6 * i].y, mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 5].z); mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 4] = new Vector3( mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 4].x, _stitchTargetMeshData.Vertices[6 * i + 3].y, mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 4].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.West, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); for (int i = 0; i < cap; i++) { mesh.Vertices[6 * cap * i] = new Vector3( mesh.Vertices[6 * cap * i].x, _stitchTargetMeshData.Vertices[6 * cap * i + 6 * cap - 5].y, mesh.Vertices[6 * cap * i].z); mesh.Vertices[6 * cap * i + 2] = new Vector3( mesh.Vertices[6 * cap * i + 2].x, _stitchTargetMeshData.Vertices[6 * cap * i + 6 * cap - 2].y, mesh.Vertices[6 * cap * i + 2].z); mesh.Vertices[6 * cap * i + 5] = new Vector3( mesh.Vertices[6 * cap * i + 5].x, _stitchTargetMeshData.Vertices[6 * cap * i + 6 * cap - 2].y, mesh.Vertices[6 * cap * i + 5].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.East, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); for (int i = 0; i < cap; i++) { mesh.Vertices[6 * cap * i + 6 * cap - 5] = new Vector3( mesh.Vertices[6 * cap * i + 6 * cap - 5].x, _stitchTargetMeshData.Vertices[6 * cap * i].y, mesh.Vertices[6 * cap * i + 6 * cap - 5].z); mesh.Vertices[6 * cap * i + 6 * cap - 3] = new Vector3( mesh.Vertices[6 * cap * i + 6 * cap - 3].x, _stitchTargetMeshData.Vertices[6 * cap * i].y, mesh.Vertices[6 * cap * i + 6 * cap - 3].z); mesh.Vertices[6 * cap * i + 6 * cap - 2] = new Vector3( mesh.Vertices[6 * cap * i + 6 * cap - 2].x, _stitchTargetMeshData.Vertices[6 * cap * i + 5].y, mesh.Vertices[6 * cap * i + 6 * cap - 2].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.NorthWest, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); mesh.Vertices[0] = new Vector3( mesh.Vertices[0].x, _stitchTargetMeshData.Vertices[meshVertCount - 2].y, mesh.Vertices[0].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.NorthEast, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); mesh.Vertices[6 * cap - 5] = new Vector3( mesh.Vertices[6 * cap - 5].x, _stitchTargetMeshData.Vertices[6 * (cap - 1) * cap + 2].y, mesh.Vertices[6 * cap - 5].z); mesh.Vertices[6 * cap - 3] = new Vector3( mesh.Vertices[6 * cap - 3].x, _stitchTargetMeshData.Vertices[6 * (cap - 1) * cap + 2].y, mesh.Vertices[6 * cap - 3].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.SouthWest, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); mesh.Vertices[6 * (cap - 1) * cap + 2] = new Vector3( mesh.Vertices[6 * (cap - 1) * cap + 2].x, _stitchTargetMeshData.Vertices[6 * cap - 5].y, mesh.Vertices[6 * (cap - 1) * cap + 2].z); mesh.Vertices[6 * (cap - 1) * cap + 5] = new Vector3( mesh.Vertices[6 * (cap - 1) * cap + 5].x, _stitchTargetMeshData.Vertices[6 * cap - 5].y, mesh.Vertices[6 * (cap - 1) * cap + 5].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.SouthEast, out _stitchTarget); if (_stitchTarget != null) { _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); mesh.Vertices[6 * cap * cap - 2] = new Vector3( mesh.Vertices[6 * cap * cap - 2].x, _stitchTargetMeshData.Vertices[0].y, mesh.Vertices[6 * cap * cap - 2].z); } }
/// <summary> /// Checkes all neighbours of the given tile and stitches the edges to achieve a smooth mesh surface. /// </summary> /// <param name="tile"></param> /// <param name="mesh"></param> private void FixStitches(UnwrappedTileId tileId, MeshData mesh) { var meshVertCount = mesh.Vertices.Count; _stitchTarget = null; _meshData.TryGetValue(tileId.North, out _stitchTarget); var cap = _sampleCount - 1; if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < cap; i++) { mesh.Vertices[6 * i] = new Vector3( mesh.Vertices[6 * i].x, _stitchTargetMeshData.Vertices[6 * cap * (cap - 1) + 6 * i + 2].y, mesh.Vertices[6 * i].z); mesh.Vertices[6 * i + 1] = new Vector3( mesh.Vertices[6 * i + 1].x, _stitchTargetMeshData.Vertices[6 * cap * (cap - 1) + 6 * i + 4].y, mesh.Vertices[6 * i + 1].z); mesh.Vertices[6 * i + 3] = new Vector3( mesh.Vertices[6 * i + 3].x, _stitchTargetMeshData.Vertices[6 * cap * (cap - 1) + 6 * i + 4].y, mesh.Vertices[6 * i + 3].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.South, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < cap; i++) { mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 2] = new Vector3( mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 2].x, _stitchTargetMeshData.Vertices[6 * i].y, mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 2].z); mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 5] = new Vector3( mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 5].x, _stitchTargetMeshData.Vertices[6 * i].y, mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 5].z); mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 4] = new Vector3( mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 4].x, _stitchTargetMeshData.Vertices[6 * i + 3].y, mesh.Vertices[6 * cap * (cap - 1) + 6 * i + 4].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.West, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < cap; i++) { mesh.Vertices[6 * cap * i] = new Vector3( mesh.Vertices[6 * cap * i].x, _stitchTargetMeshData.Vertices[6 * cap * i + 6 * cap - 5].y, mesh.Vertices[6 * cap * i].z); mesh.Vertices[6 * cap * i + 2] = new Vector3( mesh.Vertices[6 * cap * i + 2].x, _stitchTargetMeshData.Vertices[6 * cap * i + 6 * cap - 2].y, mesh.Vertices[6 * cap * i + 2].z); mesh.Vertices[6 * cap * i + 5] = new Vector3( mesh.Vertices[6 * cap * i + 5].x, _stitchTargetMeshData.Vertices[6 * cap * i + 6 * cap - 2].y, mesh.Vertices[6 * cap * i + 5].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.East, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < cap; i++) { mesh.Vertices[6 * cap * i + 6 * cap - 5] = new Vector3( mesh.Vertices[6 * cap * i + 6 * cap - 5].x, _stitchTargetMeshData.Vertices[6 * cap * i].y, mesh.Vertices[6 * cap * i + 6 * cap - 5].z); mesh.Vertices[6 * cap * i + 6 * cap - 3] = new Vector3( mesh.Vertices[6 * cap * i + 6 * cap - 3].x, _stitchTargetMeshData.Vertices[6 * cap * i].y, mesh.Vertices[6 * cap * i + 6 * cap - 3].z); mesh.Vertices[6 * cap * i + 6 * cap - 2] = new Vector3( mesh.Vertices[6 * cap * i + 6 * cap - 2].x, _stitchTargetMeshData.Vertices[6 * cap * i + 5].y, mesh.Vertices[6 * cap * i + 6 * cap - 2].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.NorthWest, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[0] = new Vector3( mesh.Vertices[0].x, _stitchTargetMeshData.Vertices[meshVertCount - 2].y, mesh.Vertices[0].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.NorthEast, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[6 * cap - 5] = new Vector3( mesh.Vertices[6 * cap - 5].x, _stitchTargetMeshData.Vertices[6 * (cap - 1) * cap + 2].y, mesh.Vertices[6 * cap - 5].z); mesh.Vertices[6 * cap - 3] = new Vector3( mesh.Vertices[6 * cap - 3].x, _stitchTargetMeshData.Vertices[6 * (cap - 1) * cap + 2].y, mesh.Vertices[6 * cap - 3].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.SouthWest, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[6 * (cap - 1) * cap + 2] = new Vector3( mesh.Vertices[6 * (cap - 1) * cap + 2].x, _stitchTargetMeshData.Vertices[6 * cap - 5].y, mesh.Vertices[6 * (cap - 1) * cap + 2].z); mesh.Vertices[6 * (cap - 1) * cap + 5] = new Vector3( mesh.Vertices[6 * (cap - 1) * cap + 5].x, _stitchTargetMeshData.Vertices[6 * cap - 5].y, mesh.Vertices[6 * (cap - 1) * cap + 5].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.SouthEast, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[6 * cap * cap - 2] = new Vector3( mesh.Vertices[6 * cap * cap - 2].x, _stitchTargetMeshData.Vertices[0].y, mesh.Vertices[6 * cap * cap - 2].z); } }
public static void BuildRenderer(Chunk chunk, BlockPos pos, MeshData meshData, BlockDirection blockDirection) { AddQuadToMeshData(chunk, pos, meshData, blockDirection, false); }
private void AddPieSliceVertex(Vector3 vertexPosition, float dist, Vector3 normal, bool lineTurnsLeft, MeshData md) { var triIndexStart = md.Vertices.Count; var extrude = normal * (lineTurnsLeft ? -1 : 1); _vertexList.Add(vertexPosition + extrude * _scaledWidth); _normalList.Add(Constants.Math.Vector3Up); _uvList.Add(new Vector2(1, dist)); _tangentList.Add(normal.Perpendicular() * -1); _index3 = triIndexStart + _vertexList.Count - 1; if (_index1 >= 0 && _index2 >= 0) { _triangleList.Add(_index1); _triangleList.Add(_index3); _triangleList.Add(_index2); if (!lineTurnsLeft) { md.Edges.Add(_index3); md.Edges.Add(_index1); } else { md.Edges.Add(_index2); md.Edges.Add(_index3); } } if (lineTurnsLeft) { _index2 = _index3; } else { _index1 = _index3; } }
static MeshData genCube(int voxelX, int voxelY, int voxelZ, int width, int height, int length, ICoreClientAPI capi, ITexPositionSource texSource, float subPixelPadding, int renderpass, int renderFlags) { MeshData mesh = CubeMeshUtil.GetCube( width / 32f, height / 32f, length / 32f, new Vec3f(voxelX / 16f, voxelY / 16f, voxelZ / 16f) ); float[] sideShadings = CubeMeshUtil.DefaultBlockSideShadingsByFacing; for (int i = 0; i < mesh.Rgba.Length; i += 4) { int faceIndex = i / 4 / 4; // 4 rgba per vertex, 4 vertices per face byte b = (byte)(255 * sideShadings[faceIndex]); mesh.Rgba[i + 0] = mesh.Rgba[i + 1] = mesh.Rgba[i + 2] = b; } mesh.Flags = new int[mesh.VerticesCount]; mesh.Flags.Fill(renderFlags); mesh.RenderPasses = new int[mesh.VerticesCount / 4]; mesh.RenderPassCount = mesh.VerticesCount / 4; for (int i = 0; i < mesh.RenderPassCount; i++) { mesh.RenderPasses[i] = renderpass; } mesh.Tints = new int[mesh.VerticesCount / 4]; mesh.TintsCount = mesh.VerticesCount / 4; mesh.XyzFaces = new int[mesh.VerticesCount / 4]; mesh.XyzFacesCount = mesh.VerticesCount / 4; int k = 0; for (int i = 0; i < 6; i++) { mesh.XyzFaces[i] = i; BlockFacing facing = BlockFacing.ALLFACES[i]; bool isOutside = ( (facing == BlockFacing.NORTH && voxelZ == 0) || (facing == BlockFacing.EAST && voxelX + length == 16) || (facing == BlockFacing.SOUTH && voxelZ + width == 16) || (facing == BlockFacing.WEST && voxelX == 0) || (facing == BlockFacing.UP && voxelY + height == 16) || (facing == BlockFacing.DOWN && voxelY == 0) ) ; TextureAtlasPosition tpos = isOutside ? texSource[facing.Code] : texSource["inside-" + facing.Code]; if (tpos == null) { tpos = texSource[facing.Code]; } for (int j = 0; j < 2 * 4; j++) { mesh.Uv[k] = (j % 2 > 0 ? tpos.y1 : tpos.x1) + mesh.Uv[k] * 32f / texSource.AtlasSize - subPixelPadding; k++; } } return(mesh); }
public void RegenMesh() { Mesh = CreateMesh(api as ICoreClientAPI, VoxelCuboids, Materials); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int borderedSize = heightMap.GetLength(0); int meshSize = borderedSize - 2 * meshSimplificationIncrement; int meshSizeUnsimplified = borderedSize - 2; float topLeftX = (meshSizeUnsimplified - 1) / -2f; float topLeftZ = (meshSizeUnsimplified - 1) / 2f; int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, useFlatShading); int[,] vertexIndicesMap = new int[borderedSize, borderedSize]; int meshVertexIndex = 0; int borderVertexIndex = -1; for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1; if (isBorderVertex) { vertexIndicesMap[x, y] = borderVertexIndex; borderVertexIndex--; } else { vertexIndicesMap[x, y] = meshVertexIndex; meshVertexIndex++; } } } for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { int vertexIndex = vertexIndicesMap[x, y]; Vector2 percent = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize); float height = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier; Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified); meshData.AddVertex(vertexPosition, percent, vertexIndex); if (x < borderedSize - 1 && y < borderedSize - 1) { int a = vertexIndicesMap[x, y]; int b = vertexIndicesMap[x + meshSimplificationIncrement, y]; int c = vertexIndicesMap[x, y + meshSimplificationIncrement]; int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement]; meshData.AddTriangle(a, d, c); meshData.AddTriangle(d, a, b); } vertexIndex++; } } meshData.Finalize(); return(meshData); }
public MeshData GenFoodMixMesh(ItemStack[] contentStacks, CookingRecipe recipe, Vec3f foodTranslate) { MeshData mergedmesh = null; MealTextureSource texSource = new MealTextureSource(capi, mealtextureSourceBlock); var shapePath = recipe.Shape.Base.Clone().WithPathPrefixOnce("shapes/").WithPathAppendixOnce(".json"); bool rotten = ContentsRotten(contentStacks); if (rotten) { shapePath = new AssetLocation("shapes/block/food/meal/rot.json"); } Shape shape = capi.Assets.TryGet(shapePath).ToObject <Shape>(); Dictionary <CookingRecipeIngredient, int> usedIngredQuantities = new Dictionary <CookingRecipeIngredient, int>(); if (rotten) { capi.Tesselator.TesselateShape( "mealpart", shape, out mergedmesh, texSource, new Vec3f(recipe.Shape.rotateX, recipe.Shape.rotateY, recipe.Shape.rotateZ) ); } else { HashSet <string> drawnMeshes = new HashSet <string>(); for (int i = 0; i < contentStacks.Length; i++) { texSource.ForStack = contentStacks[i]; CookingRecipeIngredient ingred = recipe.GetIngrendientFor( contentStacks[i], usedIngredQuantities.Where(val => val.Key.MaxQuantity <= val.Value).Select(val => val.Key).ToArray() ); if (ingred == null) { ingred = recipe.GetIngrendientFor(contentStacks[i]); } else { int cnt = 0; usedIngredQuantities.TryGetValue(ingred, out cnt); cnt++; usedIngredQuantities[ingred] = cnt; } if (ingred == null) { continue; } MeshData meshpart; string[] selectiveElements = null; CookingRecipeStack recipestack = ingred.GetMatchingStack(contentStacks[i]); if (recipestack.ShapeElement != null) { selectiveElements = new string[] { recipestack.ShapeElement } } ; texSource.customTextureMapping = recipestack.TextureMapping; if (drawnMeshes.Contains(recipestack.ShapeElement + recipestack.TextureMapping)) { continue; } drawnMeshes.Add(recipestack.ShapeElement + recipestack.TextureMapping); capi.Tesselator.TesselateShape( "mealpart", shape, out meshpart, texSource, new Vec3f(recipe.Shape.rotateX, recipe.Shape.rotateY, recipe.Shape.rotateZ), 0, 0, 0, null, selectiveElements ); if (mergedmesh == null) { mergedmesh = meshpart; } else { mergedmesh.AddMeshData(meshpart); } } } if (foodTranslate != null && mergedmesh != null) { mergedmesh.Translate(foodTranslate); } return(mergedmesh); }
private static void ProcessPoint(float isolevel, Grid[] grid, MeshData meshData) { /* * Determine the index into the edge table which * tells us which vertices are inside of the surface */ ushort cubeindex = 0; if (grid[0].value < isolevel) { cubeindex |= 1; } if (grid[1].value < isolevel) { cubeindex |= 2; } if (grid[2].value < isolevel) { cubeindex |= 4; } if (grid[3].value < isolevel) { cubeindex |= 8; } if (grid[4].value < isolevel) { cubeindex |= 16; } if (grid[5].value < isolevel) { cubeindex |= 32; } if (grid[6].value < isolevel) { cubeindex |= 64; } if (grid[7].value < isolevel) { cubeindex |= 128; } /* Cube is entirely in/out of the surface */ if (edgeTable[cubeindex] == 0) { return; } /* Find the vertices where the surface intersects the cube */ Vector3[] vertlist = new Vector3[12]; if ((edgeTable[cubeindex] & 1) != 0) { vertlist[0] = VertexInterp(isolevel, grid[0], grid[1]); } if ((edgeTable[cubeindex] & 2) != 0) { vertlist[1] = VertexInterp(isolevel, grid[1], grid[2]); } if ((edgeTable[cubeindex] & 4) != 0) { vertlist[2] = VertexInterp(isolevel, grid[2], grid[3]); } if ((edgeTable[cubeindex] & 8) != 0) { vertlist[3] = VertexInterp(isolevel, grid[3], grid[0]); } if ((edgeTable[cubeindex] & 16) != 0) { vertlist[4] = VertexInterp(isolevel, grid[4], grid[5]); } if ((edgeTable[cubeindex] & 32) != 0) { vertlist[5] = VertexInterp(isolevel, grid[5], grid[6]); } if ((edgeTable[cubeindex] & 64) != 0) { vertlist[6] = VertexInterp(isolevel, grid[6], grid[7]); } if ((edgeTable[cubeindex] & 128) != 0) { vertlist[7] = VertexInterp(isolevel, grid[7], grid[4]); } if ((edgeTable[cubeindex] & 256) != 0) { vertlist[8] = VertexInterp(isolevel, grid[0], grid[4]); } if ((edgeTable[cubeindex] & 512) != 0) { vertlist[9] = VertexInterp(isolevel, grid[1], grid[5]); } if ((edgeTable[cubeindex] & 1024) != 0) { vertlist[10] = VertexInterp(isolevel, grid[2], grid[6]); } if ((edgeTable[cubeindex] & 2048) != 0) { vertlist[11] = VertexInterp(isolevel, grid[3], grid[7]); } /* Create the triangle */ for (int i = 0; triTable[cubeindex, i] != -1; i += 3) { meshData.AddTriangle(vertlist[triTable[cubeindex, i]], vertlist[triTable[cubeindex, i + 1]], vertlist[triTable[cubeindex, i + 2]]); } return; }
public static void BuildCollider(Chunk chunk, BlockPos pos, MeshData meshData, BlockDirection blockDirection) { AddQuadToMeshData(chunk, pos, meshData, blockDirection, true); }
private void AddCurrentVertex(Vector3 vertexPosition, float dist, Vector3 normal, MeshData md, float endLeft = 0, float endRight = 0) { var triIndexStart = md.Vertices.Count; var extrude = normal; if (endLeft != 0) { extrude -= (normal.Perpendicular() * endLeft); } var vert = vertexPosition + extrude * _scaledWidth; _vertexList.Add(vert); _normalList.Add(Constants.Math.Vector3Up); _uvList.Add(new Vector2(1, dist)); _tangentList.Add(normal.Perpendicular() * -1); _index3 = triIndexStart + _vertexList.Count - 1; if (_index1 >= triIndexStart && _index2 >= triIndexStart) { _triangleList.Add(_index1); _triangleList.Add(_index3); _triangleList.Add(_index2); md.Edges.Add(triIndexStart + _vertexList.Count - 1); md.Edges.Add(triIndexStart + _vertexList.Count - 3); } _index1 = _index2; _index2 = _index3; extrude = normal * -1; if (endRight != 0) { extrude -= normal.Perpendicular() * endRight; } _vertexList.Add(vertexPosition + extrude * _scaledWidth); _normalList.Add(Constants.Math.Vector3Up); _uvList.Add(new Vector2(0, dist)); _tangentList.Add(normal.Perpendicular() * -1); _index3 = triIndexStart + _vertexList.Count - 1; if (_index1 >= triIndexStart && _index2 >= triIndexStart) { _triangleList.Add(_index1); _triangleList.Add(_index2); _triangleList.Add(_index3); md.Edges.Add(triIndexStart + _vertexList.Count - 3); md.Edges.Add(triIndexStart + _vertexList.Count - 1); } _index1 = _index2; _index2 = _index3; }
private void CalculateEdgeList(MeshData md, UnityTile tile, float preferredEdgeSectionLength) { }
public static void BuildColors(Chunk chunk, BlockPos pos, MeshData meshData, BlockDirection blockDirection) { bool nSolid = false; bool eSolid = false; bool sSolid = false; bool wSolid = false; bool wnSolid = false; bool neSolid = false; bool esSolid = false; bool swSolid = false; float light = 0; switch (blockDirection) { case BlockDirection.up: nSolid = chunk.GetBlock(pos.Add(0, 1, 1)).controller.IsSolid(BlockDirection.south); eSolid = chunk.GetBlock(pos.Add(1, 1, 0)).controller.IsSolid(BlockDirection.west); sSolid = chunk.GetBlock(pos.Add(0, 1, -1)).controller.IsSolid(BlockDirection.north); wSolid = chunk.GetBlock(pos.Add(-1, 1, 0)).controller.IsSolid(BlockDirection.east); wnSolid = chunk.GetBlock(pos.Add(-1, 1, 1)).controller.IsSolid(BlockDirection.east) && chunk.GetBlock(pos.Add(-1, 1, 1)).controller.IsSolid(BlockDirection.south); neSolid = chunk.GetBlock(pos.Add(1, 1, 1)).controller.IsSolid(BlockDirection.south) && chunk.GetBlock(pos.Add(1, 1, 1)).controller.IsSolid(BlockDirection.west); esSolid = chunk.GetBlock(pos.Add(1, 1, -1)).controller.IsSolid(BlockDirection.west) && chunk.GetBlock(pos.Add(1, 1, -1)).controller.IsSolid(BlockDirection.north); swSolid = chunk.GetBlock(pos.Add(-1, 1, -1)).controller.IsSolid(BlockDirection.north) && chunk.GetBlock(pos.Add(-1, 1, -1)).controller.IsSolid(BlockDirection.east); light = chunk.GetBlock(pos.Add(0, 1, 0)).data1 / 255f; break; case BlockDirection.down: nSolid = chunk.GetBlock(pos.Add(0, -1, -1)).controller.IsSolid(BlockDirection.south); eSolid = chunk.GetBlock(pos.Add(1, -1, 0)).controller.IsSolid(BlockDirection.west); sSolid = chunk.GetBlock(pos.Add(0, -1, 1)).controller.IsSolid(BlockDirection.north); wSolid = chunk.GetBlock(pos.Add(-1, -1, 0)).controller.IsSolid(BlockDirection.east); wnSolid = chunk.GetBlock(pos.Add(-1, -1, -1)).controller.IsSolid(BlockDirection.east) && chunk.GetBlock(pos.Add(-1, -1, -1)).controller.IsSolid(BlockDirection.south); neSolid = chunk.GetBlock(pos.Add(1, -1, -1)).controller.IsSolid(BlockDirection.south) && chunk.GetBlock(pos.Add(1, -1, -1)).controller.IsSolid(BlockDirection.west); esSolid = chunk.GetBlock(pos.Add(1, -1, 1)).controller.IsSolid(BlockDirection.west) && chunk.GetBlock(pos.Add(1, -1, 1)).controller.IsSolid(BlockDirection.north); swSolid = chunk.GetBlock(pos.Add(-1, -1, 1)).controller.IsSolid(BlockDirection.north) && chunk.GetBlock(pos.Add(-1, -1, 1)).controller.IsSolid(BlockDirection.east); light = chunk.GetBlock(pos.Add(0, -1, 0)).data1 / 255f; break; case BlockDirection.north: nSolid = chunk.GetBlock(pos.Add(1, 0, 1)).controller.IsSolid(BlockDirection.west); eSolid = chunk.GetBlock(pos.Add(0, 1, 1)).controller.IsSolid(BlockDirection.down); sSolid = chunk.GetBlock(pos.Add(-1, 0, 1)).controller.IsSolid(BlockDirection.east); wSolid = chunk.GetBlock(pos.Add(0, -1, 1)).controller.IsSolid(BlockDirection.up); esSolid = chunk.GetBlock(pos.Add(-1, 1, 1)).controller.IsSolid(BlockDirection.east) && chunk.GetBlock(pos.Add(-1, 1, 1)).controller.IsSolid(BlockDirection.south); neSolid = chunk.GetBlock(pos.Add(1, 1, 1)).controller.IsSolid(BlockDirection.south) && chunk.GetBlock(pos.Add(1, 1, 1)).controller.IsSolid(BlockDirection.west); wnSolid = chunk.GetBlock(pos.Add(1, -1, 1)).controller.IsSolid(BlockDirection.west) && chunk.GetBlock(pos.Add(1, -1, 1)).controller.IsSolid(BlockDirection.north); swSolid = chunk.GetBlock(pos.Add(-1, -1, 1)).controller.IsSolid(BlockDirection.north) && chunk.GetBlock(pos.Add(-1, -1, 1)).controller.IsSolid(BlockDirection.east); light = chunk.GetBlock(pos.Add(0, 0, 1)).data1 / 255f; break; case BlockDirection.east: nSolid = chunk.GetBlock(pos.Add(1, 0, -1)).controller.IsSolid(BlockDirection.up); eSolid = chunk.GetBlock(pos.Add(1, 1, 0)).controller.IsSolid(BlockDirection.west); sSolid = chunk.GetBlock(pos.Add(1, 0, 1)).controller.IsSolid(BlockDirection.down); wSolid = chunk.GetBlock(pos.Add(1, -1, 0)).controller.IsSolid(BlockDirection.east); esSolid = chunk.GetBlock(pos.Add(1, 1, 1)).controller.IsSolid(BlockDirection.west) && chunk.GetBlock(pos.Add(1, 1, 1)).controller.IsSolid(BlockDirection.north); neSolid = chunk.GetBlock(pos.Add(1, 1, -1)).controller.IsSolid(BlockDirection.south) && chunk.GetBlock(pos.Add(1, 1, -1)).controller.IsSolid(BlockDirection.west); wnSolid = chunk.GetBlock(pos.Add(1, -1, -1)).controller.IsSolid(BlockDirection.east) && chunk.GetBlock(pos.Add(1, -1, -1)).controller.IsSolid(BlockDirection.north); swSolid = chunk.GetBlock(pos.Add(1, -1, 1)).controller.IsSolid(BlockDirection.north) && chunk.GetBlock(pos.Add(1, -1, 1)).controller.IsSolid(BlockDirection.east); light = chunk.GetBlock(pos.Add(1, 0, 0)).data1 / 255f; break; case BlockDirection.south: nSolid = chunk.GetBlock(pos.Add(-1, 0, -1)).controller.IsSolid(BlockDirection.down); eSolid = chunk.GetBlock(pos.Add(0, 1, -1)).controller.IsSolid(BlockDirection.west); sSolid = chunk.GetBlock(pos.Add(1, 0, -1)).controller.IsSolid(BlockDirection.up); wSolid = chunk.GetBlock(pos.Add(0, -1, -1)).controller.IsSolid(BlockDirection.south); esSolid = chunk.GetBlock(pos.Add(1, 1, -1)).controller.IsSolid(BlockDirection.west) && chunk.GetBlock(pos.Add(1, 1, -1)).controller.IsSolid(BlockDirection.north); neSolid = chunk.GetBlock(pos.Add(-1, 1, -1)).controller.IsSolid(BlockDirection.south) && chunk.GetBlock(pos.Add(-1, 1, -1)).controller.IsSolid(BlockDirection.west); wnSolid = chunk.GetBlock(pos.Add(-1, -1, -1)).controller.IsSolid(BlockDirection.east) && chunk.GetBlock(pos.Add(-1, -1, -1)).controller.IsSolid(BlockDirection.north); swSolid = chunk.GetBlock(pos.Add(1, -1, -1)).controller.IsSolid(BlockDirection.north) && chunk.GetBlock(pos.Add(1, -1, -1)).controller.IsSolid(BlockDirection.east); light = chunk.GetBlock(pos.Add(0, 0, -1)).data1 / 255f; break; case BlockDirection.west: nSolid = chunk.GetBlock(pos.Add(-1, 0, 1)).controller.IsSolid(BlockDirection.up); eSolid = chunk.GetBlock(pos.Add(-1, 1, 0)).controller.IsSolid(BlockDirection.west); sSolid = chunk.GetBlock(pos.Add(-1, 0, -1)).controller.IsSolid(BlockDirection.down); wSolid = chunk.GetBlock(pos.Add(-1, -1, 0)).controller.IsSolid(BlockDirection.east); esSolid = chunk.GetBlock(pos.Add(-1, 1, -1)).controller.IsSolid(BlockDirection.west) && chunk.GetBlock(pos.Add(-1, 1, -1)).controller.IsSolid(BlockDirection.north); neSolid = chunk.GetBlock(pos.Add(-1, 1, 1)).controller.IsSolid(BlockDirection.south) && chunk.GetBlock(pos.Add(-1, 1, 1)).controller.IsSolid(BlockDirection.west); wnSolid = chunk.GetBlock(pos.Add(-1, -1, 1)).controller.IsSolid(BlockDirection.east) && chunk.GetBlock(pos.Add(-1, -1, 1)).controller.IsSolid(BlockDirection.north); swSolid = chunk.GetBlock(pos.Add(-1, -1, -1)).controller.IsSolid(BlockDirection.north) && chunk.GetBlock(pos.Add(-1, -1, -1)).controller.IsSolid(BlockDirection.east); light = chunk.GetBlock(pos.Add(-1, 0, 0)).data1 / 255f; break; default: Debug.LogError("BlockDirection not recognized"); break; } AddColors(meshData, wnSolid, nSolid, neSolid, eSolid, esSolid, sSolid, swSolid, wSolid, light); }
public override void Run(VectorFeatureUnity feature, MeshData md, float scale) { _scaledWidth = _options.Width * scale; ExtrudeLine(feature, md); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail) { // so further meshes don't have to be as detailed int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int borderedSize = heightMap.GetLength(0); int meshSize = borderedSize - 2 * meshSimplificationIncrement; int meshSizeUnsimplified = borderedSize - 2; float topLeftX = (meshSizeUnsimplified - 1) / -2f; float topLeftZ = (meshSizeUnsimplified - 1) / 2f; int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, meshSettings.useFlatShading); // int vertexIndex = 0; int[,] vertexIndicesMap = new int[borderedSize, borderedSize]; int meshVertexIndex = 0; int borderVertexIndex = -1; for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1; if (isBorderVertex) { vertexIndicesMap[x, y] = borderVertexIndex; borderVertexIndex--; } else { vertexIndicesMap[x, y] = meshVertexIndex; meshVertexIndex++; } } } for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { int vertexIndex = vertexIndicesMap[x, y]; // make sure the UVs are properly centered by subtracting meshSimplificationIncrement Vector2 percent = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize); float height = heightMap[x, y]; Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplified), height, (topLeftZ - percent.y * meshSizeUnsimplified)); //Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplified) * meshSettings.meshScale, height, (topLeftZ - percent.y * meshSizeUnsimplified) * meshSettings.meshScale); meshData.AddVertex(vertexPosition, percent, vertexIndex); // if not bottom or far right, add square // x,y --- x+1,y // | \ | // x,y+i --- x+i,y+i if (x < borderedSize - 1 && y < borderedSize - 1) { int a = vertexIndicesMap[x, y]; int b = vertexIndicesMap[x + meshSimplificationIncrement, y]; int c = vertexIndicesMap[x, y + meshSimplificationIncrement]; int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement]; meshData.AddTriangle(a, d, c); meshData.AddTriangle(d, a, b); } vertexIndex++; } } meshData.ProcessMesh(); return(meshData); // return meshData, not mesh for treading later }
public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null) { _scaledWidth = tile != null ? _options.Width * tile.TileScale : _options.Width; ExtrudeLine(feature, md); }
public override MeshData Blockdata (Chunk chunk, int x, int y, int z, MeshData meshData) { return(meshData); }
private void ExtrudeLine(VectorFeatureUnity feature, MeshData md) { if (feature.Points.Count < 1) { return; } foreach (var roadSegment in feature.Points) { if (roadSegment.Count < 2) { continue; } ResetFields(); var roadSegmentCount = roadSegment.Count; for (int i = 0; i < roadSegmentCount; i++) { _nextVertex = i != (roadSegmentCount - 1) ? roadSegment[i + 1] : Constants.Math.Vector3Unused; if (_nextNormal != Constants.Math.Vector3Unused) { _prevNormal = _nextNormal; } if (_currentVertex != Constants.Math.Vector3Unused) { _prevVertex = _currentVertex; } _currentVertex = roadSegment[i]; _nextNormal = (_nextVertex != Constants.Math.Vector3Unused) ? (_nextVertex - _currentVertex).normalized.Perpendicular() : _prevNormal; if (_prevNormal == Constants.Math.Vector3Unused) { _prevNormal = _nextNormal; } var joinNormal = (_prevNormal + _nextNormal).normalized; /* joinNormal prevNormal * ↖ ↑ * .________. prevVertex * | * nextNormal ← | currentVertex * | * nextVertex ! * */ var cosHalfAngle = joinNormal.x * _nextNormal.x + joinNormal.z * _nextNormal.z; var miterLength = cosHalfAngle != 0 ? 1 / cosHalfAngle : float.PositiveInfinity; var isSharpCorner = cosHalfAngle < _cosHalfSharpCorner && _prevVertex != Constants.Math.Vector3Unused && _nextVertex != Constants.Math.Vector3Unused; if (isSharpCorner && i > 0) { var prevSegmentLength = Vector3.Distance(_currentVertex, _prevVertex); if (prevSegmentLength > 2 * _sharpCornerOffset) { var dir = (_currentVertex - _prevVertex); var newPrevVertex = _currentVertex - (dir * (_sharpCornerOffset / prevSegmentLength)); _distance += Vector3.Distance(newPrevVertex, _prevVertex); AddCurrentVertex(newPrevVertex, _distance, _prevNormal, md); _prevVertex = newPrevVertex; } } var middleVertex = _prevVertex != Constants.Math.Vector3Unused && _nextVertex != Constants.Math.Vector3Unused; var currentJoin = middleVertex ? _options.JoinType : _options.CapType; if (middleVertex && currentJoin == JoinType.Round) { if (miterLength < _options.RoundLimit) { currentJoin = JoinType.Miter; } else if (miterLength <= 2) { currentJoin = JoinType.Fakeround; } } if (currentJoin == JoinType.Miter && miterLength > _options.MiterLimit) { currentJoin = JoinType.Bevel; } if (currentJoin == JoinType.Bevel) { // The maximum extrude length is 128 / 63 = 2 times the width of the line // so if miterLength >= 2 we need to draw a different type of bevel here. if (miterLength > 2) { currentJoin = JoinType.Flipbevel; } // If the miterLength is really small and the line bevel wouldn't be visible, // just draw a miter join to save a triangle. if (miterLength < _options.MiterLimit) { currentJoin = JoinType.Miter; } } if (_prevVertex != Constants.Math.Vector3Unused) { _distance += Vector3.Distance(_currentVertex, _prevVertex); } if (currentJoin == JoinType.Miter) { joinNormal *= miterLength; AddCurrentVertex(_currentVertex, _distance, joinNormal, md); } else if (currentJoin == JoinType.Flipbevel) { // miter is too big, flip the direction to make a beveled join if (miterLength > 100) { // Almost parallel lines joinNormal = _nextNormal * -1; } else { var direction = (_prevNormal.x * _nextNormal.z - _prevNormal.z * _nextNormal.x) > 0 ? -1 : 1; var bevelLength = miterLength * (_prevNormal + _nextNormal).magnitude / (_prevNormal - _nextNormal).magnitude; joinNormal = joinNormal.Perpendicular() * (bevelLength * direction); } AddCurrentVertex(_currentVertex, _distance, joinNormal, md, 0, 0); AddCurrentVertex(_currentVertex, _distance, joinNormal * -1, md, 0, 0); } else if (currentJoin == JoinType.Bevel || currentJoin == JoinType.Fakeround) { var lineTurnsLeft = (_prevNormal.x * _nextNormal.z - _prevNormal.z * _nextNormal.x) > 0; var offset = (float)-Math.Sqrt(miterLength * miterLength - 1); if (lineTurnsLeft) { _cornerOffsetB = 0; _cornerOffsetA = offset; } else { _cornerOffsetA = 0; _cornerOffsetB = offset; } // Close previous segment with a bevel if (!_startOfLine) { AddCurrentVertex(_currentVertex, _distance, _prevNormal, md, _cornerOffsetA, _cornerOffsetB); } if (currentJoin == JoinType.Fakeround) { // The join angle is sharp enough that a round join would be visible. // Bevel joins fill the gap between segments with a single pie slice triangle. // Create a round join by adding multiple pie slices. The join isn't actually round, but // it looks like it is at the sizes we render lines at. // Add more triangles for sharper angles. // This math is just a good enough approximation. It isn't "correct". var n = Mathf.Floor((0.5f - (cosHalfAngle - 0.5f)) * 8); Vector3 approxFractionalJoinNormal; for (var m = 0f; m < n; m++) { approxFractionalJoinNormal = (_nextNormal * ((m + 1f) / (n + 1f)) + (_prevNormal)).normalized; AddPieSliceVertex(_currentVertex, _distance, approxFractionalJoinNormal, lineTurnsLeft, md); } AddPieSliceVertex(_currentVertex, _distance, joinNormal, lineTurnsLeft, md); //change it to go -1, not sure if it's a good idea but it adds the last vertex in the corner, //as duplicate of next road segment start for (var k = n - 1; k >= -1; k--) { approxFractionalJoinNormal = (_prevNormal * ((k + 1) / (n + 1)) + (_nextNormal)).normalized; AddPieSliceVertex(_currentVertex, _distance, approxFractionalJoinNormal, lineTurnsLeft, md); } //ending corner _index1 = -1; _index2 = -1; } if (_nextVertex != Constants.Math.Vector3Unused) { AddCurrentVertex(_currentVertex, _distance, _nextNormal, md, -_cornerOffsetA, -_cornerOffsetB); } } else if (currentJoin == JoinType.Butt) { if (!_startOfLine) { // Close previous segment with a butt AddCurrentVertex(_currentVertex, _distance, _prevNormal, md, 0, 0); } // Start next segment with a butt if (_nextVertex != Constants.Math.Vector3Unused) { AddCurrentVertex(_currentVertex, _distance, _nextNormal, md, 0, 0); } } else if (currentJoin == JoinType.Square) { if (!_startOfLine) { // Close previous segment with a square cap AddCurrentVertex(_currentVertex, _distance, _prevNormal, md, 1, 1); // The segment is done. Unset vertices to disconnect segments. _index1 = _index2 = -1; } // Start next segment if (_nextVertex != Constants.Math.Vector3Unused) { AddCurrentVertex(_currentVertex, _distance, _nextNormal, md, -1, -1); } } else if (currentJoin == JoinType.Round) { if (_startOfLine) { AddCurrentVertex(_currentVertex, _distance, _prevNormal * 0.33f, md, -2f, -2f); AddCurrentVertex(_currentVertex, _distance, _prevNormal * 0.66f, md, -.7f, -.7f); AddCurrentVertex(_currentVertex, _distance, _prevNormal, md, 0, 0); } else if (_nextVertex == Constants.Math.Vector3Unused) { AddCurrentVertex(_currentVertex, _distance, _prevNormal, md, 0, 0); AddCurrentVertex(_currentVertex, _distance, _prevNormal * 0.66f, md, .7f, .7f); AddCurrentVertex(_currentVertex, _distance, _prevNormal * 0.33f, md, 2f, 2f); _index1 = -1; _index2 = -1; } else { AddCurrentVertex(_currentVertex, _distance, _prevNormal, md, 0, 0); AddCurrentVertex(_currentVertex, _distance, _nextNormal, md, 0, 0); //adding extra vertices instead of switching indexing as it looks better on sharp corners //var t = _index1; //_index1 = _index2; //_index2 = t; } } if (isSharpCorner && i < roadSegmentCount - 1) { var nextSegmentLength = Vector3.Distance(_currentVertex, _nextVertex); if (nextSegmentLength > 2 * _sharpCornerOffset) { var newCurrentVertex = _currentVertex + ((_nextVertex - _currentVertex) * (_sharpCornerOffset / nextSegmentLength)); //._round() _distance += Vector3.Distance(newCurrentVertex, _currentVertex); AddCurrentVertex(newCurrentVertex, _distance, _nextNormal, md); _currentVertex = newCurrentVertex; } } _startOfLine = false; } md.Edges.Add(md.Vertices.Count); md.Edges.Add(md.Vertices.Count + 1); md.Edges.Add(md.Vertices.Count + _vertexList.Count - 1); md.Edges.Add(md.Vertices.Count + _vertexList.Count - 2); md.Vertices.AddRange(_vertexList); md.Normals.AddRange(_normalList); if (md.Triangles.Count == 0) { md.Triangles.Add(new List <int>()); } md.Triangles[0].AddRange(_triangleList); md.Tangents.AddRange(_tangentList); md.UV[0].AddRange(_uvList); } }
public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null) { if (md.Vertices.Count == 0 || feature == null || feature.Points.Count < 1) { return; } _uv.Clear(); _mdVertexCount = md.Vertices.Count; _size = md.TileRect.Size; if (_options.texturingType != UvMapType.Atlas && _options.texturingType != UvMapType.AtlasWithColorPalette) { for (int i = 0; i < _mdVertexCount; i++) { _vert = md.Vertices[i]; if (_options.style == StyleTypes.Satellite) { var fromBottomLeft = new Vector2((float)(((_vert.x + md.PositionInTile.x) / tile.TileScale + _size.x / 2) / _size.x), (float)(((_vert.z + md.PositionInTile.z) / tile.TileScale + _size.x / 2) / _size.x)); _uv.Add(fromBottomLeft); } else if (_options.texturingType == UvMapType.Tiled) { _uv.Add(new Vector2(_vert.x, _vert.z)); } } } else if (_options.texturingType == UvMapType.Atlas || _options.texturingType == UvMapType.AtlasWithColorPalette) { _currentFacade = _options.atlasInfo.Roofs[UnityEngine.Random.Range(0, _options.atlasInfo.Roofs.Count)]; minx = float.MaxValue; miny = float.MaxValue; maxx = float.MinValue; maxy = float.MinValue; _textureUvCoordinates = new Vector2[_mdVertexCount]; _textureDirection = Quaternion.FromToRotation((md.Vertices[0] - md.Vertices[1]), Mapbox.Unity.Constants.Math.Vector3Right); _textureUvCoordinates[0] = new Vector2(0, 0); _firstVert = md.Vertices[0]; for (int i = 1; i < _mdVertexCount; i++) { _vert = md.Vertices[i]; _vertexRelativePos = _vert - _firstVert; _vertexRelativePos = _textureDirection * _vertexRelativePos; _textureUvCoordinates[i] = new Vector2(_vertexRelativePos.x, _vertexRelativePos.z); if (_vertexRelativePos.x < minx) { minx = _vertexRelativePos.x; } if (_vertexRelativePos.x > maxx) { maxx = _vertexRelativePos.x; } if (_vertexRelativePos.z < miny) { miny = _vertexRelativePos.z; } if (_vertexRelativePos.z > maxy) { maxy = _vertexRelativePos.z; } } var width = maxx - minx; var height = maxy - miny; for (int i = 0; i < _mdVertexCount; i++) { _uv.Add(new Vector2( (((_textureUvCoordinates[i].x - minx) / width) * _currentFacade.TextureRect.width) + _currentFacade.TextureRect.x, (((_textureUvCoordinates[i].y - miny) / height) * _currentFacade.TextureRect.height) + _currentFacade.TextureRect.y)); } } md.UV[0].AddRange(_uv); }
public void DrawMesh(MeshData meshData, Texture2D texture) { meshFilter.sharedMesh = meshData.CreateMesh(); meshRenderer.sharedMaterial.mainTexture = texture; }
private static void Subdivide(MeshData meshData) { // Save a copy of the input geometry. Vertex[] verticesCopy = meshData.Vertices.ToArray(); int[] indicesCopy = meshData.Indices32.ToArray(); meshData.Vertices.Clear(); meshData.Indices32.Clear(); // v1 // * // / \ // / \ // m0*-----*m1 // / \ / \ // / \ / \ // *-----*-----* // v0 m2 v2 int numTriangles = indicesCopy.Length / 3; for (int i = 0; i < numTriangles; i++) { Vertex v0 = verticesCopy[indicesCopy[i * 3 + 0]]; Vertex v1 = verticesCopy[indicesCopy[i * 3 + 1]]; Vertex v2 = verticesCopy[indicesCopy[i * 3 + 2]]; // // Generate the midpoints. // Vertex m0 = MidPoint(v0, v1); Vertex m1 = MidPoint(v1, v2); Vertex m2 = MidPoint(v0, v2); // // Add new geometry. // meshData.Vertices.Add(v0); // 0 meshData.Vertices.Add(v1); // 1 meshData.Vertices.Add(v2); // 2 meshData.Vertices.Add(m0); // 3 meshData.Vertices.Add(m1); // 4 meshData.Vertices.Add(m2); // 5 meshData.Indices32.Add(i * 6 + 0); meshData.Indices32.Add(i * 6 + 3); meshData.Indices32.Add(i * 6 + 5); meshData.Indices32.Add(i * 6 + 3); meshData.Indices32.Add(i * 6 + 4); meshData.Indices32.Add(i * 6 + 5); meshData.Indices32.Add(i * 6 + 5); meshData.Indices32.Add(i * 6 + 4); meshData.Indices32.Add(i * 6 + 2); meshData.Indices32.Add(i * 6 + 3); meshData.Indices32.Add(i * 6 + 1); meshData.Indices32.Add(i * 6 + 4); } }
public static bool TesselateBlockAdv(this ITesselatorManager tesselator, Block block, out MeshData tesselated, int x = 0, int y = 0, int z = 0) { int id = block.Id; var tesselatormanager = tesselator as ShapeTesselatorManager; var lod0 = (tesselatormanager.blockModelDatasLod0.ContainsKey(id) ? tesselatormanager.blockModelDatasLod0[id] : null)?.Clone(); var lod1 = tesselatormanager.blockModelDatas[id].Clone(); var lod0alt = tesselatormanager.altblockModelDatasLod0[id]; var lod1alt = tesselatormanager.altblockModelDatasLod1[id]; if (block.HasAlternates && lod1alt != null) { long alternateIndex = block.RandomizeAxes == EnumRandomizeAxes.XYZ ? GameMath.MurmurHash3Mod(x, y, z, lod1alt.Length) : GameMath.MurmurHash3Mod(x, 0, z, lod1alt.Length); tesselated = lod1alt[alternateIndex].Clone(); var lod = lod0alt?[alternateIndex].Clone(); if (lod != null && tesselated != lod) { tesselated.IndicesMax = tesselated.Indices.Count(); lod.IndicesMax = lod.Indices.Count(); tesselated.AddMeshData(lod); } } else { tesselated = lod1; tesselated.IndicesMax = tesselated.Indices.Count(); if (lod0 != null) { lod0.IndicesMax = lod0.Indices.Count(); if (tesselated != lod0) { tesselated.AddMeshData(lod0); } } } tesselated?.CompactBuffers(); return(tesselated != null); }
void GenerateInteriorMeshData(TreeNode rootNode) { meshData_Interior = new MeshData(); GenrateAllInteriorQuads(rootNode); }
protected override GameObject CreateLayer(Tile tile, List <JSONObject> items) { var main = new GameObject("Water Layer"); var meshes = new Dictionary <WaterType, MeshData>(); foreach (var geo in items.Where(x => Query(x))) { var kind = geo["properties"].HasField("kind") ? geo["properties"]["kind"].str.ConvertToWaterType() : WaterType.Water; var typeSettings = FactorySettings.GetSettingsFor <WaterSettings>(kind); //if we dont have a setting defined for that, it'Ll be merged to "unknown" if (!FactorySettings.HasSettingsFor(kind)) { kind = WaterType.Water; } if (!meshes.ContainsKey(kind)) { meshes.Add(kind, new MeshData()); } foreach (var bb in geo["geometry"]["coordinates"].list) { var jo = (bb.list[0].list[0].IsArray) ? bb.list[0] : bb; var count = jo.list.Count - 1; if (count < 3) { continue; } var inp = new InputGeometry(count); for (int i = 0; i < count; i++) { var c = jo.list[i]; var dotMerc = GM.LatLonToMeters(c[1].f, c[0].f); var localMercPos = dotMerc - tile.Rect.Center; inp.AddPoint(localMercPos.x, localMercPos.y); inp.AddSegment(i, (i + 1) % count); } //create mesh, actually just to get vertice&indices //filling last two parameters, horrible call yea CreateMesh(inp, meshes[kind]); //unity cant handle more than 65k on single mesh //so we'll finish current and start a new one if (meshes[kind].Vertices.Count > 64000) { CreateGameObject(kind, meshes[kind], main.transform); meshes[kind] = new MeshData(); } } } foreach (var group in meshes) { CreateGameObject(group.Key, group.Value, main.transform); } return(main); }
void OnMeshDataReceived(MeshData meshData) { meshFilter.mesh = meshData.CreateMesh(); }
public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null) { if (md.Vertices.Count == 0 || feature == null || feature.Points.Count < 1) { return; } if (tile != null) { _scale = tile.TileScale; } //facade texture to decorate this building _currentFacade = _options.atlasInfo.Textures[UnityEngine.Random.Range(0, _options.atlasInfo.Textures.Count)]; //rect is a struct so we're caching this _currentTextureRect = _currentFacade.TextureRect; //this can be moved to initialize or in an if clause if you're sure all your tiles will be same level/scale _singleFloorHeight = (tile.TileScale * _currentFacade.FloorHeight) / _currentFacade.MidFloorCount; _scaledFirstFloorHeight = tile.TileScale * _currentFacade.FirstFloorHeight; _scaledTopFloorHeight = tile.TileScale * _currentFacade.TopFloorHeight; _scaledPreferredWallLength = tile.TileScale * _currentFacade.PreferredEdgeSectionLength; _scaledFloorHeight = _scaledPreferredWallLength * _currentFacade.WallToFloorRatio; _singleColumnLength = _scaledPreferredWallLength / _currentFacade.ColumnCount; //read or force height float maxHeight = 1, minHeight = 0; //query height and push polygon up to create roof //can we do this vice versa and create roof at last? QueryHeight(feature, md, tile, out maxHeight, out minHeight); maxHeight = maxHeight * _options.extrusionScaleFactor * _scale; minHeight = minHeight * _options.extrusionScaleFactor * _scale; height = (maxHeight - minHeight); GenerateRoofMesh(md, minHeight, maxHeight); if (_options.extrusionGeometryType != ExtrusionGeometryType.RoofOnly) { //limiting section heights, first floor gets priority, then we draw top floor, then mid if we still have space finalFirstHeight = Mathf.Min(height, _scaledFirstFloorHeight); finalTopHeight = (height - finalFirstHeight) < _scaledTopFloorHeight ? 0 : _scaledTopFloorHeight; finalMidHeight = Mathf.Max(0, height - (finalFirstHeight + finalTopHeight)); //scaledFloorHeight = midHeight / floorCount; wallTriangles = new List <int>(); //cuts long edges into smaller ones using PreferredEdgeSectionLength currentWallLength = 0; start = Constants.Math.Vector3Zero; wallSegmentDirection = Constants.Math.Vector3Zero; for (int i = 0; i < md.Edges.Count; i += 2) { var v1 = md.Vertices[md.Edges[i]]; var v2 = md.Vertices[md.Edges[i + 1]]; wallDirection = v2 - v1; currentWallLength = Vector3.Distance(v1, v2); _leftOverColumnLength = currentWallLength % _singleColumnLength; start = v1; wallSegmentDirection = (v2 - v1).normalized; //half of leftover column (if _centerSegments ofc) at the begining if (_centerSegments && currentWallLength > _singleColumnLength) { //save left,right vertices and wall length wallSegmentFirstVertex = start; wallSegmentLength = (_leftOverColumnLength / 2); start += wallSegmentDirection * wallSegmentLength; wallSegmentSecondVertex = start; _leftOverColumnLength = _leftOverColumnLength / 2; CreateWall(md); } while (currentWallLength > _singleColumnLength) { wallSegmentFirstVertex = start; //columns fitting wall / max column we have in texture var stepRatio = (float)Math.Min(_currentFacade.ColumnCount, Math.Floor(currentWallLength / _singleColumnLength)) / _currentFacade.ColumnCount; wallSegmentLength = stepRatio * _scaledPreferredWallLength; start += wallSegmentDirection * wallSegmentLength; wallSegmentSecondVertex = start; currentWallLength -= (stepRatio * _scaledPreferredWallLength); CreateWall(md); } //left over column at the end if (_leftOverColumnLength > 0) { wallSegmentFirstVertex = start; wallSegmentSecondVertex = v2; wallSegmentLength = _leftOverColumnLength; CreateWall(md); } } //this first loop is for columns if (_separateSubmesh) { md.Triangles.Add(wallTriangles); } else { md.Triangles.Capacity = md.Triangles.Count + wallTriangles.Count; md.Triangles[0].AddRange(wallTriangles); } } }