예제 #1
0
        public static Mesh MeshFromPolygons(List <CsgPolygon> polygons)
        {
            Mesh model = new Mesh();
            HashSet <PolygonMesh.Vertex> vertices = new HashSet <PolygonMesh.Vertex>();

            for (int polygonIndex = 0; polygonIndex < polygons.Count; polygonIndex++)
            {
                CsgPolygon poly = polygons[polygonIndex];
                vertices.Clear();

                for (int vertexIndex = 0; vertexIndex < poly.vertices.Count; vertexIndex++)
                {
                    vertices.Add(model.CreateVertex(poly.vertices[vertexIndex].Position));
                }

                if (vertices.Count > 2)
                {
                    model.CreateFace(vertices.ToArray());
                }
            }

            return(model);
        }
예제 #2
0
        // Split `polygon` by this plane if needed, then put the polygon or polygon
        // fragments in the appropriate lists. Coplanar polygons go into either
        // `coplanarFront` or `coplanarBack` depending on their orientation with
        // respect to this plane. Polygons in front or in back of this plane go into
        // either `front` or `back`.
        public void SplitPolygon(CsgPolygon polygon, List <CsgPolygon> coplanarFront, List <CsgPolygon> coplanarBack, List <CsgPolygon> front, List <CsgPolygon> back)
        {
            double splitTolerance = 0.00001;
            // Classify each point as well as the entire polygon into one of the above
            // four classes.
            PolyType        polygonType = PolyType.COPLANAR;
            List <PolyType> types       = new List <PolyType>();

            for (int i = 0; i < polygon.vertices.Count; i++)
            {
                double   t    = Vector3.Dot(this.normal, polygon.vertices[i].Position) - this.w;
                PolyType type = (t < -splitTolerance) ? PolyType.BACK : ((t > splitTolerance) ? PolyType.FRONT : PolyType.COPLANAR);
                polygonType |= type;
                types.Add(type);
            }

            // Put the polygon in the correct list, splitting it when necessary.
            switch (polygonType)
            {
            case PolyType.COPLANAR:
            {
                if (Vector3.Dot(this.normal, polygon.plane.normal) > 0)
                {
                    coplanarFront.Add(polygon);
                }
                else
                {
                    coplanarBack.Add(polygon);
                }
                break;
            }

            case PolyType.FRONT:
            {
                front.Add(polygon);
                break;
            }

            case PolyType.BACK:
            {
                back.Add(polygon);
                break;
            }

            case PolyType.SPANNING:
            {
                List <Vertex> frontVertices = new List <Vertex>();
                List <Vertex> backVertices  = new List <Vertex>();
                for (int firstVertexIndex = 0; firstVertexIndex < polygon.vertices.Count; firstVertexIndex++)
                {
                    int      nextVertexIndex = (firstVertexIndex + 1) % polygon.vertices.Count;
                    PolyType firstPolyType   = types[firstVertexIndex];
                    PolyType nextPolyType    = types[nextVertexIndex];
                    Vertex   firstVertex     = polygon.vertices[firstVertexIndex];
                    Vertex   nextVertex      = polygon.vertices[nextVertexIndex];
                    if (firstPolyType != PolyType.BACK)
                    {
                        frontVertices.Add(firstVertex);
                    }

                    if (firstPolyType != PolyType.FRONT)
                    {
                        backVertices.Add(firstVertex);
                    }

                    if ((firstPolyType | nextPolyType) == PolyType.SPANNING)
                    {
                        double  planDotFirstVertex   = Vector3.Dot(this.normal, firstVertex.Position);
                        double  firstDistToPlane     = this.w - planDotFirstVertex;
                        Vector3 deltaFromFirstToNext = nextVertex.Position - firstVertex.Position;
                        double  t         = firstDistToPlane / Vector3.Dot(this.normal, deltaFromFirstToNext);
                        Vertex  newVertex = firstVertex.CreateInterpolated(nextVertex, t);
                        frontVertices.Add(newVertex);
                        backVertices.Add(newVertex);
                    }
                }

                if (frontVertices.Count >= 3)
                {
                    front.Add(new CsgPolygon(frontVertices));
                }

                if (backVertices.Count >= 3)
                {
                    back.Add(new CsgPolygon(backVertices));
                }
            }
            break;

            default:
                throw new NotImplementedException();
            }
        }
