Пример #1
0
		public static Mesh CreateCube(Vector3 scale)
		{
			scale *= .5; // the cube is -1 to 1 and I want it to be -.5 to .5 so it is a unit cube.
			Mesh cube = new Mesh();
			Vertex[] verts = new Vertex[8];
			verts[0] = cube.CreateVertex(new Vector3(-1, -1, 1) * scale);
			verts[1] = cube.CreateVertex(new Vector3(1, -1, 1) * scale);
			verts[2] = cube.CreateVertex(new Vector3(1, 1, 1) * scale);
			verts[3] = cube.CreateVertex(new Vector3(-1, 1, 1) * scale);
			verts[4] = cube.CreateVertex(new Vector3(-1, -1, -1) * scale);
			verts[5] = cube.CreateVertex(new Vector3(1, -1, -1) * scale);
			verts[6] = cube.CreateVertex(new Vector3(1, 1, -1) * scale);
			verts[7] = cube.CreateVertex(new Vector3(-1, 1, -1) * scale);

			// front
			cube.CreateFace(new Vertex[] { verts[0], verts[1], verts[2], verts[3] });
			// left
			cube.CreateFace(new Vertex[] { verts[4], verts[0], verts[3], verts[7] });
			// right
			cube.CreateFace(new Vertex[] { verts[1], verts[5], verts[6], verts[2] });
			// back
			cube.CreateFace(new Vertex[] { verts[4], verts[7], verts[6], verts[5] });
			// top
			cube.CreateFace(new Vertex[] { verts[3], verts[2], verts[6], verts[7] });
			// bottom
			cube.CreateFace(new Vertex[] { verts[4], verts[5], verts[1], verts[0] });

			return cube;
		}
Пример #2
0
		public override List<Vertex> FindVertices(List<Vertex> vertices, Vector3 position, double maxDistanceToConsiderVertexAsSame)
		{
			List<Vertex> foundVertexes = new List<Vertex>();

			Vertex testPos = new Vertex(position);
			int index = vertices.BinarySearch(testPos, this);
			if (index < 0)
			{
				index = ~index;
			}
			// we have the starting index now get all the vertices that are close enough starting from here
			double maxDistanceToConsiderVertexAsSameSquared = maxDistanceToConsiderVertexAsSame * maxDistanceToConsiderVertexAsSame;
			for (int i = index; i < vertices.Count; i++)
			{
				if (Math.Abs(vertices[i].Position.x - position.x) > maxDistanceToConsiderVertexAsSame)
				{
					// we are too far away in x, we are done with this direction
					break;
				}
				AddToListIfSameEnough(vertices, position, foundVertexes, maxDistanceToConsiderVertexAsSameSquared, i);
			}
			for (int i = index - 1; i >= 0; i--)
			{
				if (Math.Abs(vertices[i].Position.x - position.x) > maxDistanceToConsiderVertexAsSame)
				{
					// we are too far away in x, we are done with this direction
					break;
				}
				AddToListIfSameEnough(vertices, position, foundVertexes, maxDistanceToConsiderVertexAsSameSquared, i);
			}

			return foundVertexes;
		}
Пример #3
0
        public FaceEdge(Face face, MeshEdge meshEdge, Vertex vertex)
        {
            this.containingFace = face;
            this.meshEdge = meshEdge;
            this.firstVertex = vertex;

            nextFaceEdge = null;
            prevFaceEdge = null;

            radialNextFaceEdge = radialPrevFaceEdge = this;
        }
Пример #4
0
		public static Mesh CreateTetrahedron()
		{
			Mesh tetrahedron = new Mesh();
			Vector2 basePoint = new Vector2(1, 0);
			double baseOffsetZ = -Math.Sin(MathHelper.DegreesToRadians(30));
			Vertex[] verts = new Vertex[4];
			verts[0] = tetrahedron.CreateVertex(new Vector3(basePoint, baseOffsetZ));
			verts[1] = tetrahedron.CreateVertex(new Vector3(Vector2.Rotate(basePoint, MathHelper.Tau / 3), baseOffsetZ));
			verts[2] = tetrahedron.CreateVertex(new Vector3(Vector2.Rotate(basePoint, 2 * MathHelper.Tau / 3), baseOffsetZ));
			verts[3] = tetrahedron.CreateVertex(new Vector3(0, 0, 1));

			tetrahedron.CreateFace(new Vertex[] { verts[0], verts[2], verts[1] }); // add reversed because we want to see the bottom.
			tetrahedron.CreateFace(new Vertex[] { verts[0], verts[1], verts[3] });
			tetrahedron.CreateFace(new Vertex[] { verts[1], verts[2], verts[3] });
			tetrahedron.CreateFace(new Vertex[] { verts[2], verts[0], verts[3] });

			return tetrahedron;
		}
