예제 #1
0
		/// <summary>
		/// Adds shapes of entity to collision collection.
		/// </summary>
		/// <param name="shapedEntity"></param>
		public void Add(IShapedEntity shapedEntity)
		{
			if (shapedEntity.Shapes == null || shapedEntity.Shapes.Count == 0 || !shapedEntity.IsCollision)
				return;

			foreach (var points in shapedEntity.Shapes)
			{
				var line1 = new LinePath(points[0], points[1]);
				var line2 = new LinePath(points[1], points[2]);
				var line3 = new LinePath(points[2], points[3]);
				var line4 = new LinePath(points[3], points[0]);

				lock (_tree)
				{
					_tree.Insert(line1);
					_tree.Insert(line2);
					_tree.Insert(line3);
					_tree.Insert(line4);
				}

				lock (_reference)
				{
					if (!_reference.ContainsKey(shapedEntity.EntityId))
						_reference[shapedEntity.EntityId] = new List<LinePath>();

					_reference[shapedEntity.EntityId].Add(line1);
					_reference[shapedEntity.EntityId].Add(line2);
					_reference[shapedEntity.EntityId].Add(line3);
					_reference[shapedEntity.EntityId].Add(line4);
				}
			}
		}
예제 #2
0
        /// <summary>
        /// Adds shape to collisions, referenced by the given ident.
        /// </summary>
        /// <param name="ident"></param>
        /// <param name="shape"></param>
        public void Add(string ident, ShapeData shape)
        {
            var p1 = new Point(shape.X1, shape.Y1);
            var p2 = new Point(shape.X2, shape.Y2);
            var p3 = new Point(shape.X3, shape.Y3);
            var p4 = new Point(shape.X4, shape.Y4);

            var line1 = new LinePath(p1, p2);
            var line2 = new LinePath(p2, p3);
            var line3 = new LinePath(p3, p4);
            var line4 = new LinePath(p4, p1);

            lock (_tree)
            {
                _tree.Insert(line1);
                _tree.Insert(line2);
                _tree.Insert(line3);
                _tree.Insert(line4);
            }

            if (ident == null)
            {
                return;
            }

            lock (_reference)
            {
                if (!_reference.ContainsKey(ident))
                {
                    _reference[ident] = new List <LinePath>();
                }

                _reference[ident].Add(line1);
                _reference[ident].Add(line2);
                _reference[ident].Add(line3);
                _reference[ident].Add(line4);
            }
        }
예제 #3
0
        /// <summary>
        /// Adds shapes of entity to collision collection.
        /// </summary>
        /// <param name="shapedEntity"></param>
        public void Add(IShapedEntity shapedEntity)
        {
            if (shapedEntity.Shapes == null || shapedEntity.Shapes.Count == 0 || !shapedEntity.IsCollision)
            {
                return;
            }

            foreach (var points in shapedEntity.Shapes)
            {
                var line1 = new LinePath(points[0], points[1]);
                var line2 = new LinePath(points[1], points[2]);
                var line3 = new LinePath(points[2], points[3]);
                var line4 = new LinePath(points[3], points[0]);

                lock (_tree)
                {
                    _tree.Insert(line1);
                    _tree.Insert(line2);
                    _tree.Insert(line3);
                    _tree.Insert(line4);
                }

                lock (_reference)
                {
                    if (!_reference.ContainsKey(shapedEntity.EntityId))
                    {
                        _reference[shapedEntity.EntityId] = new List <LinePath>();
                    }

                    _reference[shapedEntity.EntityId].Add(line1);
                    _reference[shapedEntity.EntityId].Add(line2);
                    _reference[shapedEntity.EntityId].Add(line3);
                    _reference[shapedEntity.EntityId].Add(line4);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Returns true if the path between from and to intersects with
        /// anything and returns the intersection position via out.
        /// </summary>
        /// <param name="region"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="intersection"></param>
        /// <returns></returns>
        public bool Find(Position from, Position to, out Position intersection)
        {
            intersection = to;

            var x1 = from.X;
            var y1 = from.Y;
            var x2 = to.X;
            var y2 = to.Y;

            var intersections = new List <Position>();

            // Query lines
            var rect = new LinePath(from, to).Rect;

            // Extend rect a little, so there's no chance to miss any lines.
            rect.X      -= 100;
            rect.Y      -= 100;
            rect.Width  += 200;
            rect.Height += 200;

            List <LinePath> lines;

            lock (_tree)
                lines = _tree.Query(rect);

            // Get intersections
            foreach (var line in lines)
            {
                var x3 = line.P1.X;
                var y3 = line.P1.Y;
                var x4 = line.P2.X;
                var y4 = line.P2.Y;

                Position inter;
                if (this.FindIntersection(x1, y1, x2, y2, x3, y3, x4, y4, out inter))
                {
                    intersections.Add(inter);
                }
            }

            // No collisions
            if (intersections.Count < 1)
            {
                return(false);
            }

            // One collision
            if (intersections.Count == 1)
            {
                intersection = intersections[0];
                return(true);
            }

            // Select nearest intersection
            double distance = double.MaxValue;

            foreach (var inter in intersections)
            {
                var interDist = Math.Pow(x1 - inter.X, 2) + Math.Pow(y1 - inter.Y, 2);
                if (interDist < distance)
                {
                    intersection = inter;
                    distance     = interDist;
                }
            }

            return(true);
        }