예제 #3
0
		// Split `polygon` by this plane if needed, then put the polygon or polygon
		// fragments in the appropriate lists. Coplanar polygons go into either
		// `coplanarFront` or `coplanarBack` depending on their orientation with
		// respect to this plane. Polygons in front or in back of this plane go into
		// either `front` or `back`.
		public void SplitPolygon(CsgPolygon polygon, List<CsgPolygon> coplanarFront, List<CsgPolygon> coplanarBack, List<CsgPolygon> front, List<CsgPolygon> back)
		{
			double splitTolerance = 0.00001;
			// Classify each point as well as the entire polygon into one of the above
			// four classes.
			PolyType polygonType = PolyType.COPLANAR;
			List<PolyType> types = new List<PolyType>();

			for (int i = 0; i < polygon.vertices.Count; i++)
			{
				double t = Vector3.Dot(this.normal, polygon.vertices[i].Position) - this.w;
				PolyType type = (t < -splitTolerance) ? PolyType.BACK : ((t > splitTolerance) ? PolyType.FRONT : PolyType.COPLANAR);
				polygonType |= type;
				types.Add(type);
			}

			// Put the polygon in the correct list, splitting it when necessary.
			switch (polygonType)
			{
				case PolyType.COPLANAR:
					{
						if (Vector3.Dot(this.normal, polygon.plane.normal) > 0)
						{
							coplanarFront.Add(polygon);
						}
						else
						{
							coplanarBack.Add(polygon);
						}
						break;
					}
				case PolyType.FRONT:
					{
						front.Add(polygon);
						break;
					}
				case PolyType.BACK:
					{
						back.Add(polygon);
						break;
					}
				case PolyType.SPANNING:
					{
						List<Vertex> frontVertices = new List<Vertex>();
						List<Vertex> backVertices = new List<Vertex>();
						for (int firstVertexIndex = 0; firstVertexIndex < polygon.vertices.Count; firstVertexIndex++)
						{
							int nextVertexIndex = (firstVertexIndex + 1) % polygon.vertices.Count;
							PolyType firstPolyType = types[firstVertexIndex];
							PolyType nextPolyType = types[nextVertexIndex];
							Vertex firstVertex = polygon.vertices[firstVertexIndex];
							Vertex nextVertex = polygon.vertices[nextVertexIndex];
							if (firstPolyType != PolyType.BACK)
							{
								frontVertices.Add(firstVertex);
							}

							if (firstPolyType != PolyType.FRONT)
							{
								backVertices.Add(firstVertex);
							}

							if ((firstPolyType | nextPolyType) == PolyType.SPANNING)
							{
								double planDotFirstVertex = Vector3.Dot(this.normal, firstVertex.Position);
								double firstDistToPlane = this.w - planDotFirstVertex;
								Vector3 deltaFromFirstToNext = nextVertex.Position - firstVertex.Position;
								double t = firstDistToPlane / Vector3.Dot(this.normal, deltaFromFirstToNext);
								Vertex newVertex = firstVertex.CreateInterpolated(nextVertex, t);
								frontVertices.Add(newVertex);
								backVertices.Add(newVertex);
							}
						}

						if (frontVertices.Count >= 3)
						{
							front.Add(new CsgPolygon(frontVertices));
						}

						if (backVertices.Count >= 3)
						{
							back.Add(new CsgPolygon(backVertices));
						}
					}
					break;

				default:
					throw new NotImplementedException();
			}
		}