Пример #5
0
		public static PolygonMesh.Mesh CreateBox(AxisAlignedBoundingBox aabb)
		{
			PolygonMesh.Mesh cube = new PolygonMesh.Mesh();
			Vertex[] verts = new Vertex[8];
			//verts[0] = cube.CreateVertex(new Vector3(-1, -1, 1));
			//verts[1] = cube.CreateVertex(new Vector3(1, -1, 1));
			//verts[2] = cube.CreateVertex(new Vector3(1, 1, 1));
			//verts[3] = cube.CreateVertex(new Vector3(-1, 1, 1));
			//verts[4] = cube.CreateVertex(new Vector3(-1, -1, -1));
			//verts[5] = cube.CreateVertex(new Vector3(1, -1, -1));
			//verts[6] = cube.CreateVertex(new Vector3(1, 1, -1));
			//verts[7] = cube.CreateVertex(new Vector3(-1, 1, -1));

			verts[0] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.z));
			verts[1] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.z));
			verts[2] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.maxXYZ.y, aabb.maxXYZ.z));
			verts[3] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.maxXYZ.y, aabb.maxXYZ.z));
			verts[4] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.minXYZ.y, aabb.minXYZ.z));
			verts[5] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.minXYZ.y, aabb.minXYZ.z));
			verts[6] = cube.CreateVertex(new Vector3(aabb.maxXYZ.x, aabb.maxXYZ.y, aabb.minXYZ.z));
			verts[7] = cube.CreateVertex(new Vector3(aabb.minXYZ.x, aabb.maxXYZ.y, aabb.minXYZ.z));

			// front
			cube.CreateFace(new Vertex[] { verts[0], verts[1], verts[2], verts[3] });
			// left
			cube.CreateFace(new Vertex[] { verts[4], verts[0], verts[3], verts[7] });
			// right
			cube.CreateFace(new Vertex[] { verts[1], verts[5], verts[6], verts[2] });
			// back
			cube.CreateFace(new Vertex[] { verts[4], verts[7], verts[6], verts[5] });
			// top
			cube.CreateFace(new Vertex[] { verts[3], verts[2], verts[6], verts[7] });
			// bottom
			cube.CreateFace(new Vertex[] { verts[4], verts[5], verts[1], verts[0] });

			return cube;
		}
Пример #6
0
		public Vertex CreateVertex(Vector3 position, CreateOption createOption = CreateOption.ReuseExisting, SortOption sortOption = SortOption.SortNow)
		{
			if (createOption == CreateOption.ReuseExisting)
			{
				List<Vertex> existingVertices = FindVertices(position);
				if (existingVertices != null && existingVertices.Count > 0)
				{
					return existingVertices[0];
				}
			}

			Vertex createdVertex = new Vertex(position);
			vertices.Add(createdVertex, sortOption);
			return createdVertex;
		}
Пример #7
0
 public Vertex this[int index]
 {
     get
     {
         if (index == 0)
         {
             return vertex0;
         }
         return vertex1;
     }
     set
     {
         if (index == 0)
         {
             vertex0 = value;
         }
         else
         {
             vertex1 = value;
         }
     }
 }
Пример #8
0
        internal bool IsConnectedTo(Vertex vertexToCheck)
        {
            if (VertexOnEnd[0] == vertexToCheck || VertexOnEnd[1] == vertexToCheck)
            {
                return true;
            }

            return false;
        }
