예제 #1
0
        public MeshPoint IntersectLine(MeshPolygon tri, int lineInd)
        {
            var points   = tri.Points;
            var lineInd2 = (lineInd + 1) % points.Count;
            var pt1      = tri.Points[lineInd];
            var pt2      = tri.Points[lineInd2];

            Vector3 a = EdgeVec;                     //line 1
            Vector3 b = pt2.Position - pt1.Position; //line 2
            Vector3 c = EdgePos - pt1.Position;      //vec between starts

            //percent of line 1 where we intersect with line 2
            float ip = 1 / (-b.X * a.Z + a.X * b.Z); //projection
            float t  = (b.X * c.Z - b.Z * c.X) * ip;

            //percent of line 2 where we intersect line 1
            float ip2 = 1 / (-a.X * b.Z + b.X * a.Z);
            float s   = (a.X * (-c.Z) - a.Z * (-c.X)) * ip2;

            //pos + vec * t = pos2 + vec2 * s
            //vec * t - vec2 * s = pos2 - pos1
            float[] newTC = new float[pt1.TexCoords.Length];
            float   ms    = 1 - s;

            for (int i = 0; i < newTC.Length; i++)
            {
                newTC[i] = pt1.TexCoords[i] * ms + pt2.TexCoords[i] * s;
            }

            return(new MeshPoint(
                       //position from the clip triangle (use t)
                       EdgePos + EdgeVec * t,
                       //texcoords from the two points in the poly (use s)
                       newTC
                       ));
        }
예제 #2
0
        private void ClipTriangles(BaseMeshTriangle baseTri, MeshTriangle projTri, List <MeshPoint> outverts, List <int> inds)
        {
            //Sutherland–Hodgman algorithm
            //clip a triangle against another by iteratively clipping each edge of the second one

            //we want to clip against base tri
            var outputList = new MeshPolygon(projTri);
            var basePlane  = new Plane(baseTri.Vertices[0], baseTri.Vertices[1], baseTri.Vertices[2]);

            for (int i = 0; i < 3; i++)
            {
                if (outputList.Points.Count == 0)
                {
                    return;
                }
                var inputList = outputList;
                var edge      = new ClipEdge(baseTri.Vertices[i], baseTri.Vertices[(i + 1) % 3]);
                outputList = new MeshPolygon();
                var lastPoint = inputList.Points.Last();
                int j         = inputList.Points.Count - 1;
                foreach (var point in inputList.Points)
                {
                    if (!edge.ShouldClip(point.Position))
                    {
                        if (edge.ShouldClip(lastPoint.Position))
                        {
                            outputList.Points.Add(edge.IntersectLine(inputList, j));
                        }
                        //we still need to project the point onto the surface...
                        var ray        = new Ray(point.Position, new Vector3(0, -1, 0));
                        var intersect2 = ray.Intersects(basePlane);
                        if (intersect2 == null)
                        {
                            ray.Direction *= -1;
                            intersect2     = ray.Intersects(basePlane);
                            if (intersect2 == null)
                            {
                            }
                            intersect2 = -(intersect2 ?? 0f);
                        }
                        point.Position.Y -= intersect2.Value;
                        outputList.Points.Add(point);
                    }
                    else
                    {
                        if (!edge.ShouldClip(lastPoint.Position))
                        {
                            outputList.Points.Add(edge.IntersectLine(inputList, j));
                        }
                    }
                    j         = (j + 1) % inputList.Points.Count;
                    lastPoint = point;
                }
            }

            if (outputList.Points.Count < 3)
            {
                return;                              //?
            }
            outputList.Triangulate(outverts, inds);
        }