예제 #4
0
        // Split `polygon` by this plane if needed, then put the polygon or polygon
        // fragments in the appropriate lists. Coplanar polygons go into either
        // `coplanarFront` or `coplanarBack` depending on their orientation with
        // respect to this plane. Polygons in front or in back of this plane go into
        // either `front` or `back`.
        public void SplitPolygon(CsgPolygon polygon, List <CsgPolygon> coplanarFront, List <CsgPolygon> coplanarBack, List <CsgPolygon> front, List <CsgPolygon> back)
        {
            throw new NotImplementedException();
            //double splitTolerance = 0.00001;
            //// Classify each point as well as the entire polygon into one of the above
            //// four classes.
            //PolyType polygonType = PolyType.COPLANAR;
            //List<PolyType> types = new List<PolyType>();

            //for (int i = 0; i < polygon.vertices.Count; i++)
            //{
            //	double t = Vector3Ex.Dot(this.normal, polygon.vertices[i].Position) - this.w;
            //	PolyType type = (t < -splitTolerance) ? PolyType.BACK : ((t > splitTolerance) ? PolyType.FRONT : PolyType.COPLANAR);
            //	polygonType |= type;
            //	types.Add(type);
            //}

            //// Put the polygon in the correct list, splitting it when necessary.
            //switch (polygonType)
            //{
            //	case PolyType.COPLANAR:
            //		{
            //			if (Vector3Ex.Dot(this.normal, polygon.plane.normal) > 0)
            //			{
            //				coplanarFront.Add(polygon);
            //			}
            //			else
            //			{
            //				coplanarBack.Add(polygon);
            //			}
            //			break;
            //		}
            //	case PolyType.FRONT:
            //		{
            //			front.Add(polygon);
            //			break;
            //		}
            //	case PolyType.BACK:
            //		{
            //			back.Add(polygon);
            //			break;
            //		}
            //	case PolyType.SPANNING:
            //		{
            //			List<IVertex> frontVertices = new List<IVertex>();
            //			List<IVertex> backVertices = new List<IVertex>();
            //			for (int firstVertexIndex = 0; firstVertexIndex < polygon.vertices.Count; firstVertexIndex++)
            //			{
            //				int nextVertexIndex = (firstVertexIndex + 1) % polygon.vertices.Count;
            //				PolyType firstPolyType = types[firstVertexIndex];
            //				PolyType nextPolyType = types[nextVertexIndex];
            //				IVertex firstVertex = polygon.vertices[firstVertexIndex];
            //				IVertex nextVertex = polygon.vertices[nextVertexIndex];
            //				if (firstPolyType != PolyType.BACK)
            //				{
            //					frontVertices.Add(firstVertex);
            //				}

            //				if (firstPolyType != PolyType.FRONT)
            //				{
            //					backVertices.Add(firstVertex);
            //				}

            //				if ((firstPolyType | nextPolyType) == PolyType.SPANNING)
            //				{
            //					double planDotFirstVertex = Vector3Ex.Dot(this.normal, firstVertex.Position);
            //					double firstDistToPlane = this.w - planDotFirstVertex;
            //					Vector3 deltaFromFirstToNext = nextVertex.Position - firstVertex.Position;
            //					double t = firstDistToPlane / Vector3Ex.Dot(this.normal, deltaFromFirstToNext);
            //					IVertex newVertex = firstVertex.CreateInterpolated(nextVertex, t);
            //					frontVertices.Add(newVertex);
            //					backVertices.Add(newVertex);
            //				}
            //			}

            //			if (frontVertices.Count >= 3)
            //			{
            //				front.Add(new CsgPolygon(frontVertices));
            //			}

            //			if (backVertices.Count >= 3)
            //			{
            //				back.Add(new CsgPolygon(backVertices));
            //			}
            //		}
            //		break;

            //	default:
            //		throw new NotImplementedException();
            //}
        }