Пример #9
0
        public void RemoveFromMeshEdgeLinksOfVertex(Vertex vertexToRemoveFrom)
        {
            // lets first fix up the MeshEdge ponted to be the vertexToRemoveFrom
            if (vertexToRemoveFrom.firstMeshEdge == this)
            {
                MeshEdge nextMeshEdgeConnectedToThisVertex = vertexToRemoveFrom.firstMeshEdge.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);
                // if this is a radial loop
                if (nextMeshEdgeConnectedToThisVertex == vertexToRemoveFrom.firstMeshEdge)
                {
                    // the vertex is connected to no edges
                    vertexToRemoveFrom.firstMeshEdge = null;
                    return;
                }
                else
                {
                    // hook it up to the next connected mesh edge
                    vertexToRemoveFrom.firstMeshEdge = nextMeshEdgeConnectedToThisVertex;
                }
            }

            // no lets clean up the edge links on the meshe edges that are stil connected to the vertexToRemoveFrom
            MeshEdge nextEdgeThisConnectedTo = GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);
            if (nextEdgeThisConnectedTo == this)
            {
                throw new Exception("You can't disconect when you are the only mesh edge.");
            }

            MeshEdge edgeAfterEdgeWeAreConnectedTo = nextEdgeThisConnectedTo.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);
            if (edgeAfterEdgeWeAreConnectedTo == this)
            {
                // if only 2 edges (this and other) then set the other one to a circular reference to itself
                int indexOnEdgeWeAreConnectedTo = nextEdgeThisConnectedTo.GetVertexEndIndex(vertexToRemoveFrom);
                nextEdgeThisConnectedTo.NextMeshEdgeFromEnd[indexOnEdgeWeAreConnectedTo] = nextEdgeThisConnectedTo;

                // and set this one to null (it has not vertexes)
                VertexOnEnd[GetVertexEndIndex(vertexToRemoveFrom)] = null;
            }
            else
            {
                // we need to find the edge that has a reference to this one
                MeshEdge edgeConnectedToThis = edgeAfterEdgeWeAreConnectedTo;
                while (edgeConnectedToThis.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom) != this)
                {
                    edgeConnectedToThis = edgeConnectedToThis.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);
                }
                int indexOfThisOnOther = nextEdgeThisConnectedTo.GetOpositeVertexEndIndex(vertexToRemoveFrom);
                edgeConnectedToThis.NextMeshEdgeFromEnd[indexOfThisOnOther] = nextEdgeThisConnectedTo;
            }
        }
Пример #10
0
 public int GetVertexEndIndex(Vertex vertexToGetIndexOf)
 {
     if (vertexToGetIndexOf == VertexOnEnd[0])
     {
         return 0;
     }
     else
     {
         if (vertexToGetIndexOf != VertexOnEnd[1])
         {
             // if it is not the first one it must be the other one
             throw new Exception("You must only ask to get the edge links for a MeshEdge that is linked to the given vertex.");
         }
         return 1;
     }
 }
Пример #11
0
        public MeshEdge(Vertex vertex1, Vertex vertex2)
            : this()
        {
            this.VertexOnEnd[0] = vertex1;
            this.VertexOnEnd[1] = vertex2;

            AddToMeshEdgeLinksOfVertex(vertex1);
            AddToMeshEdgeLinksOfVertex(vertex2);
        }
