Ejemplo n.º 1
0
    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;
    }
Ejemplo n.º 2
0
    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;

	}
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
    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;
    }
Ejemplo n.º 7
0
    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;
    }
Ejemplo n.º 8
0
    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);
 }
Ejemplo n.º 10
0
    //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;
		//}
    }
Ejemplo n.º 11
0
    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;
    }
Ejemplo n.º 12
0
        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;

	}
Ejemplo n.º 14
0
    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;
    }
Ejemplo n.º 15
0
    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
            });
        }
    }
Ejemplo n.º 16
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;
	}
Ejemplo n.º 18
0
	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;
	}
Ejemplo n.º 19
0
 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");
 }
Ejemplo n.º 20
0
 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);
 }
Ejemplo n.º 21
0
    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;
    }
Ejemplo n.º 22
0
 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;
        }
Ejemplo n.º 24
0
        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;
        }
Ejemplo n.º 25
0
    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);
    }
Ejemplo n.º 26
0
	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;
	}
Ejemplo n.º 27
0
    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;
    }
Ejemplo n.º 29
0
    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;
    }
Ejemplo n.º 30
0
    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;
    }
Ejemplo n.º 31
0
        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);
                }
            }
        }
Ejemplo n.º 35
0
        /// <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);
            }
        }
Ejemplo n.º 36
0
        /// <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);
            }
        }
Ejemplo n.º 37
0
 public static void BuildRenderer(Chunk chunk, BlockPos pos, MeshData meshData, BlockDirection blockDirection)
 {
     AddQuadToMeshData(chunk, pos, meshData, blockDirection, false);
 }
Ejemplo n.º 38
0
        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;
            }
        }
Ejemplo n.º 39
0
        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);
        }
Ejemplo n.º 40
0
 public void RegenMesh()
 {
     Mesh = CreateMesh(api as ICoreClientAPI, VoxelCuboids, Materials);
 }
Ejemplo n.º 41
0
    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);
    }
Ejemplo n.º 42
0
        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);
        }
Ejemplo n.º 43
0
    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;
    }
Ejemplo n.º 44
0
 public static void BuildCollider(Chunk chunk, BlockPos pos, MeshData meshData, BlockDirection blockDirection)
 {
     AddQuadToMeshData(chunk, pos, meshData, blockDirection, true);
 }
Ejemplo n.º 45
0
        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)
 {
 }
Ejemplo n.º 47
0
    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);
    }
Ejemplo n.º 48
0
 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
    }
Ejemplo n.º 50
0
 public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
 {
     _scaledWidth = tile != null ? _options.Width * tile.TileScale : _options.Width;
     ExtrudeLine(feature, md);
 }
Ejemplo n.º 51
0
 public override MeshData Blockdata
     (Chunk chunk, int x, int y, int z, MeshData meshData)
 {
     return(meshData);
 }
Ejemplo n.º 52
0
        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);
            }
        }
Ejemplo n.º 53
0
        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);
        }
Ejemplo n.º 54
0
 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);
            }
        }
Ejemplo n.º 56
0
        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);
        }
Ejemplo n.º 57
0
 void GenerateInteriorMeshData(TreeNode rootNode)
 {
     meshData_Interior = new MeshData();
     GenrateAllInteriorQuads(rootNode);
 }
Ejemplo n.º 58
0
        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);
        }
Ejemplo n.º 59
0
 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);
                }
            }
        }