Ejemplo n.º 1
0
        public void PerpendicularTest_float()
        {
            LineF line1 = new LineF(1, 2, 3, 4);
            LineF line2 = line1.Perpendicular(5, 6);

            Assert.AreEqual(-1.0 / line1.M, line2.M);
        }
Ejemplo n.º 2
0
        public void LocateCollinearReverse()
        {
            LineD reverseDiagD = diagD.Reverse();

            Assert.AreEqual(LineLocation.End, reverseDiagD.LocateCollinear(new PointD(0, 0)));
            Assert.AreEqual(LineLocation.Start, reverseDiagD.LocateCollinear(new PointD(2, 2)));
            Assert.AreEqual(LineLocation.After, reverseDiagD.LocateCollinear(new PointD(-1, -1)));
            Assert.AreEqual(LineLocation.Between, reverseDiagD.LocateCollinear(new PointD(1, 1)));
            Assert.AreEqual(LineLocation.Before, reverseDiagD.LocateCollinear(new PointD(3, 3)));
            Assert.AreEqual(LineLocation.Between, reverseDiagD.LocateCollinear(new PointD(0, 1)));
            Assert.AreEqual(LineLocation.Between, reverseDiagD.LocateCollinear(new PointD(1, 0)));

            LineF reverseDiagF = diagF.Reverse();

            Assert.AreEqual(LineLocation.End, reverseDiagF.LocateCollinear(new PointF(0, 0)));
            Assert.AreEqual(LineLocation.Start, reverseDiagF.LocateCollinear(new PointF(2, 2)));
            Assert.AreEqual(LineLocation.After, reverseDiagF.LocateCollinear(new PointF(-1, -1)));
            Assert.AreEqual(LineLocation.Between, reverseDiagF.LocateCollinear(new PointF(1, 1)));
            Assert.AreEqual(LineLocation.Before, reverseDiagF.LocateCollinear(new PointF(3, 3)));
            Assert.AreEqual(LineLocation.Between, reverseDiagF.LocateCollinear(new PointF(0, 1)));
            Assert.AreEqual(LineLocation.Between, reverseDiagF.LocateCollinear(new PointF(1, 0)));

            LineI reverseDiagI = diagI.Reverse();

            Assert.AreEqual(LineLocation.End, reverseDiagI.LocateCollinear(new PointI(0, 0)));
            Assert.AreEqual(LineLocation.Start, reverseDiagI.LocateCollinear(new PointI(2, 2)));
            Assert.AreEqual(LineLocation.After, reverseDiagI.LocateCollinear(new PointI(-1, -1)));
            Assert.AreEqual(LineLocation.Between, reverseDiagI.LocateCollinear(new PointI(1, 1)));
            Assert.AreEqual(LineLocation.Before, reverseDiagI.LocateCollinear(new PointI(3, 3)));
            Assert.AreEqual(LineLocation.Between, reverseDiagI.LocateCollinear(new PointI(0, 1)));
            Assert.AreEqual(LineLocation.Between, reverseDiagI.LocateCollinear(new PointI(1, 0)));
        }
Ejemplo n.º 3
0
 public static WallCoord GetNearestPortalableEdge(IList<IWall> walls, Vector2 point, float maxRadius, float portalSize)
 {
     WallCoord wallCoord = null;
     double distanceMin = -1;
     for (int i = 0; i < walls.Count; i++)
     {
         IList<Vector2> vertices = walls[i].GetWorldVertices();
         for (int edgeIndex = 0; edgeIndex < walls[i].Vertices.Count; edgeIndex++)
         {
             int edgeIndexNext = (edgeIndex + 1) % vertices.Count;
             LineF edge = new LineF(vertices[edgeIndex], vertices[edgeIndexNext]);
             if (!EdgeValidLength(edge.Length, portalSize))
             {
                 continue;
             }
             Vector2 nearPos = edge.Nearest(point, true);
             float portalT = edge.NearestT(point, true);
             portalT = GetValidT(portalT, edge, portalSize);
             Vector2 portalPos = edge.Lerp(portalT);
             double distance = (portalPos - point).Length;
             if (maxRadius < (nearPos - point).Length)
             {
                 continue;
             }
             if (distanceMin == -1 || distance < distanceMin)
             {
                 wallCoord = new WallCoord(walls[i], edgeIndex, portalT);
                 distanceMin = distance;
             }
         }
     }
     return wallCoord;
 }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            Point p  = new Point(10, 30);
            Point p1 = new Point(10, 45);
            Point p2 = new Point(10, 60);
            Point p3 = new Point(10, 85);
            Point p4 = new Point(10, 100);
            Point p5 = new Point(30, 100);
            Point p6 = new Point(50, 100);
            Point p7 = new Point(50, 70);
            Point p8 = new Point(50, 50);
            Point p9 = new Point(0, 50);

            LineF l01 = new LineF(p, p1);
            LineF l12 = new LineF(p1, p2);
            LineF l23 = new LineF(p2, p3);
            LineF l34 = new LineF(p3, p4);
            LineF l45 = new LineF(p4, p5);
            LineF l56 = new LineF(p5, p6);
            LineF l67 = new LineF(p6, p7);
            LineF l78 = new LineF(p7, p8);
            LineF l89 = new LineF(p8, p9);

            List <Point> output = new List <Point>();

            output.Add(p1);
            output.Add(p2);
            output.Add(p3);
            output.Add(p4);
            output.Add(p5);
            output.Add(p6);
            output.Add(p7);
            output.Add(p8);
            output.Add(p9);
            int count = 0;

            List <LineF> lines = new List <LineF>();

            foreach (LineF line in lines)
            {
                line.Intersection(line);
                Console.WriteLine("X:" + line.X1 + " Y:" + line.Y1);
                Console.WriteLine(count);
                Console.ReadKey();
            }


            //foreach (Point point in output)
            //{

            //    double res = point.X;
            //    double rez = point.Y;
            //    count++;

            //    Console.WriteLine(" X:" + res + " Y:" + rez);
            //}
            Console.WriteLine(count);
            Console.ReadKey();
        }
Ejemplo n.º 5
0
        /*
         * Heal rows by calculating median row height
         * and splitting bigger rows by that row height
         */
        private List <RowInfo> HealRows(List <RowInfo> rows, List <LineF> horizLines, float leftX, float rightX)
        {
            List <float> rowHeights      = rows.Select(row => RowHeight(row)).OrderBy(h => h).ToList();
            float        medianRowHeight = rowHeights[rowHeights.Count / 2];

            return(rows.SelectMany(row => {
                float possibleInnerRows = RowHeight(row) / medianRowHeight;
                int innerRowCount = (int)Math.Round(possibleInnerRows);
                float ratio = innerRowCount / possibleInnerRows;
                if (innerRowCount > 1 && ratio > 0.9 && ratio < 1.1)
                {
                    // this row can be divided into several smaller ones
                    // because we can fit whole number of median row heights into it
                    float innerRowHeight = RowHeight(row) / innerRowCount;
                    List <LineF> innerRowLines = new List <LineF>();
                    for (int ir = 1; ir < innerRowCount; ir++)
                    {
                        float irY = row.topLine.p1.Y + ir * innerRowHeight;
                        if (horizLines.Find(hl => Math.Abs(hl.p1.Y - irY) < 5) != null)
                        {
                            // we can find real (sub-threshold) line for this Y,
                            // so we confirm our guess
                            innerRowLines.Add(new LineF(new PointF(leftX, irY), new PointF(rightX, irY)));
                        }
                    }
                    // check that we were able to confirm our guess for all inner lines
                    if (innerRowLines.Count == innerRowCount - 1)
                    {
                        // return guessed rows
                        List <RowInfo> innerRows = new List <RowInfo>();
                        innerRowLines.Add(row.bottomLine);
                        LineF prevLine = row.topLine;
                        for (int ir = 0; ir < innerRowCount; ir++)
                        {
                            innerRows.Add(new RowInfo {
                                topLine = prevLine,
                                bottomLine = innerRowLines[ir],
                                dividers = new List <float>(row.dividers)
                            });
                            prevLine = innerRowLines[ir];
                        }
                        return innerRows;
                    }
                    else
                    {
                        // return orignal row
                        return new List <RowInfo> {
                            row
                        };
                    }
                }
                else
                {
                    return new List <RowInfo> {
                        row
                    };
                }
            }).ToList());
        }
Ejemplo n.º 6
0
        private InsetVertex CombineVectorLines(InsetVertex prev, InsetVertex next, double thickness)
        {
            var prevLine = new LineF(prev.Previous, prev.Outer);
            var nextLine = new LineF(next.Outer, next.Next);
            var newOuter = prevLine.Intersect(nextLine);

            return(new InsetVertex(newOuter, prev.Previous, next.Next, thickness));
        }
Ejemplo n.º 7
0
 public void ArrayAccessorTest1()
 {
     LineF line = new LineF(new Vector2(1f, 5f), new Vector2(100.1f, 2f));
     line[0] = new Vector2(9f, 2.2f);
     line[1] = new Vector2(99f, 92.2f);
     Assert.IsTrue(line[0] == new Vector2(9f, 2.2f));
     Assert.IsTrue(line[1] == new Vector2(99f, 92.2f));
 }
Ejemplo n.º 8
0
            private static void AddIfIntersect(LineF first, LineF second, ICollection <PointF> result)
            {
                var intersection = first.Intersection(second);

                if (intersection != null)
                {
                    result.Add(intersection.Value);
                }
            }
Ejemplo n.º 9
0
        static void Main(string[] args)
        {
            Point p = new Point(10, 30);
            Point p1 = new Point(10, 45);
            Point p2 = new Point(10, 60);
            Point p3 = new Point(10, 85);
            Point p4 = new Point(10, 100);
            Point p5 = new Point(30, 100);
            Point p6 = new Point(50, 100);
            Point p7 = new Point(50, 70);
            Point p8 = new Point(50, 50);
            Point p9 = new Point(0, 50);

            LineF l01 = new LineF(p, p1);
            LineF l12 = new LineF(p1, p2);
            LineF l23 = new LineF(p2, p3);
            LineF l34 = new LineF(p3, p4);
            LineF l45 = new LineF(p4, p5);
            LineF l56 = new LineF(p5, p6);
            LineF l67 = new LineF(p6, p7);
            LineF l78 = new LineF(p7, p8);
            LineF l89 = new LineF(p8, p9);

            List<Point> output = new List<Point>();
            output.Add(p1);
            output.Add(p2);
            output.Add(p3);
            output.Add(p4);
            output.Add(p5);
            output.Add(p6);
            output.Add(p7);
            output.Add(p8);
            output.Add(p9);
            int count = 0;

            List<LineF> lines = new List<LineF>();
            foreach (LineF line in lines)
            {
                line.Intersection(line);
                Console.WriteLine("X:"+line.X1+" Y:"+line.Y1);
                Console.WriteLine(count);
                Console.ReadKey();
            }

            //foreach (Point point in output)
            //{

            //    double res = point.X;
            //    double rez = point.Y;
            //    count++;

            //    Console.WriteLine(" X:" + res + " Y:" + rez);
            //}
            Console.WriteLine(count);
            Console.ReadKey();
        }