Пример #12
0
		/// <summary>
		/// Unsplit (merge) the edgeToJoin and the edge that it is connected to through vertexToDelete.
		/// Only unsplit the edge if we are reversing what would have been a split (a single vertex connecting only two edges).
		/// </summary>
		/// <param name="edgeToJoin"></param>
		/// <param name="vertexToDelete"></param>
		/// <returns></returns>
		public void UnsplitMeshEdge(MeshEdge edgeToJoin, Vertex vertexToDelete)
		{
			int endToJoinIndex = edgeToJoin.GetVertexEndIndex(vertexToDelete);

			MeshEdge edgeToDelete = edgeToJoin.GetNextMeshEdgeConnectedTo(vertexToDelete);
			if (edgeToDelete.GetNextMeshEdgeConnectedTo(vertexToDelete) != edgeToJoin)
			{
				// make sure the edgeToJoin is a valid unsplit (only one connection)
				throw new Exception("The edge that is being unsplit must be connected to only one other MeshEdge across the vertexToDelete.");
			}

			int otherEndOfEdgeToDelete = edgeToDelete.GetOpositeVertexEndIndex(vertexToDelete);
			MeshEdge edgeToJoinTo = edgeToDelete.NextMeshEdgeFromEnd[otherEndOfEdgeToDelete];

			// if the MeshEdge is part of any faces than we have to fix the faces.
			if (edgeToJoin.firstFaceEdge != null)
			{
				// The edge we split was part of one or more faces, we need to fix the FaceEdge loops
				foreach (FaceEdge faceEdge in edgeToJoin.FaceEdgesSharingMeshEdge())
				{
					FaceEdge faceEdgeToDelete = null;
					if (faceEdge.nextFaceEdge.meshEdge == edgeToDelete)
					{
						faceEdgeToDelete = faceEdge.nextFaceEdge;
						FaceEdge newNextFaceEdge = faceEdgeToDelete.nextFaceEdge;
						newNextFaceEdge.prevFaceEdge = faceEdge;
						faceEdge.nextFaceEdge = newNextFaceEdge;
					}
					else if (faceEdge.prevFaceEdge.meshEdge == edgeToDelete)
					{
						faceEdgeToDelete = faceEdge.prevFaceEdge;
						FaceEdge newPrevFaceEdge = faceEdgeToDelete.prevFaceEdge;
						newPrevFaceEdge.nextFaceEdge = faceEdge;
						faceEdge.prevFaceEdge = newPrevFaceEdge;
					}
					else
					{
						throw new Exception("Either the next or prev edge must be the same as the edge to delete.");
					}

					// if the FaceEdge we are deleting is the one that the face was using as its firstFaceEdge, change it.
					if (faceEdge.containingFace.firstFaceEdge == faceEdgeToDelete)
					{
						faceEdge.containingFace.firstFaceEdge = faceEdge;
					}

					// and clear out the FaceEdge we are deleting to help debugging and other references to it.
					faceEdgeToDelete.nextFaceEdge = null;
					faceEdgeToDelete.prevFaceEdge = null;
					faceEdgeToDelete.radialNextFaceEdge = null;
					faceEdgeToDelete.radialPrevFaceEdge = null;
					faceEdgeToDelete.meshEdge = null;
					faceEdgeToDelete.containingFace = null;
					faceEdgeToDelete.firstVertex = null;
				}
			}

			// fix the MeshEdgeLinks on the edgeToJoin
			{
				edgeToJoin.VertexOnEnd[endToJoinIndex] = edgeToDelete.VertexOnEnd[otherEndOfEdgeToDelete];
				edgeToJoin.NextMeshEdgeFromEnd[endToJoinIndex] = edgeToDelete.NextMeshEdgeFromEnd[otherEndOfEdgeToDelete];
			}

			// Clear all  the data on the deleted vertex and edge so we have less code that will work if it continues to use them.
			vertexToDelete.firstMeshEdge = null;
			edgeToDelete.firstFaceEdge = null;
			edgeToDelete.VertexOnEnd[0] = null;
			edgeToDelete.NextMeshEdgeFromEnd[0] = null;
			edgeToDelete.VertexOnEnd[1] = null;
			edgeToDelete.NextMeshEdgeFromEnd[1] = null;
		}
