/// <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); } } }
/// <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); } }
/// <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); } } }
/// <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); }