Ejemplo n.º 10
0
 public static void AddLinesWidth(Mesh mesh, LineF[] lines, float width)
 {
     for (int i = 0; i < lines.Length; i++)
     {
         Vector2 vStart, vEnd;
         vStart = lines[i][0];
         vEnd = lines[i][1];
         AddLineWidth(mesh, vStart, vEnd, width);
     }
 }
Ejemplo n.º 11
0
            /// <returns>
            /// false - no intersection, or infinite intersecion
            /// true - single intersection point
            /// </returns>
            public static bool LineIntersectsSgment(LineF line, SegmentF seg, ref PointF intersec)
            {
                var segLine = LineF.makeLine(seg.start, seg.end);

                if (LineIntersectsLine(line, segLine, ref intersec))
                {
                    float p = seg.GetProjectionOnLine(intersec);
                    return(p >= 0 && p <= 1);
                }
                return(false);
            }
Ejemplo n.º 12
0
 /// <summary>
 /// Attach a portal to the nearest valid wall edge along a ray.
 /// </summary>
 /// <param name="portal">Portal that will potentially be attached to a wall edge.</param>
 /// <param name="ray">Portal ray cast.  ray[0] is the begin point and ray[1] is the end point.</param>
 /// <returns>True if a valid edge was found, otherwise false.</returns>
 public static bool PortalPlace(FixturePortal portal, LineF ray)
 {
     WallCoord intersection = RayCast(portal.Scene, ray);
     if (intersection != null)
     {
         intersection = AdjustCoord(intersection, portal.Size);
         if (intersection != null)
         {
             portal.SetPosition(intersection.Wall, new PolygonCoord(intersection.EdgeIndex, intersection.EdgeT));
             return true;
         }
     }
     return false;
 }
Ejemplo n.º 13
0
 public PortalView(PortalView parent, Matrix4 viewMatrix, List<List<IntPoint>> path, LineF[] fovLines, LineF[] fovLinesPrevious, LineF portalLine)
 {
     PortalLine = portalLine;
     FovLines = fovLines;
     FovLinesPrevious = fovLinesPrevious;
     Children = new List<PortalView>();
     Parent = parent;
     if (Parent != null)
     {
         Parent.Children.Add(this);
     }
     ViewMatrix = viewMatrix;
     Paths = path;
 }
Ejemplo n.º 14
0
        /// <param name="depth">Number of iterations.</param>
        /// <param name="clipModels">Adds the ClipModel instances to this list.</param>
        private static List<ClipModel> _getClipModels(IRenderable entity, Model model, IList<IPortal> portalList, Vector2 centerPoint, IPortal portalEnter, Matrix4 modelMatrix, int depth, int count)
        {
            List<ClipModel> clipModels = new List<ClipModel>();
            if (depth <= 0)
            {
                return clipModels;
            }

            List<IPortal> collisions = Portal.GetCollisions(
                centerPoint,
                Vector2Ext.Transform(model.GetWorldConvexHull(),
                entity.GetWorldTransform().GetMatrix() * modelMatrix),
                portalList,
                PORTAL_CLIP_MARGIN);

            List<LineF> clipLines = new List<LineF>();
            foreach (IPortal portal in collisions)
            {
                Vector2[] pv = Portal.GetWorldVerts(portal);
                LineF clipLine = new LineF(pv);

                LineF portalLine = new LineF(pv);
                Vector2 normal = portal.WorldTransform.GetRight();
                if (portal.WorldTransform.MirrorX)
                {
                    normal = -normal;
                }

                Vector2 portalNormal = portal.WorldTransform.Position + normal;
                if (portalLine.GetSideOf(centerPoint) != portalLine.GetSideOf(portalNormal))
                {
                    normal *= Portal.EnterMinDistance;
                }
                else
                {
                    clipLine = clipLine.Reverse();
                    normal *= -Portal.EnterMinDistance;
                }

                clipLines.Add(clipLine);
                if (portalEnter == null || portal != portalEnter.Linked)
                {
                    Vector2 centerPointNext = Vector2Ext.Transform(portal.WorldTransform.Position + normal, Portal.GetLinkedMatrix(portal));
                    clipModels.AddRange(_getClipModels(entity, model, portalList, centerPointNext, portal, modelMatrix * Portal.GetLinkedMatrix(portal), depth - 1, count + 1));
                }
            }
            clipModels.Add(new ClipModel(entity, model, clipLines.ToArray(), modelMatrix));
            return clipModels;
        }
Ejemplo n.º 15
0
        public static Vector2[] CreateLineWidth(LineF line, float widthStart, float widthEnd)
        {
            Debug.Assert(widthStart > 0 && widthEnd > 0, "Line must have positive width.");
            Vector2 offsetStart = (line[0] - line[1]).PerpendicularLeft.Normalized() * widthStart / 2;
            Vector2 offsetEnd = (line[0] - line[1]).PerpendicularLeft.Normalized() * widthEnd / 2;

            Vector2[] lineWidth = new Vector2[] {
                line[0] - offsetStart,
                line[0] + offsetStart,
                line[1] + offsetEnd,
                line[1] - offsetEnd
            };
            Debug.Assert(PolygonExt.IsInterior(lineWidth));
            return lineWidth;
        }
Ejemplo n.º 16
0
            public float a, b; // a may be float.PositiveInfinity
            //public PointF p1, p2;

            public static LineF makeLine(PointF p1, PointF p2)
            {
                var l = new LineF();

                //l.p1 = p1;
                //l.p2 = p2;
                if (p1.X == p2.X)
                {
                    l.a = float.PositiveInfinity;
                    l.b = p1.X;
                    return(l);
                }
                l.a = (p2.Y - p1.Y) / (p2.X - p1.X);
                l.b = p1.Y - l.a * p1.X;
                return(l);
            }
Ejemplo n.º 17
0
        public UnintersectingLine(Point point1, Point point2, List <UnintersectingLine> lines)
        {
            LineSegments = new List <LineF>();
            From         = point1;
            To           = point2;
            OriginalLine = new LineF(From, To);

            points.Add(point1);
            //points.Add(new Point(point1.X + 30, point2.Y - 30)); // Test. Fungerar bra att rita ut linjer som en path.

            LineF thisline = new LineF(From, To);

            Console.Out.WriteLine("Ny linje " + From + " till " + To);
            counter      = 0;
            LineSegments = FindPath(From, To, lines);
            if (LineSegments == null)
            {
                HasErrors = true;
                return;
            }

            /*
             * foreach(UnintersectingLine otherUnintersectingLine in lines)
             * {
             *  foreach (LineF otherLine in otherUnintersectingLine.LineSegments)
             *  {
             *      Point? intersection = thisline.Intersection(otherLine);
             *      if(intersection != null)
             *      {
             *          // Vi har en korsning. Lägg till ny punkt istället.
             *          points.Add(otherLine.To);
             *      }
             *  }
             * }
             */

            points.Add(point2);

            // Registrera alla segment för framtida kollisionsdetekteringar.
            Point lastPoint = From;

            for (int i = 1; i < points.Count; i++)
            {
                LineSegments.Add(new LineF(lastPoint, points[i]));
                lastPoint = points[i];
            }
        }
Ejemplo n.º 18
0
            private PointF?Intersection(LineF other)
            {
                var a1 = Y2 - Y1;
                var b1 = X1 - X2;
                var c1 = X2 * Y1 - X1 * Y2;

                var r3 = a1 * other.X1 + b1 * other.Y1 + c1;
                var r4 = a1 * other.X2 + b1 * other.Y2 + c1;

                if (r3 != 0 && r4 != 0 && Math.Sign(r3) == Math.Sign(r4))
                {
                    return(null);
                }

                var a2 = other.Y2 - other.Y1;
                var b2 = other.X1 - other.X2;
                var c2 = other.X2 * other.Y1 - other.X1 * other.Y2;

                var r1 = a2 * X1 + b2 * Y1 + c2;
                var r2 = a2 * X2 + b2 * Y2 + c2;

                if (r1 != 0 && r2 != 0 && Math.Sign(r1) == Math.Sign(r2))
                {
                    return(null);
                }

                var denom = a1 * b2 - a2 * b1;

                if (denom == 0)
                {
                    return(null);
                }

                var offset = denom < 0 ? -denom / 2 : denom / 2;

                var num = b1 * c2 - b2 * c1;
                var x   = (num < 0 ? num - offset : num + offset) / denom;

                num = a2 * c1 - a1 * c2;
                var y = (num < 0 ? num - offset : num + offset) / denom;

                return(new PointF(x, y));
            }
Ejemplo n.º 19
0
        public void CalculateEdgeLines()
        {
            List <PointF> leftEndPoints  = rowLines.Select(ln => ln.p1).ToList();
            List <PointF> rightEndPoints = rowLines.Select(ln => ln.p2).ToList();

            // recalculate X values for left and right table edges (minimizing RMSD from end points)
            leftEdgeX  = leftEndPoints.Select(pt => pt.X).Average();
            rightEdgeX = rightEndPoints.Select(pt => pt.X).Average();

            PointF leftEdgeTop    = new PointF(leftEdgeX, leftEndPoints.First().Y);
            PointF leftEdgeBottom = new PointF(leftEdgeX, leftEndPoints.Last().Y);

            leftEdge = new LineF(leftEdgeTop, leftEdgeBottom);

            PointF rightEdgeTop    = new PointF(rightEdgeX, rightEndPoints.First().Y);
            PointF rightEdgeBottom = new PointF(rightEdgeX, rightEndPoints.Last().Y);

            rightEdge = new LineF(rightEdgeTop, rightEdgeBottom);
        }
Ejemplo n.º 20
0
            public static bool LineIntersectsRectTest(LineF line, RectangleF r)
            {
                if (line.a == float.PositiveInfinity)
                {
                    return(r.Left <= line.b && r.Right >= line.b);
                }

                var  vert     = r.getVertices();
                bool areBelow = vert[0].Y < line.getY(vert[0].X);

                for (int i = 1; i < 4; ++i)
                {
                    if (areBelow != (vert[i].Y < line.getY(vert[i].X))) // some points in rect are below the line, some are above
                    {
                        return(true);
                    }
                }
                return(false);
            }