Пример #13
0
		public void SplitMeshEdge(MeshEdge meshEdgeToSplit, out Vertex vertexCreatedDuringSplit, out MeshEdge meshEdgeCreatedDuringSplit)
		{
			// create our new Vertex and MeshEdge
			{
				// make a new vertex between the existing ones

				// TODO: make this create an interpolated vertex, check if it exits and add it or use the right one.
				//vertexCreatedDuringSplit = meshEdgeToSplit.edgeEndVertex[0].CreateInterpolated(meshEdgeToSplit.edgeEndVertex[1], .5);
				vertexCreatedDuringSplit = CreateVertex((meshEdgeToSplit.VertexOnEnd[0].Position + meshEdgeToSplit.VertexOnEnd[1].Position) / 2);
				// TODO: check if the mesh edge exits and use the existing one (or not)
				meshEdgeCreatedDuringSplit = new MeshEdge();
			}

			// Set the new firstMeshEdge on the new Vertex
			vertexCreatedDuringSplit.firstMeshEdge = meshEdgeCreatedDuringSplit;

			Vertex existingVertexToConectTo = meshEdgeToSplit.VertexOnEnd[1];
			// fix the Vertex references on the MeshEdges
			{
				// and set the edges to point to this new one
				meshEdgeCreatedDuringSplit.VertexOnEnd[0] = vertexCreatedDuringSplit;
				meshEdgeCreatedDuringSplit.VertexOnEnd[1] = existingVertexToConectTo;
				meshEdgeToSplit.VertexOnEnd[1] = vertexCreatedDuringSplit;
			}

			// fix the MeshEdgeLinks on the MeshEdges
			{
				// set the created edge to be connected to the old edges other mesh edges
				meshEdgeCreatedDuringSplit.NextMeshEdgeFromEnd[0] = meshEdgeToSplit;

				// make anything that pointed to the split edge point to the new mesh edge

				meshEdgeToSplit.NextMeshEdgeFromEnd[1] = meshEdgeCreatedDuringSplit;
			}

			// if the MeshEdge is part of a face than we have to fix the face up
			FaceEdge faceEdgeToSplit = meshEdgeToSplit.firstFaceEdge;
			if (faceEdgeToSplit != null)
			{
				foreach (FaceEdge faceEdge in meshEdgeToSplit.FaceEdgesSharingMeshEdge())
				{
					Face currentFace = faceEdge.containingFace;
					FaceEdge newFaceEdge = new FaceEdge(currentFace, meshEdgeCreatedDuringSplit, vertexCreatedDuringSplit);
					newFaceEdge.AddToRadialLoop(meshEdgeCreatedDuringSplit);
					// and inject it into the face loop for this face
					newFaceEdge.prevFaceEdge = faceEdge;
					newFaceEdge.nextFaceEdge = faceEdge.nextFaceEdge;
					faceEdge.nextFaceEdge.prevFaceEdge = newFaceEdge;
					faceEdge.nextFaceEdge = newFaceEdge;
				}
			}
		}
Пример #14
0
		public MeshEdge CreateMeshEdge(Vertex vertex1, Vertex vertex2, CreateOption createOption = CreateOption.ReuseExisting)
		{
			if (false)//!vertices.Contains(vertex1) || !vertices.Contains(vertex2))
			{
				throw new ArgumentException("the two vertices must be in the vertices list before a mesh edge can be made between them.");
			}

			if (vertex1 == vertex2)
			{
				throw new ArgumentException("Your input vertices must not be the same vertex.");
			}

			if (createOption == CreateOption.ReuseExisting)
			{
				MeshEdge existingMeshEdge = vertex1.GetMeshEdgeConnectedToVertex(vertex2);
				if (existingMeshEdge != null)
				{
					return existingMeshEdge;
				}
			}

			MeshEdge createdMeshEdge = new MeshEdge(vertex1, vertex2);

			MeshEdges.Add(createdMeshEdge);

			return createdMeshEdge;
		}
Пример #15
0
		public List<MeshEdge> FindMeshEdges(Vertex vertex1, Vertex vertex2)
		{
			List<MeshEdge> meshEdges = new List<MeshEdge>();

			foreach (MeshEdge meshEdge in vertex1.ConnectedMeshEdges())
			{
				if (meshEdge.IsConnectedTo(vertex2))
				{
					meshEdges.Add(meshEdge);
				}
			}

			return meshEdges;
		}
Пример #16
0
		public void MergeVertices(Vertex vertexToKeep, Vertex vertexToDelete, bool doActualDeletion = true)
		{
#if false // this check is relatively slow
			if (!Vertices.ContainsAVertexAtPosition(vertexToKeep) || !Vertices.ContainsAVertexAtPosition(vertexToDelete))
			{
				throw new Exception("Both vertexes have to be part of this mesh to be merged.");
			}
#endif
			// fix up the mesh edges
			List<MeshEdge> connectedMeshEdges = vertexToDelete.GetConnectedMeshEdges();
			foreach (MeshEdge meshEdgeToFix in connectedMeshEdges)
			{
				// fix up the face edges
				foreach (FaceEdge faceEdge in meshEdgeToFix.FaceEdgesSharingMeshEdge())
				{
					if (faceEdge.firstVertex == vertexToDelete)
					{
						faceEdge.firstVertex = vertexToKeep;
					}
				}

				// fix up the mesh edge
				if (meshEdgeToFix.VertexOnEnd[0] == vertexToDelete)
				{
					meshEdgeToFix.VertexOnEnd[0] = vertexToKeep;
				}
				else if (meshEdgeToFix.VertexOnEnd[1] == vertexToDelete)
				{
					meshEdgeToFix.VertexOnEnd[1] = vertexToKeep;
				}

				// make sure it is in the vertex edge loop
				meshEdgeToFix.AddToMeshEdgeLinksOfVertex(vertexToKeep);
			}

			// delete the vertex
			if (doActualDeletion)
			{
				Vertices.Remove(vertexToDelete);
			}
		}
Пример #17
0
		public void DeleteVertex(Vertex vertex)
		{
			throw new NotImplementedException();
		}
Пример #18
0
		public bool ContainsVertex(Vertex vertexToLookFor)
		{
			return vertices.ContainsAVertexAtPosition(vertexToLookFor);
		}
Пример #19
0
		public static Mesh CreateIcosahedron(double scale = 1)
		{
			Mesh icosahedron = new Mesh();
			double[] icosahedronVertices =
            {
                0, -0.525731, 0.850651,
                0.850651, 0, 0.525731,
                0.850651, 0, -0.525731,
                -0.850651, 0, -0.525731,
                -0.850651, 0, 0.525731,
                -0.525731, 0.850651, 0,
                0.525731, 0.850651, 0,
                0.525731, -0.850651, 0,
                -0.525731, -0.850651, 0,
                0, -0.525731, -0.850651,
                0, 0.525731, -0.850651,
                0, 0.525731, 0.850651
            };

			int[] icosahedronIndicies =
            {
                1, 2, 6,
                1, 7, 2,
                3, 4, 5,
                4, 3, 8,
                6, 5, 11,
                5, 6, 10,
                9, 10, 2,
                10, 9, 3,
                7, 8, 9,
                8, 7, 0,
                11, 0, 1,
                0, 11, 4,
                6, 2, 10,
                1, 6, 11,
                3, 5, 10,
                5, 4, 11,
                2, 7, 9,
                7, 1, 0,
                3, 9, 8,
                4, 8, 0,
            };

			Vertex[] verts = new Vertex[icosahedronVertices.Length / 3];
			for (int i = 0; i < icosahedronVertices.Length / 3; i++)
			{
				verts[i] = icosahedron.CreateVertex(new Vector3(icosahedronVertices[i * 3 + 0], icosahedronVertices[i * 3 + 1], icosahedronVertices[i * 3 + 2]));
			}

			for (int i = 0; i < icosahedronIndicies.Length / 3; i++)
			{
				Vertex[] triangleVertices = new Vertex[]
                {
                    verts[icosahedronIndicies[i * 3 + 0]],
                    verts[icosahedronIndicies[i * 3 + 1]],
                    verts[icosahedronIndicies[i * 3 + 2]],
                };
				icosahedron.CreateFace(triangleVertices);
			}

			icosahedron.Transform(Matrix4X4.CreateScale(scale));

			return icosahedron;
		}
Пример #20
0
		public Face CreateFace(Vertex[] verticesToUse, CreateOption createOption = CreateOption.ReuseExisting)
		{
			if (verticesToUse.Length == 3
				&& (verticesToUse[0].Position == verticesToUse[1].Position
				|| verticesToUse[1].Position == verticesToUse[2].Position
				|| verticesToUse[2].Position == verticesToUse[0].Position))
			{
				return null;
			}
			if (verticesToUse.Length < 3)
			{
				throw new ArgumentException("A face cannot have less than 3 vertices.");
			}

			List<MeshEdge> edgesToUse = new List<MeshEdge>();
			for (int i = 0; i < verticesToUse.Length - 1; i++)
			{
				edgesToUse.Add(CreateMeshEdge(verticesToUse[i], verticesToUse[i + 1], createOption));
			}
			edgesToUse.Add(CreateMeshEdge(verticesToUse[verticesToUse.Length - 1], verticesToUse[0], createOption));

			// make the face and set it's data
			Face createdFace = new Face();

			CreateFaceEdges(verticesToUse, edgesToUse, createdFace);

			createdFace.CalculateNormal();

			faces.Add(createdFace);

			return createdFace;
		}