Ejemplo n.º 21
0
        private void AddLines()
        {
            foreach (Line obj in dxf.Lines)
            {
                LineF lineF = new LineF(ConvertToGdiX(obj.StartPoint.X), ConvertToGdiY(obj.StartPoint.Y), ConvertToGdiX(obj.EndPoint.X), ConvertToGdiY(obj.EndPoint.Y), IsDotted(obj));
                this.lines.Add(lineF);

                if (dxfMinX > lineF.StartPoint.X)
                {
                    dxfMinX = lineF.StartPoint.X;
                }
                if (dxfMinX > lineF.EndPoint.X)
                {
                    dxfMinX = lineF.EndPoint.X;
                }
                if (dxfMinY > lineF.StartPoint.Y)
                {
                    dxfMinY = lineF.StartPoint.Y;
                }
                if (dxfMinY > lineF.EndPoint.Y)
                {
                    dxfMinY = lineF.EndPoint.Y;
                }

                if (dxfMaxX < lineF.StartPoint.X)
                {
                    dxfMaxX = lineF.StartPoint.X;
                }
                if (dxfMaxX < lineF.EndPoint.X)
                {
                    dxfMaxX = lineF.EndPoint.X;
                }
                if (dxfMaxY < lineF.StartPoint.Y)
                {
                    dxfMaxY = lineF.StartPoint.Y;
                }
                if (dxfMaxY < lineF.EndPoint.Y)
                {
                    dxfMaxY = lineF.EndPoint.Y;
                }
            }
        }
Ejemplo n.º 22
0
        protected static CoordinateF GetIntersectionPoint(LMFace face, LineF line, bool ignoreDirection = false)
        {
            var plane     = face.Plane;
            var intersect = plane.GetIntersectionPoint(line, ignoreDirection);
            List <CoordinateF> coordinates = face.Vertices.Select(x => x.Location).ToList();

            if (intersect == null)
            {
                return(null);
            }
            BoxF bbox = new BoxF(face.BoundingBox.Start - new CoordinateF(0.5f, 0.5f, 0.5f), face.BoundingBox.End + new CoordinateF(0.5f, 0.5f, 0.5f));

            if (!bbox.CoordinateIsInside(intersect))
            {
                return(null);
            }

            CoordinateF centerPoint = face.BoundingBox.Center;

            for (var i = 0; i < coordinates.Count; i++)
            {
                var i1 = i;
                var i2 = (i + 1) % coordinates.Count;

                var lineMiddle     = (coordinates[i1] + coordinates[i2]) * 0.5f;
                var middleToCenter = centerPoint - lineMiddle;
                var v          = coordinates[i1] - coordinates[i2];
                var lineNormal = face.Plane.Normal.Cross(v);

                if ((middleToCenter - lineNormal).LengthSquared() > (middleToCenter + lineNormal).LengthSquared())
                {
                    lineNormal = -lineNormal;
                }

                if (lineNormal.Dot(intersect - lineMiddle) < 0.0f)
                {
                    return(null);
                }
            }
            return(intersect);
        }