Пример #21
0
 public MeshEdge GetNextMeshEdgeConnectedTo(Vertex vertex)
 {
     int endVertices = GetVertexEndIndex(vertex);
     return NextMeshEdgeFromEnd[endVertices];
 }
Пример #22
0
		private static void CreateFaceEdges(Vertex[] verticesToUse, List<MeshEdge> edgesToUse, Face createdFace)
		{
			FaceEdge prevFaceEdge = null;
			for (int i = 0; i < verticesToUse.Length - 1; i++)
			{
				MeshEdge currentMeshEdge = edgesToUse[i];
				FaceEdge currentFaceEdge = new FaceEdge(createdFace, currentMeshEdge, verticesToUse[i]);
				if (i == 0)
				{
					createdFace.firstFaceEdge = currentFaceEdge;
				}
				else
				{
					prevFaceEdge.nextFaceEdge = currentFaceEdge;
					currentFaceEdge.prevFaceEdge = prevFaceEdge;
				}
				currentFaceEdge.AddToRadialLoop(currentMeshEdge);
				prevFaceEdge = currentFaceEdge;
			}
			// make the last FaceEdge
			{
				MeshEdge currentMeshEdge = edgesToUse[verticesToUse.Length - 1];
				FaceEdge currentFaceEdge = new FaceEdge(createdFace, currentMeshEdge, verticesToUse[verticesToUse.Length - 1]);
				prevFaceEdge.nextFaceEdge = currentFaceEdge;
				currentFaceEdge.prevFaceEdge = prevFaceEdge;
				currentFaceEdge.nextFaceEdge = createdFace.firstFaceEdge;
				createdFace.firstFaceEdge.prevFaceEdge = currentFaceEdge;
				currentFaceEdge.AddToRadialLoop(currentMeshEdge);
			}
		}
Пример #23
0
 public int GetOpositeVertexEndIndex(Vertex vertexToNotGetIndexOf)
 {
     if (vertexToNotGetIndexOf == VertexOnEnd[0])
     {
         return 1;
     }
     else
     {
         if (vertexToNotGetIndexOf != VertexOnEnd[1])
         {
             throw new Exception("You must only ask to get the edge links for a MeshEdge that is linked to the given vertex.");
         }
         return 0;
     }
 }
Пример #24
0
		public override int Compare(Vertex a, Vertex b)
		{
			return a.Position.x.CompareTo(b.Position.x);
		}
Пример #25
0
        public void AddToMeshEdgeLinksOfVertex(Vertex vertexToAddTo)
        {
            int endIndex = GetVertexEndIndex(vertexToAddTo);

            if (vertexToAddTo.firstMeshEdge == null)
            {
                // the vertex is not currently part of any edge
                // we are the only edge for this vertex so set its links all to this.
                vertexToAddTo.firstMeshEdge = this;
                NextMeshEdgeFromEnd[endIndex] = this;
            }
            else // the vertex is already part of an edge (or many)
            {
                int endIndexOnFirstMeshEdge = vertexToAddTo.firstMeshEdge.GetVertexEndIndex(vertexToAddTo);

                // remember what the one that is there is poiting at
                MeshEdge vertexCurrentNext = vertexToAddTo.firstMeshEdge.NextMeshEdgeFromEnd[endIndexOnFirstMeshEdge];

                // point the one that is there at us
                vertexToAddTo.firstMeshEdge.NextMeshEdgeFromEnd[endIndexOnFirstMeshEdge] = this;

                // and point the one that are already there at this.
                this.NextMeshEdgeFromEnd[endIndex] = vertexCurrentNext;
            }
        }
Пример #26
0
		public bool DeleteVertexFromMeshEdge(MeshEdge meshEdgeDeleteVertexFrom, Vertex vertexToDelete)
		{
			throw new NotImplementedException();
		}
Пример #27
0
 public MeshEdge GetOppositeMeshEdge(Vertex vertexToGetOppositeFor)
 {
     if (vertexToGetOppositeFor == VertexOnEnd[0])
     {
         return NextMeshEdgeFromEnd[1];
     }
     else
     {
         if (vertexToGetOppositeFor != VertexOnEnd[1])
         {
             throw new Exception("You must only ask to get the opposite vertex on a MeshEdge that is linked to the given vertexToGetOppositeFor.");
         }
         return NextMeshEdgeFromEnd[0];
     }
 }
Пример #28
0
		private void DrawVertex(Vertex vertex)
		{
			Vector2 imagePosition = GetImagePosition(vertex.Position);

			DrawCircle(imagePosition, vertexColor);
			WriteStringAtPos(vertex.Data.ID.ToString(), imagePosition, new RGBA_Bytes());
			WriteStringAtPos("{0}".FormatWith(vertex.firstMeshEdge.Data.ID), imagePosition + new Vector2(0, -12), meshEdgeColor);
		}
Пример #29
0
		public Face FindFace(Vertex[] vertices)
		{
			//throw new NotImplementedException();
			return null;
		}
Пример #30
0
		public void SplitFace(Face faceToSplit, Vertex splitStartVertex, Vertex splitEndVertex, out MeshEdge meshEdgeCreatedDuringSplit, out Face faceCreatedDuringSplit)
		{
			if (!ContainsVertex(splitStartVertex) || !ContainsVertex(splitEndVertex))
			{
				throw new Exception("The mesh must contain the vertices you intend to split between.");
			}

			// we may want to be able to double up an edge for some operations (we'll have to see).
			if (FindMeshEdges(splitStartVertex, splitEndVertex).Count > 0)
			{
				// this also ensures that the face is more than 2 sided.
				throw new Exception("You cannot split a face on an existing edge.");
			}

			FaceEdge faceEdgeAfterSplitStart = null;
			FaceEdge faceEdgeAfterSplitEnd = null;
			int count = 0;
			foreach (FaceEdge faceEdge in faceToSplit.FaceEdges())
			{
				if (faceEdge.firstVertex == splitStartVertex)
				{
					faceEdgeAfterSplitStart = faceEdge;
					count++;
				}
				else if (faceEdge.firstVertex == splitEndVertex)
				{
					faceEdgeAfterSplitEnd = faceEdge;
					count++;
				}
				if (count == 2)
				{
					break; // stop if we found both face edges
				}
			}

			meshEdgeCreatedDuringSplit = CreateMeshEdge(splitStartVertex, splitEndVertex);
			faceCreatedDuringSplit = new Face(faceToSplit);

			faces.Add(faceCreatedDuringSplit);

			FaceEdge newFaceEdgeExistingFace = new FaceEdge(faceToSplit, meshEdgeCreatedDuringSplit, splitStartVertex);
			FaceEdge newFaceEdgeForNewFace = new FaceEdge(faceCreatedDuringSplit, meshEdgeCreatedDuringSplit, splitEndVertex);

			// get the new edges injected into the existing loop, spliting it in two.
			newFaceEdgeExistingFace.prevFaceEdge = faceEdgeAfterSplitStart.prevFaceEdge;
			newFaceEdgeForNewFace.prevFaceEdge = faceEdgeAfterSplitEnd.prevFaceEdge;

			faceEdgeAfterSplitStart.prevFaceEdge.nextFaceEdge = newFaceEdgeExistingFace;
			faceEdgeAfterSplitEnd.prevFaceEdge.nextFaceEdge = newFaceEdgeForNewFace;

			newFaceEdgeExistingFace.nextFaceEdge = faceEdgeAfterSplitEnd;
			newFaceEdgeForNewFace.nextFaceEdge = faceEdgeAfterSplitStart;

			faceEdgeAfterSplitStart.prevFaceEdge = newFaceEdgeForNewFace;
			faceEdgeAfterSplitEnd.prevFaceEdge = newFaceEdgeExistingFace;

			// make sure the first face edge of each face is valid
			faceToSplit.firstFaceEdge = newFaceEdgeExistingFace;
			faceCreatedDuringSplit.firstFaceEdge = newFaceEdgeForNewFace;

			// make sure the FaceEdges of the new face all point to the new face.
			foreach (FaceEdge faceEdge in faceCreatedDuringSplit.firstFaceEdge.NextFaceEdges())
			{
				faceEdge.containingFace = faceCreatedDuringSplit;
			}

			newFaceEdgeExistingFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
			newFaceEdgeForNewFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
		}