Ejemplo n.º 23
0
            /// <remarks>http://community.topcoder.com/tc?module=Static&amp;d1=tutorials&amp;d2=geometry2</remarks>
            private PointF?Intersection(LineF other)
            {
                const int precision = 8;

                var a1 = (double)Y2 - Y1;
                var b1 = (double)X1 - X2;
                var c1 = a1 * X1 + b1 * Y1;

                var a2 = (double)other.Y2 - other.Y1;
                var b2 = (double)other.X1 - other.X2;
                var c2 = a2 * other.X1 + b2 * other.Y1;

                var det = a1 * b2 - a2 * b1;

                if (det == 0)
                {
                    return(null);
                }
                else
                {
                    var xi = (b2 * c1 - b1 * c2) / det;
                    var yi = (a1 * c2 - a2 * c1) / det;

                    if (Math.Round(Math.Min(X1, X2), precision) <= Math.Round(xi, precision) &&
                        Math.Round(xi, precision) <= Math.Round(Math.Max(X1, X2), precision) &&
                        Math.Round(Math.Min(Y1, Y2), precision) <= Math.Round(yi, precision) &&
                        Math.Round(yi, precision) <= Math.Round(Math.Max(Y1, Y2), precision) &&
                        Math.Round(Math.Min(other.X1, other.X2), precision) <= Math.Round(xi, precision) &&
                        Math.Round(xi, precision) <= Math.Round(Math.Max(other.X1, other.X2), precision) &&
                        Math.Round(Math.Min(other.Y1, other.Y2), precision) <= Math.Round(yi, precision) &&
                        Math.Round(yi, precision) <= Math.Round(Math.Max(other.Y1, other.Y2), precision))
                    {
                        return(new PointF((float)xi, (float)yi));
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
Ejemplo n.º 24
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="line"></param>
            /// <param name="r"></param>
            /// <param name="intersects">
            /// if return value is true, intersects will have two intersection points (even for infinite case)
            /// </param>
            /// <returns>
            /// false - no intersection
            /// true - single/ infinite intersection
            /// </returns>
            public static bool LineIntersectsRect(LineF line, RectangleF r, out PointF[] intersects)
            {
                intersects = new PointF[2];
                int intersecIdx = 0;
                var verts       = r.getVertices();

                // check intersection with each of the rect's segments
                for (int i = 0; i < 4 && intersecIdx < 2; ++i)
                {
                    if (LineIntersectsSgment(line,
                                             new SegmentF()
                    {
                        start = verts[i], end = verts[(i + 1) % 4]
                    },
                                             ref intersects[intersecIdx]))
                    {
                        ++intersecIdx; // if 2 intersections were found, the loop breaks
                    }
                }

                return(intersecIdx == 2);
            }
Ejemplo n.º 25
0
        public static Vector2 GetLocalOrigin(Body body)
        {
            BodyData data = GetData(body);
            Vector2 center;
            //If this isn't the root body then the center point will be just outside of the parent portal.
            if (data.IsChild)
            {
                LineF portalLine = new LineF(Portal.GetWorldVerts(data.BodyParent.Portal.Linked));
                Vector2 offset = portalLine.Delta.PerpendicularLeft.Normalized() * 0.01f;
                center = portalLine.Center + offset;
                if (portalLine.GetSideOf(center + offset) == portalLine.GetSideOf(body.Position))
                {
                    center = portalLine.Center - offset;
                }
            }
            else
            {
                center = (Vector2)body.Position;
            }

            return center;
        }
Ejemplo n.º 26
0
            /// <returns>
            /// false - no intersection, or infinite intersecion
            /// true - single intersection point
            /// </returns>
            public static bool LineIntersectsLine(LineF l1, LineF l2, ref PointF intersec)
            {
                if (l1.a == l2.a)
                {
                    return(false);
                }

                if (float.IsInfinity(l1.a))
                {
                    intersec = new PointF(l1.b, l2.getY(l1.b));
                    return(true);
                }
                if (float.IsInfinity(l2.a))
                {
                    intersec = new PointF(l2.b, l1.getY(l2.b));
                    return(true);
                }

                float x = (l2.b - l1.b) / (l1.a - l2.a); // the solution for the equation between two lines

                intersec = new PointF(x, l1.getY(x));
                return(true);
            }
Ejemplo n.º 27
0
        private GradientPoints ExpandGradient(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd)
        {
            if (!NeedToExpandGradient(boundable, specifiedStart, specifiedEnd))
            {
                Debug.Fail("Unexpectedly expanding gradient when not needed!");
                return(new GradientPoints(specifiedStart, specifiedEnd));
            }

            var specifiedLength     = CalculateDistance(specifiedStart, specifiedEnd);
            var specifiedUnitVector = new PointF((specifiedEnd.X - specifiedStart.X) / (float)specifiedLength, (specifiedEnd.Y - specifiedStart.Y) / (float)specifiedLength);

            var effectiveStart = specifiedStart;
            var effectiveEnd   = specifiedEnd;

            var elementDiagonal = (float)CalculateDistance(new PointF(boundable.Bounds.Left, boundable.Bounds.Top), new PointF(boundable.Bounds.Right, boundable.Bounds.Bottom));

            var expandedStart = MovePointAlongVector(effectiveStart, specifiedUnitVector, -elementDiagonal);
            var expandedEnd   = MovePointAlongVector(effectiveEnd, specifiedUnitVector, elementDiagonal);

            var intersectionPoints = new LineF(expandedStart.X, expandedStart.Y, expandedEnd.X, expandedEnd.Y).Intersection(boundable.Bounds);

            if (boundable.Bounds.Contains(specifiedStart))
            {
                effectiveStart = CalculateClosestIntersectionPoint(expandedStart, intersectionPoints);

                effectiveStart = MovePointAlongVector(effectiveStart, specifiedUnitVector, -1);
            }

            if (boundable.Bounds.Contains(specifiedEnd))
            {
                effectiveEnd = CalculateClosestIntersectionPoint(effectiveEnd, intersectionPoints);

                effectiveEnd = MovePointAlongVector(effectiveEnd, specifiedUnitVector, 1);
            }

            return(new GradientPoints(effectiveStart, effectiveEnd));
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Determine a position that is sufficiently far away from all portals so that it isn't ambiguous which side of a 
        /// portal the position is at.
        /// </summary>
        /// <param name="portals"></param>
        /// <param name="portalPrevious">The last portal that was exited.</param>
        /// <param name="transform"></param>
        /// <param name="velocity"></param>
        private static Transform2 AddMargin(IEnumerable<IPortal> portals, IPortal portalPrevious, Transform2 transform, Transform2 velocity)
        {
            transform = transform.ShallowClone();
            foreach (IPortal p in portals)
            {
                if (!Portal.IsValid(p))
                {
                    continue;
                }
                LineF exitLine = new LineF(Portal.GetWorldVerts(p));
                Vector2 position = transform.Position;
                double distanceToPortal = MathExt.PointLineDistance(position, exitLine, true);
                if (distanceToPortal < Portal.EnterMinDistance)
                {
                    Vector2 exitNormal = p.WorldTransform.GetRight();
                    Side sideOf;
                    if (p == portalPrevious)
                    {
                        sideOf = exitLine.GetSideOf(position + velocity.Position);
                    }
                    else
                    {
                        sideOf = exitLine.GetSideOf(position - velocity.Position);
                    }
                    if (sideOf != exitLine.GetSideOf(exitNormal + p.WorldTransform.Position))
                    {
                        exitNormal = -exitNormal;
                    }

                    Vector2 pos = exitNormal * (Portal.EnterMinDistance - (float)distanceToPortal);
                    transform.Position += pos;
                    break;
                }
            }
            return transform;
        }
Ejemplo n.º 29
0
 public static WallCoord RayCast(IScene scene, LineF ray)
 {
     WallCoord wallCoord = null;
     float minDist = -1;
     foreach (IWall wall in scene.GetAll().OfType<IWall>())
     {
         Vector2[] vertices = wall.GetWorldVertices().ToArray();
         for (int i = 0; i < vertices.Length; i++)
         {
             int iNext = (i + 1) % vertices.Length;
             IntersectCoord coord = MathExt.LineLineIntersect(ray, new LineF(vertices[i], vertices[iNext]), false);
             if (coord.Exists)
             {
                 float dist = ((Vector2)coord.Position - ray[0]).Length;
                 if ((minDist == -1 || minDist < dist))
                 {
                     minDist = dist;
                     wallCoord = new WallCoord(wall, i, (float)coord.TLast);
                 }
             }
         }
     }
     return wallCoord;
 }
Ejemplo n.º 30
0
 public void GetSideOfTest11()
 {
     LineF line = new LineF(new Vector2(-1, 1), new Vector2(0, 0));
     Assert.IsFalse(line.GetSideOf(new Vector2(0, -100)) == Side.Left);
 }
Ejemplo n.º 31
0
 public void NearestTTest2()
 {
     LineF line = new LineF(new Vector2(3.3f,-4.9f), new Vector2(-5.3f, -6.1f));
     Assert.IsTrue(line.NearestT(new Vector2(-4, 2), false) == 0.722811639f);
 }
Ejemplo n.º 32
0
 public void NearestTTest1()
 {
     LineF line = new LineF(new Vector2(), new Vector2(0, 1));
     Assert.IsTrue(line.NearestT(new Vector2(-4, 2), false) == 2);
 }
Ejemplo n.º 33
0
 public void GetSideOfTest1()
 {
     LineF line = new LineF(new Vector2(0, 0), new Vector2(1, 0));
     Assert.IsTrue(line.GetSideOf(new Vector2(0, 100)) == Side.Left);
 }
Ejemplo n.º 34
0
 public void NearestTTest0()
 {
     LineF line = new LineF(new Vector2(), new Vector2(1, 0));
     Assert.IsTrue(line.NearestT(new Vector2(1, 5), false) == 1);
 }
Ejemplo n.º 35
0
 public void IsInsideFOVTest9()
 {
     float x = -2;
     float y = 2;
     for (double i = 0; i < Math.PI * 2; i += Math.PI / 20)
     {
         Vector2 viewPoint = new Vector2(x - 1, y);
         LineF lookLine = new LineF(new Vector2(x + 1, y), (float)i, 1f);
         LineF line = new LineF(new Vector2(x, y + 0.5f), new Vector2(x, y - 0.5f));
         Assert.IsTrue(line.IsInsideFOV(viewPoint, lookLine));
     }
 }
Ejemplo n.º 36
0
 /// <summary>
 /// Returns the point that this line intersects with this face.
 /// </summary>
 /// <param name="line">The intersection line</param>
 /// <returns>The point of intersection between the face and the line.
 /// Returns null if the line does not intersect this face.</returns>
 public virtual CoordinateF GetIntersectionPoint(LineF line)
 {
     return(GetIntersectionPoint(this, line));
 }
Ejemplo n.º 37
0
        public List <LineF> FindPath(Point from, Point to, List <UnintersectingLine> existingLines)
        {
            counter++;
            if (counter > 20)
            {
                Console.Out.WriteLine("Out of moves!");
                return(null);
            }

            LineF        thisline = new LineF(from, to);
            List <LineF> res      = new List <LineF>();

            foreach (UnintersectingLine otherUnintersectingLine in existingLines)
            {
                foreach (LineF otherLine in otherUnintersectingLine.LineSegments)
                {
                    Point?intersection = thisline.Intersection(otherLine);
                    if (intersection != null)
                    {
                        float dFrom = (float)Math.Sqrt(Math.Pow(intersection.Value.X - otherLine.From.X, 2) + Math.Pow(intersection.Value.Y - otherLine.From.Y, 2));
                        float dTo   = (float)Math.Sqrt(Math.Pow(intersection.Value.X - otherLine.To.X, 2) + Math.Pow(intersection.Value.Y - otherLine.To.Y, 2));

                        /*
                         * // Specialare! Om vi är close enough, anse at det var ok.
                         * if( dFrom < 1 || dTo < 1)
                         * {
                         *  //Console.Out.WriteLine("Punkten (" + intersection.Value.X + ", " + intersection.Value.Y + ") anses ok.");
                         *  //res.Add(new LineF(from, to));
                         *  //   return res;
                         *  continue;
                         * }
                         */


                        Point candidate1 = (dFrom < dTo ? otherUnintersectingLine.FirstSegment.ExtendFrom(10) : otherUnintersectingLine.LastSegment.ExtendTo(10));
                        Point candidate2 = (dFrom >= dTo ? otherUnintersectingLine.FirstSegment.ExtendFrom(10) : otherUnintersectingLine.LastSegment.ExtendTo(10));

                        // Vi har en korsning. Lägg till ny punkt istället. Kortast väg vinner.
                        // Här verkar det bli avgörande att ibland testa ett andra alternativ.
                        Point p = candidate1;

                        /*
                         * if(TraversedPoints.Contains(candidate1))
                         * {
                         *   p = candidate2;
                         * }
                         */


                        Console.Out.WriteLine("  Från " + from.ToString() + " till " + p.ToString());
                        Console.Out.WriteLine("  Sen från " + p.ToString() + " till " + to.ToString());
                        res = FindPath(from, p, existingLines);
                        if (res != null)
                        {
                            List <LineF> part2 = FindPath(p, to, existingLines);
                            if (part2 != null)
                            {
                                res.AddRange(part2);
                            }
                            else
                            {
                                // Om vi körde fast i förra spåret, testa att gå åt andra hållet. Starta om med 20 nya fräscha försök.
                                counter = 0;
                                Point        p2      = (dFrom >= dTo ? otherUnintersectingLine.FirstSegment.ExtendFrom(10) : otherUnintersectingLine.LastSegment.ExtendTo(10));
                                List <LineF> part2_2 = FindPath(p, to, existingLines);
                                if (part2_2 != null)
                                {
                                    res.AddRange(part2_2);
                                }
                            }
                        }

                        return(res);
                    }
                    else
                    {
                        // Keep looking.
                        continue;
                    }
                }
            }

            //   Console.Out.WriteLine("Från " + from.ToString() + " till " + to.ToString());

            res.Add(new LineF(from, to));
            return(res);
        }
Ejemplo n.º 38
0
 public void EqualsEpsilon()
 {
     Assert.IsTrue(LineD.Equals(lineD, new LineD(1.1, 2.9, 3.9, 5.1), 0.2));
     Assert.IsTrue(LineF.Equals(lineF, new LineF(1.1f, 2.9f, 3.9f, 5.1f), 0.2f));
 }
Ejemplo n.º 39
0
 private static Vector2 GetAngularVelocity(IPortal portal, float intersectT)
 {
     Vector2 intersect = new LineF(GetWorldVerts(portal)).Lerp(intersectT);
     return MathExt.AngularVelocity(intersect, portal.WorldTransform.Position, portal.WorldVelocity.Rotation);
 }
Ejemplo n.º 40
0
 public static LineF[] GetFovLines(IPortal portal, Vector2 origin, float distance, Transform2 transform)
 {
     Vector2[] vertices = GetFov(portal, origin, distance);
     LineF[] lines = new LineF[] {
         new LineF(vertices[1], vertices[2]),
         new LineF(vertices[0], vertices[vertices.Length-1])
     };
     return lines;
 }
Ejemplo n.º 41
0
 public void GetSideOfTest14()
 {
     float rot = 0;
     for (int i = 0; i < 10; i++)
     {
         Vector2 v0 = new Vector2((float)Math.Cos(rot), (float)Math.Sin(rot));
         Vector2 v1 = new Vector2((float)Math.Cos(rot + Math.PI), (float)Math.Sin(rot + Math.PI));
         Vector2 v2 = new Vector2((float)Math.Cos(rot + Math.PI/2), (float)Math.Sin(rot + Math.PI/2));
         LineF line = new LineF(v0, v1);
         Assert.IsTrue(line.GetSideOf(v2) == Side.Right);
     }
 }
Ejemplo n.º 42
0
 public void GetSideOfTest12()
 {
     LineF line = new LineF(new Vector2(-5, 20), new Vector2(20, 0));
     Assert.IsFalse(line.GetSideOf(new Vector2(0, 0)) == Side.Left);
 }
Ejemplo n.º 43
0
 public void IsInsideFOVTest7()
 {
     float x = 0;
     float y = 0;
     for (double i = 0; i < Math.PI * 2; i += Math.PI / 20)
     {
         Scene scene = new Scene();
         FloatPortal p0 = new FloatPortal(scene);
         Entity node = new Entity(scene);
         Transform2.SetPosition(node, new Vector2(x, y));
         Transform2.SetRotation(node, (float)(i + Math.PI / 4));
         p0.SetParent(node);
         PortalCommon.UpdateWorldTransform(scene);
         Vector2 viewPoint = new Vector2(x + (float)Math.Cos(i), y + (float)Math.Sin(i));
         Vector2 lookPoint = new Vector2(x + (float)Math.Cos(i) * 2, y + (float)Math.Sin(i) * 2);
         LineF line = new LineF(Vector2Ext.Transform(Portal.GetVerts(p0), p0.GetWorldTransform().GetMatrix()));
         Assert.IsFalse(line.IsInsideFOV(viewPoint, lookPoint));
     }
 }
Ejemplo n.º 44
0
 public void GetSideOfTest13()
 {
     LineF line = new LineF(new Vector2(5, 20), new Vector2(10, 25));
     LineF lineCheck = new LineF(new Vector2(-25, 10), new Vector2(25, 10));
     Assert.IsTrue(line.GetSideOf(lineCheck) == Side.Neither);
 }
Ejemplo n.º 45
0
        public static void SaveToFile(string filename, Document document, ExportForm form)
        {
            var    map      = document.Map;
            string filepath = System.IO.Path.GetDirectoryName(filename);

            filename = System.IO.Path.GetFileName(filename);
            filename = System.IO.Path.GetFileNameWithoutExtension(filename) + ".rm2";
            string lmPath = System.IO.Path.GetFileNameWithoutExtension(filename) + "_lm";

            List <Lightmap.LMFace> faces; int lmCount;
            List <Lightmap.Light>  lights;

            Lightmap.Lightmapper.Render(document, form, out faces, out lmCount);
            Lightmap.Light.FindLights(map, out lights);

            IEnumerable <Face> transparentFaces = map.WorldSpawn.Find(x => x is Solid).OfType <Solid>().SelectMany(x => x.Faces).Where(x => {
                if (x.Texture?.Texture == null)
                {
                    return(false);
                }
                if (!x.Texture.Texture.HasTransparency())
                {
                    return(false);
                }
                if (x.Texture.Name.Contains("tooltextures"))
                {
                    return(false);
                }

                return(true);
            });

            IEnumerable <Face> invisibleCollisionFaces = map.WorldSpawn.Find(x => x is Solid).OfType <Solid>().SelectMany(x => x.Faces).Where(x => x.Texture.Name.ToLowerInvariant() == "tooltextures/invisible_collision");

            Lightmap.Lightmapper.SaveLightmaps(document, lmCount, filepath + "/" + lmPath, true);
            lmPath = System.IO.Path.GetFileName(lmPath);

            List <Waypoint> waypoints = map.WorldSpawn.Find(x => x.ClassName != null && x.ClassName.ToLower() == "waypoint").OfType <Entity>().Select(x => new Waypoint(x)).ToList();

            IEnumerable <Entity> props = map.WorldSpawn.Find(x => x.ClassName != null && x.ClassName.ToLower() == "model").OfType <Entity>();

            form.ProgressLog.Invoke((MethodInvoker)(() => form.ProgressLog.AppendText("\nDetermining waypoint visibility...")));
            form.ProgressBar.Invoke((MethodInvoker)(() => form.ProgressBar.Value = 9100));

            for (int i = 0; i < waypoints.Count; i++)
            {
                for (int j = 0; j < waypoints.Count; j++)
                {
                    if (j > i)
                    {
                        waypoints[i].Connections.Add(j);
                    }
                    else if (j < i)
                    {
                        if (waypoints[j].Connections.Contains(i))
                        {
                            waypoints[i].Connections.Add(j);
                        }
                    }
                }
                foreach (Lightmap.LMFace face in faces)
                {
                    for (int j = 0; j < waypoints[i].Connections.Count; j++)
                    {
                        int connection = waypoints[i].Connections[j];
                        if (connection < i)
                        {
                            continue;
                        }
                        LineF line1 = new LineF(waypoints[i].Location, waypoints[connection].Location);
                        LineF line2 = new LineF(waypoints[connection].Location, waypoints[i].Location);
                        if (face.GetIntersectionPoint(line1) != null || face.GetIntersectionPoint(line2) != null)
                        {
                            waypoints[i].Connections.RemoveAt(j);
                            j--;
                        }
                    }
                }
            }

            FileStream   stream = new FileStream(filepath + "/" + filename, FileMode.Create);
            BinaryWriter br     = new BinaryWriter(stream);

            //header
            br.Write((byte)'.');
            br.Write((byte)'R');
            br.Write((byte)'M');
            br.Write((byte)'2');

            //textures
            List <Tuple <string, byte> > textures = new List <Tuple <string, byte> >();
            byte flag = (byte)RM2TextureLoadFlag.Opaque;

            foreach (Lightmap.LMFace face in faces)
            {
                if (!textures.Any(x => x.Item1 == face.Texture))
                {
                    textures.Add(new Tuple <string, byte>(face.Texture, flag));
                }
            }
            flag = (byte)RM2TextureLoadFlag.Alpha;
            foreach (Face face in transparentFaces)
            {
                if (!textures.Any(x => x.Item1 == face.Texture.Name))
                {
                    textures.Add(new Tuple <string, byte>(face.Texture.Name, flag));
                }
            }

            br.Write((byte)RM2Chunks.Textures);
            br.Write((byte)lmCount);
            br.Write((byte)textures.Count);
            foreach (Tuple <string, byte> tex in textures)
            {
                br.WriteByteString(tex.Item1);
                br.Write(tex.Item2);
            }

            //mesh
            int vertCount;
            int vertOffset;
            int triCount;

            for (int i = 0; i < textures.Count; i++)
            {
                for (int lmInd = 0; lmInd < lmCount; lmInd++)
                {
                    IEnumerable <Lightmap.LMFace> tLmFaces = faces.FindAll(x => x.Texture == textures[i].Item1 && x.LmIndex == lmInd);
                    vertCount  = 0;
                    vertOffset = 0;
                    triCount   = 0;

                    if (tLmFaces.Count() > 0)
                    {
                        foreach (Lightmap.LMFace face in tLmFaces)
                        {
                            vertCount += face.Vertices.Count;
                            triCount  += face.GetTriangleIndices().Count() / 3;
                        }

                        br.Write((byte)RM2Chunks.VisibleGeometry);
                        br.Write((byte)i);
                        if (lmCount > 1)
                        {
                            br.Write((byte)lmInd);
                        }

                        if (vertCount > UInt16.MaxValue)
                        {
                            throw new Exception("Vertex overflow!");
                        }
                        br.Write((UInt16)vertCount);
                        foreach (Lightmap.LMFace face in tLmFaces)
                        {
                            for (int j = 0; j < face.Vertices.Count; j++)
                            {
                                br.Write(face.Vertices[j].Location.X);
                                br.Write(face.Vertices[j].Location.Z);
                                br.Write(face.Vertices[j].Location.Y);

                                //br.Write((byte)255); //r
                                //br.Write((byte)255); //g
                                //br.Write((byte)255); //b

                                br.Write(face.Vertices[j].DiffU);
                                br.Write(face.Vertices[j].DiffV);

                                float lmMul = (lmCount > 1) ? 2.0f : 1.0f;
                                float uSub  = ((lmInd % 2) > 0) ? 0.5f : 0.0f;
                                float vSub  = ((lmInd / 2) > 0) ? 0.5f : 0.0f;

                                br.Write((face.Vertices[j].LMU - uSub) * lmMul);
                                br.Write((face.Vertices[j].LMV - vSub) * lmMul);
                            }
                        }
                        br.Write((UInt16)triCount);
                        foreach (Lightmap.LMFace face in tLmFaces)
                        {
                            foreach (uint ind in face.GetTriangleIndices())
                            {
                                br.Write((UInt16)(ind + vertOffset));
                            }

                            vertOffset += face.Vertices.Count;
                        }
                    }
                }

                IEnumerable <Face> tTrptFaces = transparentFaces.Where(x => x.Texture.Name == textures[i].Item1);
                vertCount  = 0;
                vertOffset = 0;
                triCount   = 0;

                if (tTrptFaces.Count() > 0)
                {
                    foreach (Face face in tTrptFaces)
                    {
                        vertCount += face.Vertices.Count;
                        triCount  += face.GetTriangleIndices().Count() / 3;
                    }

                    br.Write((byte)RM2Chunks.VisibleGeometry);
                    br.Write((byte)i);

                    if (vertCount > UInt16.MaxValue)
                    {
                        throw new Exception("Vertex overflow!");
                    }
                    br.Write((UInt16)vertCount);
                    foreach (Face face in tTrptFaces)
                    {
                        for (int j = 0; j < face.Vertices.Count; j++)
                        {
                            br.Write((float)face.Vertices[j].Location.X);
                            br.Write((float)face.Vertices[j].Location.Z);
                            br.Write((float)face.Vertices[j].Location.Y);

                            //vertex color is not used since we don't do vertex lighting anymore
                            //br.Write((byte)255); //r
                            //br.Write((byte)255); //g
                            //br.Write((byte)255); //b

                            br.Write((float)face.Vertices[j].TextureU);
                            br.Write((float)face.Vertices[j].TextureV);
                            br.Write(0.0f);
                            br.Write(0.0f);
                        }
                    }
                    br.Write((UInt16)triCount);
                    foreach (Face face in tTrptFaces)
                    {
                        foreach (uint ind in face.GetTriangleIndices())
                        {
                            br.Write((UInt16)(ind + vertOffset));
                        }

                        vertOffset += face.Vertices.Count;
                    }
                }
            }

            vertCount  = 0;
            vertOffset = 0;
            triCount   = 0;
            if (invisibleCollisionFaces.Count() > 0)
            {
                foreach (Face face in invisibleCollisionFaces)
                {
                    vertCount += face.Vertices.Count;
                    triCount  += face.GetTriangleIndices().Count() / 3;
                }

                br.Write((byte)RM2Chunks.InvisibleGeometry);

                if (vertCount > UInt16.MaxValue)
                {
                    throw new Exception("Vertex overflow!");
                }
                br.Write((UInt16)vertCount);
                foreach (Face face in invisibleCollisionFaces)
                {
                    for (int j = 0; j < face.Vertices.Count; j++)
                    {
                        br.Write((float)face.Vertices[j].Location.X);
                        br.Write((float)face.Vertices[j].Location.Z);
                        br.Write((float)face.Vertices[j].Location.Y);
                    }
                }
                br.Write((UInt16)triCount);
                foreach (Face face in invisibleCollisionFaces)
                {
                    foreach (uint ind in face.GetTriangleIndices())
                    {
                        br.Write((UInt16)(ind + vertOffset));
                    }

                    vertOffset += face.Vertices.Count;
                }
            }

            foreach (Lightmap.Light light in lights)
            {
                br.Write((byte)RM2Chunks.PointLight);

                br.Write(light.Origin.X);
                br.Write(light.Origin.Z);
                br.Write(light.Origin.Y);

                br.Write(light.Range);

                br.Write((byte)light.Color.X);
                br.Write((byte)light.Color.Y);
                br.Write((byte)light.Color.Z);
                br.Write(light.Intensity);
            }

            foreach (Waypoint wp in waypoints)
            {
                br.Write((byte)RM2Chunks.Waypoint);

                br.Write(wp.Location.X);
                br.Write(wp.Location.Z);
                br.Write(wp.Location.Y);

                for (int i = 0; i < wp.Connections.Count; i++)
                {
                    br.Write((byte)(wp.Connections[i] + 1));
                }
                br.Write((byte)0);
            }

            foreach (Entity prop in props)
            {
                br.Write((byte)RM2Chunks.Prop);

                br.WriteByteString(System.IO.Path.GetFileNameWithoutExtension(prop.EntityData.GetPropertyValue("file")));

                br.Write((float)prop.Origin.X);
                br.Write((float)prop.Origin.Z);
                br.Write((float)prop.Origin.Y);

                Coordinate rotation = prop.EntityData.GetPropertyCoordinate("angles");
                br.Write((float)rotation.X);
                br.Write((float)rotation.Y);
                br.Write((float)rotation.Z);

                Coordinate scale = prop.EntityData.GetPropertyCoordinate("scale");
                br.Write((float)scale.X);
                br.Write((float)scale.Y);
                br.Write((float)scale.Z);
            }

            br.Dispose();
            stream.Dispose();

            form.ProgressLog.Invoke((MethodInvoker)(() => form.ProgressLog.AppendText("\nDone!")));
            form.ProgressBar.Invoke((MethodInvoker)(() => form.ProgressBar.Value = 10000));
        }
Ejemplo n.º 46
0
        /// <summary>
        /// Get all valid portals that collide with a polygon.  Portals can occlude eachother.
        /// </summary>
        /// <param name="margin">Minimum distance inside of polygon for a portal collision to count.  
        /// Useful for avoiding round off errors.</param>
        public static List<IPortal> GetCollisions(Vector2 center, IList<Vector2> polygon, IList<IPortal> portals, double margin = 0)
        {
            List<IPortal> collisions = new List<IPortal>();
            foreach (IPortal p in portals.Where(item => IsValid(item)))
            {
                LineF portalLine = new LineF(GetWorldVerts(p));
                if (MathExt.LineInPolygon(portalLine, polygon) &&
                    (margin == 0 ||
                    MathExt.PointPolygonDistance(portalLine[0], polygon) > margin ||
                    MathExt.PointPolygonDistance(portalLine[1], polygon) > margin))
                {
                    collisions.Add(p);
                }
            }

            var ordered = collisions.OrderBy(item => (item.WorldTransform.Position - center).Length).ToList();
            for (int i = 0; i < ordered.Count; i++)
            {
                IPortal portal = ordered[i];
                for (int j = ordered.Count - 1; j > i; j--)
                {
                    LineF currentLine = new LineF(GetWorldVerts(ordered[i]));
                    LineF checkLine = new LineF(GetWorldVerts(ordered[j]));
                    Side checkSide = currentLine.GetSideOf(checkLine);
                    if (checkSide != currentLine.GetSideOf(center))
                    {
                        ordered.RemoveAt(j);
                    }
                }
            }
            return ordered.ToList();
        }
Ejemplo n.º 47
0
        public void IntersectTest6()
        {
            LineF line0 = new LineF(new Vector2(1f, 1f), new Vector2(2f, 2f));
            LineF line1 = new LineF(new Vector2(1.5f, 3f), new Vector2(1.5f, -1.5f));
            IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, false);

            IntersectCoord comparison = new IntersectCoord();
            comparison.Exists = true;
            comparison.Position = new Vector2d(1.5, 1.5);
            comparison.TFirst = 0.5;
            comparison.TLast = 1/(double)3;
            Assert.IsTrue(intersect.Equals(comparison));
        }
Ejemplo n.º 48
0
        /// <summary>
        /// Returns all the portal intersections for a line in this path.  
        /// TFirst is the t value for the line intersection.  
        /// TLast is the t value for the portal intersection.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public static IntersectCoord[] PathIntersections(PortalPath path, LineF line)
        {
            IntersectCoord[] intersections = new IntersectCoord[path.Portals.Count];
            line = line.ShallowClone();

            LineF[] portalLines = new LineF[path.Portals.Count];
            for (int i = 0; i < path.Portals.Count; i++)
            {
                portalLines[i] = new LineF(GetWorldVerts(path.Portals[i]));
            }

            for (int i = path.Portals.Count - 1; i >= 0; i--)
            {
                Matrix4 mat = GetLinkedMatrix(path.Portals[i].Linked);
                line[1] = line.Transform(mat)[1];
                for (int j = i + 1; j < path.Portals.Count; j++)
                {
                    portalLines[j] = portalLines[j].Transform(mat);
                }
            }

            for (int i = 0; i < path.Portals.Count; i++)
            {
                intersections[i] = MathExt.LineLineIntersect(portalLines[i], line, true);
            }

            return intersections;
        }
Ejemplo n.º 49
0
        public void IntersectTest7()
        {
            LineF line0 = new LineF(new Vector2(1f, 1f), new Vector2(2f, 2f));
            LineF line1 = new LineF(new Vector2(3f, 9f), new Vector2(12f, -6f));
            IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, true);

            IntersectCoord comparison = new IntersectCoord();
            comparison.Exists = false;
            Assert.IsTrue(intersect.Equals(comparison));
        }
Ejemplo n.º 50
0
        public void FillPolygon(Color Col, ref PointF[] points)
        {
            int pCount = points.Count();
            int val    = Col.ToArgb();

            // Add the first point to the end of the array, for easier line access
            Array.Resize(ref points, points.Length + 1);
            points[points.Count() - 1] = points[0];

            // Convert array of points to an array of Lines
            LineF[] lines = new LineF[pCount];
            int     LID   = 0;
            // Get min/max Ys too
            float FminY = points[0].Y;
            float FmaxY = points[0].Y;

            for (int i = 0; i < pCount; i++)
            {
                if (points[i].Y < FminY)
                {
                    FminY = points[i].Y;
                }
                else if (points[i].Y > FmaxY)
                {
                    FmaxY = points[i].Y;
                }

                if (points[i].Y == points[i + 1].Y) // Exclude lines that are perfectly horizontal
                {
                    continue;
                }

                if (points[i].Y < points[i + 1].Y)
                {
                    lines[LID] = new LineF(points[i], points[i + 1]);
                }
                else
                {
                    lines[LID] = new LineF(points[i + 1], points[i]);
                }
                LID++;
            }
            Array.Resize(ref lines, LID);
            // Remove last element of points, which was added here
            Array.Resize(ref points, points.Length - 1);

            // Array for maximum possible length fill line
            int[] arr4 = new int[Width];
            for (int i = 0; i < arr4.Length; i++)
            {
                arr4[i] = val;
            }

            // Stay within top/bottom bounds
            int minY = (int)FminY;
            int maxY = (int)FmaxY;

            if (minY < 0)
            {
                minY = 0;
            }
            if (maxY >= Height)
            {
                maxY = Height - 1;
            }

            // Lines to Check (for if a new line matches iY)
            List <int> ltc = new List <int>();

            for (int i = 0; i < lines.Length; i++)
            {
                ltc.Add(i);
            }
            IntPtr       YPtr      = BLoc + (minY * Stride);
            List <LineF> intersect = new List <LineF>(); // Lines that went through last loop

            // Find lines to fill for each Y pixel of any line
            for (int iY = minY; iY < maxY; iY++)
            {
                List <int> Xpos = new List <int>();
                // Find lines that still go through iY
                for (int i2 = 0; i2 < intersect.Count; i2++)
                {
                    if (intersect[i2].end.Y > iY)
                    {
                        Xpos.Add((int)intersect[i2].XatY(iY));
                    }
                    else
                    {
                        intersect.RemoveAt(i2);
                        i2--;
                    }
                }
                // Find new lines that go through iY
                for (int i2 = 0; i2 < ltc.Count; i2++)
                {
                    LineF cL = lines[ltc[i2]];
                    if (iY >= cL.start.Y)
                    {
                        intersect.Add(cL);
                        ltc.RemoveAt(i2);
                        i2--;
                        if (iY < cL.end.Y)
                        {
                            Xpos.Add((int)cL.XatY(iY));
                        }
                    }
                }
                // Sort by Xpos at iY
                Xpos.Sort();
                // Fill!
                int iF = 0;
                for (; iF < Xpos.Count && Xpos[iF] < 0; iF += 2)
                {
                    Xpos[iF] = 0;
                    if (Xpos[iF + 1] >= 0)
                    {
                        break;
                    }
                }
                for (; iF < Xpos.Count; iF += 2)
                {
                    if (Xpos[iF + 1] >= Width)
                    {
                        Xpos[iF + 1] = Width - 1;
                        if (Xpos[iF] >= Width)
                        {
                            break;
                        }
                    }
                    IntPtr dest = YPtr + (Xpos[iF] * 4);
                    Marshal.Copy(arr4, 0, dest, Xpos[iF + 1] - Xpos[iF]);
                }
                YPtr += Stride;
            }
        }
Ejemplo n.º 51
0
            /// <summary>
            /// Calculates intersection - if any - of two lines
            /// </summary>
            /// <param name="otherLine"></param>
            /// <returns>Intersection or null</returns>
            /// <remarks> </remarks>
            public Point Intersection(LineF otherLine)
            {
                var a1 = Y2 - Y1;
                var b1 = X1 - X2;
                var c1 = X2 * Y1 - X1 * Y2;

                /* Compute r3 and r4.
                 */

                var r3 = a1 * otherLine.X1 + b1 * otherLine.Y1 + c1;
                var r4 = a1 * otherLine.X2 + b1 * otherLine.Y2 + c1;

                /* Check signs of r3 and r4.  If both point 3 and point 4 lie on
                 * same side of line 1, the line segments do not intersect.
                 */

                if (r3 != 0 && r4 != 0 && Math.Sign(r3) == Math.Sign(r4))
                {
                    return(null); // DONT_INTERSECT
                }

                /* Compute a2, b2, c2 */

                var a2 = otherLine.Y2 - otherLine.Y1;
                var b2 = otherLine.X1 - otherLine.X2;
                var c2 = otherLine.X2 * otherLine.Y1 - otherLine.X1 * otherLine.Y2;

                /* Compute r1 and r2 */

                var r1 = a2 * X1 + b2 * Y1 + c2;
                var r2 = a2 * X2 + b2 * Y2 + c2;

                /* Check signs of r1 and r2.  If both point 1 and point 2 lie
                 * on same side of second line segment, the line segments do
                 * not intersect.
                 */
                if (r1 != 0 && r2 != 0 && Math.Sign(r1) == Math.Sign(r2))
                {
                    return(null);  // DONT_INTERSECT
                }

                /* Line segments intersect: compute intersection point.
                 */

                var denom = a1 * b2 - a2 * b1;

                if (denom == 0)
                {
                    return(null); //( COLLINEAR );
                }
                var offset = denom < 0 ? -denom / 2 : denom / 2;

                /* The denom/2 is to get rounding instead of truncating.  It
                 * is added or subtracted to the numerator, depending upon the
                 * sign of the numerator.
                 */

                var num = b1 * c2 - b2 * c1;
                var x   = (num < 0 ? num - offset : num + offset) / denom;

                num = a2 * c1 - a1 * c2;
                var y = (num < 0 ? num - offset : num + offset) / denom;

                return(new Point(x, y));
            }
Ejemplo n.º 52
0
        /// <summary>
        /// Returns true if a contact should not be disabled due to portal clipping.
        /// </summary>
        private bool IsContactValid(Contact contact)
        {
            FixtureData[] fixtureData = new FixtureData[2];
            fixtureData[0] = FixtureExt.GetData(contact.FixtureA);
            fixtureData[1] = FixtureExt.GetData(contact.FixtureB);

            BodyData[] bodyData = new BodyData[2];
            bodyData[0] = BodyExt.GetData(contact.FixtureA.Body);
            bodyData[1] = BodyExt.GetData(contact.FixtureB.Body);

            Xna.Vector2 normal;
            FixedArray2<Xna.Vector2> vList;
            contact.GetWorldManifold(out normal, out vList);

            if (bodyData[0].IsChild || bodyData[1].IsChild)
            {
                if (bodyData[0].IsChild && bodyData[1].IsChild)
                {
                    //return true;
                }

                int childIndex = bodyData[0].IsChild ? 0 : 1;
                int otherIndex = bodyData[0].IsChild ? 1 : 0;
                BodyData bodyDataChild = bodyData[childIndex];
                BodyData bodyDataOther = bodyData[otherIndex];
                FixtureData fixtureDataChild = fixtureData[childIndex];
                FixtureData fixtureDataOther = fixtureData[otherIndex];

            }

            //Contact is invalid if it is between two fixtures where one fixture is colliding with a portal on the other fixture.
            if (fixtureData[0].IsPortalParentless() && fixtureData[1].IsPortalParentless())
            {
                for (int i = 0; i < fixtureData.Length; i++)
                {
                    int iNext = (i + 1) % fixtureData.Length;
                    var intersection = fixtureData[iNext].GetPortalChildren().Intersect(fixtureData[i].PortalCollisions);
                    if (intersection.Count() > 0)
                    {
                        //Debug.Fail("Fixtures with portal collisions should be filtered.");
                        return false;
                    }
                }
            }

            //Contact is invalid if it is too close to a portal.
            foreach (IPortal p in Scene.GetPortalList())
            {
                if (!Portal.IsValid(p))
                {
                    continue;
                }
                FixturePortal portal = p as FixturePortal;
                if (portal != null)
                {
                    //Don't consider this portal if its fixtures are part of the contact.
                    if (fixtureData[0].PartOfPortal(portal) || fixtureData[1].PartOfPortal(portal))
                    {
                        continue;
                    }

                    LineF line = new LineF(Portal.GetWorldVerts(portal));
                    double[] vDist = new double[] {
                        MathExt.PointLineDistance(vList[0], line, true),
                        MathExt.PointLineDistance(vList[1], line, true)
                    };
                    //Only consider contacts that are between the fixture this portal is parented too and some other fixture.
                    if (contact.FixtureA == FixtureExt.GetFixtureAttached(portal) || contact.FixtureB == FixtureExt.GetFixtureAttached(portal))
                    {
                        if (contact.Manifold.PointCount == 1)
                        {
                            if (vDist[0] < FixturePortal.CollisionMargin)
                            {
                                return false;
                            }
                        }
                        else if (vDist[0] < FixturePortal.CollisionMargin && vDist[1] < FixturePortal.CollisionMargin)
                        {
                            return false;
                        }
                    }
                }
            }

            //Contact is invalid if it is on the opposite side of a colliding portal.
            for (int i = 0; i < fixtureData.Length; i++)
            {
                int iNext = (i + 1) % fixtureData.Length;
                foreach (IPortal portal in fixtureData[i].PortalCollisions)
                {
                    LineF line = new LineF(Portal.GetWorldVerts(portal));

                    FixturePortal cast = portal as FixturePortal;
                    if (cast != null)
                    {
                        if (fixtureData[i].PartOfPortal(cast) || fixtureData[iNext].PartOfPortal(cast))
                        {
                            continue;
                        }
                    }

                    //Contact is invalid if it is on the opposite side of the portal from its body origin.
                    //Xna.Vector2 pos = BodyExt.GetData(fixtureData[i].Fixture.Body).PreviousPosition;
                    Vector2 pos = BodyExt.GetLocalOrigin(fixtureData[i].Fixture.Body);
                    bool oppositeSides0 = line.GetSideOf(vList[0]) != line.GetSideOf(pos);
                    Debug.Assert(contact.Manifold.PointCount > 0);
                    if (contact.Manifold.PointCount == 1)
                    {
                        if (oppositeSides0)
                        {
                            return false;
                        }
                    }
                    else
                    //else if (line.GetSideOf((vList[0] + vList[1])/2) != line.GetSideOf(pos))
                    {
                        bool oppositeSides1 = line.GetSideOf(vList[1]) != line.GetSideOf(pos);
                        /*if (oppositeSides0 && oppositeSides1)
                        {
                            return false;
                        }
                        if (oppositeSides0)
                        {
                            contact.Manifold.Points[0] = contact.Manifold.Points[1];
                        }
                        contact.Manifold.PointCount = 1;

                        return true;*/
                        if (!oppositeSides0 && !oppositeSides1)
                        {
                            continue;
                        }
                        if (!fixtureData[iNext].PortalCollisions.Contains(portal) || !(oppositeSides0 || oppositeSides1))
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
Ejemplo n.º 53
0
        public void IntersectTest8()
        {
            LineF line0 = new LineF(new Vector2(1f, 1f), new Vector2(2f, 2f));
            LineF line1 = new LineF(new Vector2(3f, 9f), new Vector2(12f, -6f));
            IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, false);

            IntersectCoord comparison = new IntersectCoord();
            comparison.Exists = true;
            comparison.Position = new Vector2d(5.25, 5.25);
            comparison.TFirst = 4.25;
            comparison.TLast = 0.25;
            Assert.IsTrue(intersect.Equals(comparison));
        }
Ejemplo n.º 54
0
        private static void RenderLightOntoFace(Document doc, float[][] bitmaps, List <Light> lights, LightmapGroup group, LMFace targetFace, IEnumerable <LMFace> blockerFaces)
        {
            Random rand = new Random();

            int writeX = group.writeX;
            int writeY = group.writeY;

            int textureDims;

            lock (doc.TextureCollection.Lightmaps)
            {
                textureDims = doc.TextureCollection.Lightmaps[0].Width;
            }

            lights = lights.FindAll(x =>
            {
                float range   = x.Range;
                BoxF lightBox = new BoxF(x.Origin - new CoordinateF(range, range, range), x.Origin + new CoordinateF(range, range, range));
                return(lightBox.IntersectsWith(targetFace.BoundingBox));
            });

            float?minX = null; float?maxX = null;
            float?minY = null; float?maxY = null;

            foreach (CoordinateF coord in targetFace.Vertices.Select(x => x.Location))
            {
                float x = coord.Dot(group.uAxis);
                float y = coord.Dot(group.vAxis);

                if (minX == null || x < minX)
                {
                    minX = x;
                }
                if (minY == null || y < minY)
                {
                    minY = y;
                }
                if (maxX == null || x > maxX)
                {
                    maxX = x;
                }
                if (maxY == null || y > maxY)
                {
                    maxY = y;
                }
            }

            CoordinateF leewayPoint = group.Plane.PointOnPlane + (group.Plane.Normal * Math.Max(LightmapConfig.DownscaleFactor * 0.25f, 1.5f));

            minX -= LightmapConfig.DownscaleFactor; minY -= LightmapConfig.DownscaleFactor;
            maxX += LightmapConfig.DownscaleFactor; maxY += LightmapConfig.DownscaleFactor;

            minX /= LightmapConfig.DownscaleFactor; minX = (float)Math.Ceiling(minX.Value); minX *= LightmapConfig.DownscaleFactor;
            minY /= LightmapConfig.DownscaleFactor; minY = (float)Math.Ceiling(minY.Value); minY *= LightmapConfig.DownscaleFactor;
            maxX /= LightmapConfig.DownscaleFactor; maxX = (float)Math.Ceiling(maxX.Value); maxX *= LightmapConfig.DownscaleFactor;
            maxY /= LightmapConfig.DownscaleFactor; maxY = (float)Math.Ceiling(maxY.Value); maxY *= LightmapConfig.DownscaleFactor;

            foreach (LMFace.Vertex vert in targetFace.Vertices)
            {
                float x = vert.Location.Dot(group.uAxis);
                float y = vert.Location.Dot(group.vAxis);

                float u = (writeX + 0.5f + (x - group.minTotalX.Value) / LightmapConfig.DownscaleFactor);
                float v = (writeY + 0.5f + (y - group.minTotalY.Value) / LightmapConfig.DownscaleFactor);

                targetFace.LmIndex = (u >= LightmapConfig.TextureDims ? 1 : 0) + (v >= LightmapConfig.TextureDims ? 2 : 0);

                u /= (float)textureDims;
                v /= (float)textureDims;

                vert.LMU = u; vert.LMV = v;
                vert.OriginalVertex.LMU = u; vert.OriginalVertex.LMV = v;
            }

            float centerX           = (maxX.Value + minX.Value) / 2;
            float centerY           = (maxY.Value + minY.Value) / 2;

            int iterX = (int)Math.Ceiling((maxX.Value - minX.Value) / LightmapConfig.DownscaleFactor);
            int iterY = (int)Math.Ceiling((maxY.Value - minY.Value) / LightmapConfig.DownscaleFactor);

            float[][,] r = new float[4][, ];
            r[0]         = new float[iterX, iterY];
            r[1]         = new float[iterX, iterY];
            r[2]         = new float[iterX, iterY];
            r[3]         = new float[iterX, iterY];
            float[][,] g = new float[4][, ];
            g[0]         = new float[iterX, iterY];
            g[1]         = new float[iterX, iterY];
            g[2]         = new float[iterX, iterY];
            g[3]         = new float[iterX, iterY];
            float[][,] b = new float[4][, ];
            b[0]         = new float[iterX, iterY];
            b[1]         = new float[iterX, iterY];
            b[2]         = new float[iterX, iterY];
            b[3]         = new float[iterX, iterY];

            foreach (Light light in lights)
            {
                CoordinateF lightPos   = light.Origin;
                float       lightRange = light.Range;
                CoordinateF lightColor = light.Color * (1.0f / 255.0f) * light.Intensity;

                BoxF          lightBox = new BoxF(new BoxF[] { targetFace.BoundingBox, new BoxF(light.Origin - new CoordinateF(30.0f, 30.0f, 30.0f), light.Origin + new CoordinateF(30.0f, 30.0f, 30.0f)) });
                List <LMFace> applicableBlockerFaces = blockerFaces.Where(x =>
                {
                    if (x == targetFace)
                    {
                        return(false);
                    }
                    if (group.Faces.Contains(x))
                    {
                        return(false);
                    }
                    //return true;
                    if (lightBox.IntersectsWith(x.BoundingBox))
                    {
                        return(true);
                    }
                    return(false);
                }).ToList();

                bool[,] illuminated = new bool[iterX, iterY];

                for (int y = 0; y < iterY; y++)
                {
                    for (int x = 0; x < iterX; x++)
                    {
                        illuminated[x, y] = true;
                    }
                }

                for (int y = 0; y < iterY; y++)
                {
                    for (int x = 0; x < iterX; x++)
                    {
                        int tX = (int)(writeX + x + (int)(minX - group.minTotalX) / LightmapConfig.DownscaleFactor);
                        int tY = (int)(writeY + y + (int)(minY - group.minTotalY) / LightmapConfig.DownscaleFactor);

                        if (tX >= 0 && tY >= 0 && tX < textureDims && tY < textureDims)
                        {
                            int offset = (tX + tY * textureDims) * Bitmap.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format32bppArgb) / 8;
                            bitmaps[0][offset + 3] = 1.0f;
                            bitmaps[1][offset + 3] = 1.0f;
                            bitmaps[2][offset + 3] = 1.0f;
                            bitmaps[3][offset + 3] = 1.0f;
                        }
                    }
                }

                for (int y = 0; y < iterY; y++)
                {
                    for (int x = 0; x < iterX; x++)
                    {
                        float       ttX          = minX.Value + (x * LightmapConfig.DownscaleFactor);
                        float       ttY          = minY.Value + (y * LightmapConfig.DownscaleFactor);
                        CoordinateF pointOnPlane = (ttX - centerX) * group.uAxis + (ttY - centerY) * group.vAxis + targetFace.BoundingBox.Center;

                        /*Entity entity = new Entity(map.IDGenerator.GetNextObjectID());
                         * entity.Colour = Color.Pink;
                         * entity.Origin = new Coordinate(pointOnPlane);
                         * entity.UpdateBoundingBox();
                         * entity.SetParent(map.WorldSpawn);*/

                        int tX = (int)(writeX + x + (int)(minX - group.minTotalX) / LightmapConfig.DownscaleFactor);
                        int tY = (int)(writeY + y + (int)(minY - group.minTotalY) / LightmapConfig.DownscaleFactor);

                        CoordinateF luxelColor0    = new CoordinateF(r[0][x, y], g[0][x, y], b[0][x, y]);
                        CoordinateF luxelColor1    = new CoordinateF(r[1][x, y], g[1][x, y], b[1][x, y]);
                        CoordinateF luxelColor2    = new CoordinateF(r[2][x, y], g[2][x, y], b[2][x, y]);
                        CoordinateF luxelColorNorm = new CoordinateF(r[3][x, y], g[3][x, y], b[3][x, y]);

                        float dotToLight0    = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.LightBasis0), 0.0f);
                        float dotToLight1    = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.LightBasis1), 0.0f);
                        float dotToLight2    = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.LightBasis2), 0.0f);
                        float dotToLightNorm = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.Normal), 0.0f);

                        if (illuminated[x, y] && (pointOnPlane - lightPos).LengthSquared() < lightRange * lightRange)
                        {
#if TRUE
                            LineF lineTester = new LineF(lightPos, pointOnPlane);
                            for (int i = 0; i < applicableBlockerFaces.Count; i++)
                            {
                                LMFace      otherFace = applicableBlockerFaces[i];
                                CoordinateF hit       = otherFace.GetIntersectionPoint(lineTester);
                                if (hit != null && ((hit - leewayPoint).Dot(group.Plane.Normal) > 0.0f || (hit - pointOnPlane).LengthSquared() > LightmapConfig.DownscaleFactor * 2f))
                                {
                                    applicableBlockerFaces.RemoveAt(i);
                                    applicableBlockerFaces.Insert(0, otherFace);
                                    illuminated[x, y] = false;
                                    i++;
                                    break;
                                }
                            }
#endif
                        }
                        else
                        {
                            illuminated[x, y] = false;
                        }

                        if (illuminated[x, y])
                        {
                            float brightness = (lightRange - (pointOnPlane - lightPos).VectorMagnitude()) / lightRange;

                            if (light.Direction != null)
                            {
                                float directionDot = light.Direction.Dot((pointOnPlane - lightPos).Normalise());

                                if (directionDot < light.innerCos)
                                {
                                    if (directionDot < light.outerCos)
                                    {
                                        brightness = 0.0f;
                                    }
                                    else
                                    {
                                        brightness *= (directionDot - light.outerCos.Value) / (light.innerCos.Value - light.outerCos.Value);
                                    }
                                }
                            }

                            float brightness0    = dotToLight0 * brightness * brightness;
                            float brightness1    = dotToLight1 * brightness * brightness;
                            float brightness2    = dotToLight2 * brightness * brightness;
                            float brightnessNorm = dotToLightNorm * brightness * brightness;

                            brightness0    += ((float)rand.NextDouble() - 0.5f) * 0.005f;
                            brightness1    += ((float)rand.NextDouble() - 0.5f) * 0.005f;
                            brightness2    += ((float)rand.NextDouble() - 0.5f) * 0.005f;
                            brightnessNorm += ((float)rand.NextDouble() - 0.5f) * 0.005f;

                            r[0][x, y] += lightColor.Z * brightness0; if (r[0][x, y] > 1.0f)
                            {
                                r[0][x, y] = 1.0f;
                            }
                            if (r[0][x, y] < 0)
                            {
                                r[0][x, y] = 0;
                            }
                            g[0][x, y] += lightColor.Y * brightness0; if (g[0][x, y] > 1.0f)
                            {
                                g[0][x, y] = 1.0f;
                            }
                            if (g[0][x, y] < 0)
                            {
                                g[0][x, y] = 0;
                            }
                            b[0][x, y] += lightColor.X * brightness0; if (b[0][x, y] > 1.0f)
                            {
                                b[0][x, y] = 1.0f;
                            }
                            if (b[0][x, y] < 0)
                            {
                                b[0][x, y] = 0;
                            }

                            r[1][x, y] += lightColor.Z * brightness1; if (r[1][x, y] > 1.0f)
                            {
                                r[1][x, y] = 1.0f;
                            }
                            if (r[1][x, y] < 0)
                            {
                                r[1][x, y] = 0;
                            }
                            g[1][x, y] += lightColor.Y * brightness1; if (g[1][x, y] > 1.0f)
                            {
                                g[1][x, y] = 1.0f;
                            }
                            if (g[1][x, y] < 0)
                            {
                                g[1][x, y] = 0;
                            }
                            b[1][x, y] += lightColor.X * brightness1; if (b[1][x, y] > 1.0f)
                            {
                                b[1][x, y] = 1.0f;
                            }
                            if (b[1][x, y] < 0)
                            {
                                b[1][x, y] = 0;
                            }

                            r[2][x, y] += lightColor.Z * brightness2; if (r[2][x, y] > 1.0f)
                            {
                                r[2][x, y] = 1.0f;
                            }
                            if (r[2][x, y] < 0)
                            {
                                r[2][x, y] = 0;
                            }
                            g[2][x, y] += lightColor.Y * brightness2; if (g[2][x, y] > 1.0f)
                            {
                                g[2][x, y] = 1.0f;
                            }
                            if (g[2][x, y] < 0)
                            {
                                g[2][x, y] = 0;
                            }
                            b[2][x, y] += lightColor.X * brightness2; if (b[2][x, y] > 1.0f)
                            {
                                b[2][x, y] = 1.0f;
                            }
                            if (b[2][x, y] < 0)
                            {
                                b[2][x, y] = 0;
                            }

                            r[3][x, y] += lightColor.Z * brightnessNorm; if (r[3][x, y] > 1.0f)
                            {
                                r[3][x, y] = 1.0f;
                            }
                            if (r[3][x, y] < 0)
                            {
                                r[3][x, y] = 0;
                            }
                            g[3][x, y] += lightColor.Y * brightnessNorm; if (g[3][x, y] > 1.0f)
                            {
                                g[3][x, y] = 1.0f;
                            }
                            if (g[3][x, y] < 0)
                            {
                                g[3][x, y] = 0;
                            }
                            b[3][x, y] += lightColor.X * brightnessNorm; if (b[3][x, y] > 1.0f)
                            {
                                b[3][x, y] = 1.0f;
                            }
                            if (b[3][x, y] < 0)
                            {
                                b[3][x, y] = 0;
                            }

                            luxelColor0    = new CoordinateF(r[0][x, y], g[0][x, y], b[0][x, y]);
                            luxelColor1    = new CoordinateF(r[1][x, y], g[1][x, y], b[1][x, y]);
                            luxelColor2    = new CoordinateF(r[2][x, y], g[2][x, y], b[2][x, y]);
                            luxelColorNorm = new CoordinateF(r[3][x, y], g[3][x, y], b[3][x, y]);

                            if (tX >= 0 && tY >= 0 && tX < textureDims && tY < textureDims)
                            {
                                int offset = (tX + tY * textureDims) * Bitmap.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format32bppArgb) / 8;
                                if (luxelColor0.X + luxelColor0.Y + luxelColor0.Z > bitmaps[0][offset + 2] + bitmaps[0][offset + 1] + bitmaps[0][offset + 0])
                                {
                                    bitmaps[0][offset + 0] = luxelColor0.X;
                                    bitmaps[0][offset + 1] = luxelColor0.Y;
                                    bitmaps[0][offset + 2] = luxelColor0.Z;
                                }
                                if (luxelColor1.X + luxelColor1.Y + luxelColor1.Z > bitmaps[1][offset + 2] + bitmaps[1][offset + 1] + bitmaps[1][offset + 0])
                                {
                                    bitmaps[1][offset + 0] = luxelColor1.X;
                                    bitmaps[1][offset + 1] = luxelColor1.Y;
                                    bitmaps[1][offset + 2] = luxelColor1.Z;
                                }
                                if (luxelColor2.X + luxelColor2.Y + luxelColor2.Z > bitmaps[2][offset + 2] + bitmaps[2][offset + 1] + bitmaps[2][offset + 0])
                                {
                                    bitmaps[2][offset + 0] = luxelColor2.X;
                                    bitmaps[2][offset + 1] = luxelColor2.Y;
                                    bitmaps[2][offset + 2] = luxelColor2.Z;
                                }
                                if (luxelColorNorm.X + luxelColorNorm.Y + luxelColorNorm.Z > bitmaps[3][offset + 2] + bitmaps[3][offset + 1] + bitmaps[3][offset + 0])
                                {
                                    bitmaps[3][offset + 0] = luxelColorNorm.X;
                                    bitmaps[3][offset + 1] = luxelColorNorm.Y;
                                    bitmaps[3][offset + 2] = luxelColorNorm.Z;
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 55
0
 public void ConstructorTest0()
 {
     LineF line = new LineF();
     Assert.IsTrue(line[0] == new Vector2());
     Assert.IsTrue(line[1] == new Vector2());
 }