void polygon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Vector2 point = new Vector2((float)(e.GetPosition(_parentCanvas).X), (float)(e.GetPosition(_parentCanvas).Y)); _pickedSprite = (sender as PhysicsSprite); _pickedSprite.CaptureMouse(); if (MousePickEnabled) { if (_pickedSprite != null) { _mousePickSpring = ControllerFactory.Instance.CreateFixedLinearSpring(Simulator, _pickedSprite.BodyObject, _pickedSprite.BodyObject.GetLocalPosition(point), point, 10, 5); _lineShowSpring.X1 = point.X; _lineShowSpring.Y1 = point.Y; _lineShowSpring.X2 = point.X; _lineShowSpring.Y2 = point.Y; _lineShowSpring.Visibility = Visibility.Visible; e.Handled = true; } } if (MouseLeftButtonDown != null) { MouseLeftButtonDown(_pickedSprite.Name); } }
public static Vector2 GetOffsetPositionInScreen(PhysicsSprite spr) { Vector2 offset = new Vector2(); offset.X = (float)Canvas.GetLeft(spr); offset.Y = (float)Canvas.GetTop(spr); SysWinF.FrameworkElement parent = spr.Parent as SysWinF.FrameworkElement; while (parent != null) { offset.X += (float)Canvas.GetLeft(parent); offset.Y += (float)Canvas.GetTop(parent); if (parent is PhysicsCanvas) { // we found the top canvas, break here. break; } parent = parent.Parent as SysWinF.FrameworkElement; } return offset; }
private void FingerCollision(PhysicsSprite source, string collidedWith) { Debug.WriteLine(collidedWith); if (collidedWith != "player") return; _touchingPlayer = true; //Debug.WriteLine("touchingPlayer"); target.Stroke = new SolidColorBrush(Colors.Red); target.SetValue(Canvas.TopProperty, _player.Position.Y - (target.Height /2)); target.SetValue(Canvas.LeftProperty, _player.Position.X - (target.Width / 2)); }
private void SetupTarget() { if (Controller == null || !Controller.PhysicsObjects.Keys.Contains(Target)) { return; } _targetElement = Controller.PhysicsObjects[Target]; // try to find a scale transform if (_parentCanvas.RenderTransform != null && _parentCanvas.RenderTransform is TransformGroup) { foreach (Transform trn in (_parentCanvas.RenderTransform as TransformGroup).Children) { if (trn is ScaleTransform) { _scaleTransform = trn as ScaleTransform; } if (trn is TranslateTransform) { _translateTransform = trn as TranslateTransform; } } } if (_parentCanvas.RenderTransform is ScaleTransform) { _scaleTransform = _parentCanvas.RenderTransform as ScaleTransform; } if (_parentCanvas.RenderTransform is TranslateTransform) { _translateTransform = _parentCanvas.RenderTransform as TranslateTransform; } // last ditch effort: if we did not find the transforms we need, then add them in. if (_translateTransform == null) { _translateTransform = new TranslateTransform(); if (_parentCanvas.RenderTransform == null || !(_parentCanvas.RenderTransform is TransformGroup)) { _parentCanvas.RenderTransform = new TransformGroup(); } (_parentCanvas.RenderTransform as TransformGroup).Children.Add(_translateTransform); } if (_scaleTransform == null) { _scaleTransform = new ScaleTransform(); (_parentCanvas.RenderTransform as TransformGroup).Children.Add(_scaleTransform); } }
/// <summary> /// Adds a single XAML element into the Physics simulation. /// </summary> /// <param name="cnvContainer">The container to add items from.</param> public PhysicsSprite AddPhysicsBody(UIElement element, UIElement boundaryElement) { string thisName = element.GetValue(Canvas.NameProperty).ToString(); element.SetValue(Canvas.TagProperty, thisName); // special case: if we are adding a UserControl _AND_ the UserControl contains one or more // Physics Controllers, then we handle that UserControl as a "nested" canvas! if (element is UserControl) { Canvas cnvNestedPhysics = FindPhysicsCanvas(element as UserControl); if (cnvNestedPhysics != null) { EnsureUniqueNames(cnvNestedPhysics); AddPhysicsBodyForCanvas(cnvNestedPhysics); return(null); } } // look to see if we have processed this object before, and if so, // use its point collection instead of recalculating List <Point> points = FindMatchingUIElement(element); string nameKey = (string)element.GetValue(Canvas.NameProperty); PhysicsSprite polygon = new PhysicsSprite(Simulator, _parentCanvas, element, points, DebugMode, (float)FrictionDefault, boundaryElement); polygon.Name = nameKey; if (polygon.OutlinePoints != null) { polygon.Collision += new PhysicsSprite.CollisionHandler(polygon_Collision); _parentCanvas.Children.Add(polygon); PhysicsObjects.Add(polygon.Name, polygon); polygon.Update(); } //if (MousePickEnabled) //{ polygon.MouseLeftButtonDown += new MouseButtonEventHandler(polygon_MouseLeftButtonDown); polygon.MouseLeftButtonUp += new MouseButtonEventHandler(polygon_MouseLeftButtonUp); polygon.MouseMove += new MouseEventHandler(polygon_MouseMove); //} return(polygon); }
public void AddFluidContainer(FluidContainerMain fluidContainerMain) { double x = Convert.ToDouble(fluidContainerMain.VisualElement.GetValue(Canvas.LeftProperty)); double y = Convert.ToDouble(fluidContainerMain.VisualElement.GetValue(Canvas.TopProperty)); float width = (float)fluidContainerMain.VisualElement.ActualWidth; float height = (float)fluidContainerMain.VisualElement.ActualHeight; WaveController waveController = fluidContainerMain.WaveControllerObject; waveController.Position = new Vector2((float)x, (float)y); waveController.Width = width; waveController.Height = height; waveController.NodeCount = fluidContainerMain.NodeCount; waveController.DampingCoefficient = (float)fluidContainerMain.DampingCoefficient; waveController.Frequency = (float)fluidContainerMain.Frequency; waveController.WaveGeneratorMax = (float)fluidContainerMain.WaveGeneratorMax; waveController.WaveGeneratorMin = (float)fluidContainerMain.WaveGeneratorMin; waveController.WaveGeneratorStep = (float)fluidContainerMain.WaveGeneratorStep; waveController.Initialize(); Vector2 vecTopLeft = new Vector2((float)x, (float)y); Vector2 vecBottomRight = new Vector2((float)x + width, (float)y + height); AABB waterAABB = new AABB(vecTopLeft, vecBottomRight); AABBFluidContainer waterContainer = new AABBFluidContainer(waterAABB); FluidDragController fluidDragController = new FluidDragController(); foreach (KeyValuePair <string, PhysicsSprite> item in PhysicsObjects) { PhysicsSprite sprite = item.Value; fluidDragController.AddGeom(sprite.GeometryObject); } fluidDragController.Initialize(waterContainer, (float)fluidContainerMain.FluidDensity, (float)fluidContainerMain.LinearDragCoefficient, (float)fluidContainerMain.RotationalDragCoefficient, new Vector2((float)fluidContainerMain.GravityHorizontal, (float)fluidContainerMain.GravityVertical)); Simulator.Add(fluidDragController); }
void polygon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (_pickedSprite != null) { _pickedSprite.ReleaseMouseCapture(); } if (_mousePickSpring != null && _mousePickSpring.IsDisposed == false) { _mousePickSpring.Dispose(); _mousePickSpring = null; _lineShowSpring.Visibility = Visibility.Collapsed; e.Handled = true; } if (MouseLeftButtonUp != null && _pickedSprite != null) { MouseLeftButtonUp(_pickedSprite.Name); } _pickedSprite = null; }
/// <summary> /// Validates a <see cref="PhysicsSprite"/>. /// </summary> /// <param name="physicSprite">The physic sprite.</param> static void ValidatePhysicSprite(PhysicsSprite physicSprite) { Check.NotNull(physicSprite, "physicSprite"); if (physicSprite.BodyObject == null) throw new InvalidOperationException("BodyObject is not initialized"); }
void CompositionTarget_Rendering(object sender, EventArgs e) { if (!Enabled) { return; } double currentTargetXOffset = 0, currentTargetYOffset = 0; double currentScreenCenterX, currentScreenCenterY; currentScreenCenterX = (_parentCanvas.ActualWidth / 2) / _scaleTransform.ScaleX; currentScreenCenterY = (_parentCanvas.ActualHeight / 2) / _scaleTransform.ScaleY; if (Target != string.Empty && ScrollEnabled) { if (!Controller.PhysicsObjects.Keys.Contains(Target)) { return; } _targetElement = Controller.PhysicsObjects[Target]; currentTargetXOffset = _targetElement.BodyObject.Position.X; currentTargetYOffset = _targetElement.BodyObject.Position.Y; if (TargetOverrideX != 0) { currentTargetXOffset = TargetOverrideX; // use the override X instead of the Target X } else { currentTargetXOffset += _targetElement.Width / 2; // use the center position of the Target } if (TargetOverrideY != 0) { currentTargetYOffset = TargetOverrideY; // use the override Y instead of the Target Y } else { currentTargetYOffset += _targetElement.Height / 2; // use the center position of the Target } if (ScrollSpeed == 0) { // just scroll directly to target _translateTransform.X = currentScreenCenterX - (_relativeTranslateX + currentTargetXOffset); _translateTransform.Y = currentScreenCenterY - (_relativeTranslateY + currentTargetYOffset); } else { // do a gradual scroll double diffX = (_relativeTranslateX + currentTargetXOffset) - currentScreenCenterX; double diffY = (_relativeTranslateY + currentTargetYOffset) - currentScreenCenterY; if (Math.Abs(diffX) > CenteringThreshold) { if (diffX > 0) { _relativeTranslateX -= ScrollSpeed; } else { _relativeTranslateX += ScrollSpeed; } } if (Math.Abs(diffY) > CenteringThreshold) { if (diffY > 0) { _relativeTranslateY -= ScrollSpeed; } else { _relativeTranslateY += ScrollSpeed; } } if (ScrollX) { _translateTransform.X = (_relativeTranslateX); } if (ScrollY) { _translateTransform.Y = (_relativeTranslateY); } } // Now do the Zoom if (ZoomEnabled) { double targetZoom = ZoomPercentage / 100; double currentZoom = _scaleTransform.ScaleX; // allow a threshold of zoomspeed if (ZoomSpeed == 0) { // just zoom directly to target _scaleTransform.ScaleX = targetZoom; _scaleTransform.ScaleY = targetZoom; } else if (Math.Abs(currentZoom - targetZoom) > ZoomSpeed) { // zooming out if (currentZoom > targetZoom) { _scaleTransform.ScaleX -= ZoomSpeed; _scaleTransform.ScaleY -= ZoomSpeed; if (_scaleTransform.ScaleX < -1) { _scaleTransform.ScaleX = -1; _scaleTransform.ScaleY = -1; } } else { _scaleTransform.ScaleX += ZoomSpeed; _scaleTransform.ScaleY += ZoomSpeed; } } } } // update any parallax layers foreach (ParallaxLayer layer in ParallaxLayers) { layer.Z = layer.Z; double x = Convert.ToDouble(layer.CanvasContainer.GetValue(Canvas.LeftProperty)); double y = Convert.ToDouble(layer.CanvasContainer.GetValue(Canvas.TopProperty)); double zChange = 1 / Math.Abs(layer.Z); double newX, newY; newX = -_translateTransform.X; newY = -_translateTransform.Y; // compensate for camera newX = newX + (zChange * _translateTransform.X); newY = newY + (zChange * _translateTransform.Y); layer.TransformPosition.X = newX; layer.TransformPosition.Y = newY; } }
PhysicsSprite CreateSprite(string name) { var sprite = new PhysicsSprite() { IsStatic = true, Background = ModernBlueBrush, Name = name, }; UIHelper.ExecuteOnLoad(sprite, (x) => { if (x.BodyObject != null) { x.BodyObject.CollisionCategories = FarseerPhysics.Dynamics.Category.All; } }); this.Children.Add(sprite); return sprite; }
private void PhysicObject_MousePickStarted(PhysicsSprite source, Microsoft.Xna.Framework.Vector2 ptMoveStart) { // Show the contact card. this.ContactCard.Visibility = Visibility.Visible; //Canvas.SetLeft(this, ptMoveStart.X); //Canvas.SetTop(this, ptMoveStart.Y); }
public PhysicsSprite AddPhysicsBody(PhysicsObjectMain physObject) { FrameworkElement element = physObject.VisualElement; string thisName = element.GetValue(Canvas.NameProperty).ToString(); element.SetValue(Canvas.TagProperty, thisName); // special case: if we are adding a UserControl _AND_ the UserControl contains one or more // Physics Controllers, then we handle that UserControl as a "nested" canvas! if (BoundaryHelper.IsInsideNestedUsercontrol(element)) //element is UserControl) { UserControl ucParent = BoundaryHelper.GetParentUserControl(element); Canvas cnvNestedPhysics = FindPhysicsCanvas(ucParent); if (cnvNestedPhysics != null) { EnsureUniqueNames(cnvNestedPhysics); if (element is UserControl) { AddPhysicsBodyForCanvasWithBehaviors(cnvNestedPhysics); return(null); } } } // look to see if we have processed this object before, and if so, // use its point collection instead of recalculating List <Point> points = FindMatchingUIElement(element); string nameKey = (string)element.GetValue(Canvas.NameProperty); FrameworkElement boundaryElement = null; if (physObject.BoundaryElement != null && physObject.BoundaryElement != string.Empty) { boundaryElement = element.FindName(physObject.BoundaryElement) as FrameworkElement; } if (nameKey == string.Empty) { nameKey = GetUniqueSpriteName(); element.Name = nameKey; } PhysicsSprite sprite = new PhysicsSprite(Simulator, _parentCanvas, element, points, DebugMode, (float)FrictionDefault, boundaryElement); sprite.Name = nameKey; if (sprite.OutlinePoints != null) { sprite.Collision += new PhysicsSprite.CollisionHandler(polygon_Collision); _parentCanvas.Children.Add(sprite); PhysicsObjects.Add(sprite.Name, sprite); sprite.Update(); } sprite.MouseLeftButtonDown += new MouseButtonEventHandler(polygon_MouseLeftButtonDown); sprite.MouseLeftButtonUp += new MouseButtonEventHandler(polygon_MouseLeftButtonUp); sprite.MouseMove += new MouseEventHandler(polygon_MouseMove); sprite.GeometryObject.CollisionGroup = physObject.CollisionGroup; sprite.BodyObject.IsStatic = physObject.IsStatic; if (physObject.RestitutionCoefficient != 0) { sprite.GeometryObject.RestitutionCoefficient = (float)physObject.RestitutionCoefficient; } if (physObject.FrictionCoefficient != 0) { sprite.GeometryObject.FrictionCoefficient = (float)physObject.FrictionCoefficient; } if (physObject.MomentOfIntertia != 0) { sprite.BodyObject.MomentOfInertia = (float)physObject.MomentOfIntertia; } if (physObject.Mass != 0) { sprite.BodyObject.Mass = (float)physObject.Mass; } return(sprite); }
public static string EnsureUniqueName(Canvas cnv, PhysicsSprite sprToAdd, string name) { int suffix = 1; string thisName = name; Object possibleMatch = cnv.FindName(name); while (possibleMatch != null && possibleMatch != sprToAdd) { name = thisName + "_" + suffix.ToString(); suffix++; possibleMatch = cnv.FindName(name); } return name; }
private void RemoveBorders() { foreach (var border in _borders) { this.DeletePhysicsObject(border.Name); } _ground = null; _leftBorder = null; _topBorder = null; _rightBorder = null; _borders.Clear(); }
/// <summary> /// Adds a single Physics Sprite into the Physics simulation. /// </summary> /// <param name="cnvContainer">The container to add items from.</param> public PhysicsSprite AddPhysicsSprite(PhysicsSprite element, bool enablePhysics) { if (enablePhysics) { string thisName = element.GetValue(Canvas.NameProperty).ToString(); element.SetValue(Canvas.TagProperty, thisName); // save original name in tag if ((element.Parent as Panel).Children.IndexOf(element) < 0) throw new Exception("Could not find element " + thisName + " in the parent"); (element.Parent as Panel).Children.Remove(element); thisName = PhysicsUtilities.EnsureUniqueName(this, element, thisName); // get a unique name in the game canvas element.Name = thisName; //PhysicsUtilities.DebugVisualTree(this, 1); this.Children.Add(element); PhysicsObjects.Add(thisName, element); element.Update(); element.Collision += new PhysicsSprite.CollisionHandler(polygon_Collision); } if (MousePickEnabled) { element.MousePickEnabled = true; } return element; }
private void PhysicsControllerInitialized(object source) { _player = _physicsController.PhysicsObjects["player"]; _physicsController.TimerLoop += PhysicsControllerTimerLoop; //var branch = _physicsController.PhysicsObjects["branch"]; //branch.DoubleTap += BranchDoubleTap; }
void polygon_Collision(PhysicsSprite source, string spriteCollided, Contact contact) { // for now we just STORE the collision because we // cannot destroy or inactivate things during a FP3 Step operation! if (Collision != null && this.PhysicsObjects.Keys.Contains(spriteCollided)) { PhysicsSprite sprite2 = this.PhysicsObjects[spriteCollided]; CollisionStore.AddCollision(source, sprite2, contact); if (PhysicsObjects.Keys.Contains(source.Name) == false) throw new Exception("sprite " + source.Name + " is not in the list of sprites"); if (PhysicsObjects.Keys.Contains(sprite2.Name) == false) throw new Exception("sprite " + sprite2.Name + " is not in the list of sprites"); } }
void SetSize(PhysicsSprite sprite, double width, double height) { if (sprite == null) return; sprite.Width = width; sprite.Height = height; }
void SetPosition(PhysicsSprite sprite, double x, double y) { if (sprite == null) return; //Canvas.SetLeft(sprite, x); //Canvas.SetTop(sprite, y); //double offsetX = (x + (sprite.Width / 2d)); //double offsetY = (y + (sprite.Height / 2d)); sprite.SetPosition(x, y); }
public CollisionInstance(PhysicsSprite sprite1, PhysicsSprite sprite2, Contact contact) { Sprite1 = sprite1; Sprite2 = sprite2; Contact = contact; }
/// <summary> /// Gets a list of all joint-related sprites, given a sprite. /// </summary> public static void GetAllSpritesRelatedByJoints(PhysicsCanvas cnvGame, PhysicsSprite spr, List<PhysicsSprite> sprJoined) { // add in the given sprite if (sprJoined.IndexOf(spr) < 0) sprJoined.Add(spr); foreach (Joint joint in cnvGame.Simulator.JointList) { if (joint.BodyA == spr.BodyObject || joint.BodyB == spr.BodyObject) { var spritesJoined = from s in cnvGame.PhysicsObjects.Values where s.BodyObject == joint.BodyA || s.BodyObject == joint.BodyB && (joint.BodyA.Enabled == true && joint.BodyB.Enabled == true) select s; foreach (PhysicsSprite sprFound in spritesJoined) { if (sprJoined.IndexOf(sprFound) < 0) { GetAllSpritesRelatedByJoints(cnvGame, sprFound, sprJoined); } } } } }
public static void AddCollision(PhysicsSprite sprite1, PhysicsSprite sprite2, Contact contact) { Collisions.Add(new CollisionInstance(sprite1, sprite2, contact)); }
private void InitializeBorders() { // Set category to border elements //Action<PhysicsSprite> setCategoryToAll = new Action<PhysicsSprite>((sprite) => //{ // sprite.BodyObject.CollisionCategories = FarseerPhysics.Dynamics.Category.All; //}); // Add physic borders _ground = CreateSprite("PART_Ground"); _borders.Add(_ground); //this.Children.Add(_ground); //UIHelper.ExecuteOnLoad(_ground, setCategoryToAll); _leftBorder = CreateSprite("PART_LeftBorder"); _borders.Add(_leftBorder); //this.Children.Add(_leftBorder); //UIHelper.ExecuteOnLoad(_leftBorder, setCategoryToAll); _rightBorder = CreateSprite("PART_RightBorder"); _borders.Add(_rightBorder); //this.Children.Add(_rightBorder); //UIHelper.ExecuteOnLoad(_rightBorder, setCategoryToAll); _topBorder = CreateSprite("PART_TopBorder"); _borders.Add(_topBorder); //this.Children.Add(_topBorder); //UIHelper.ExecuteOnLoad(_topBorder, setCategoryToAll); }
/// <summary> /// Create a path object based on a list of vertices - used when creating geometry /// </summary> public static UIShapes.Shape CreatePathFromVertices(Body body, PhysicsSprite element, WinUI.Color colorFill) { List<Fixture> vertices = body.FixtureList; // is this an ellipse? if (vertices[0].Shape is CircleShape) { CircleShape cs = vertices[0].Shape as CircleShape; UIShapes.Ellipse el = new UIShapes.Ellipse(); Vector2 screenSize = PhysicsCanvas.BoundaryHelper.WorldSizeToScreenSize(new Vector2(cs.Radius * 2, cs.Radius * 2)); el.Width = screenSize.X; el.Height = screenSize.Y; el.Stroke = new SysWinMedia.SolidColorBrush(new WinUI.Color() { A = 255, R = 76, G = 108, B = 76 }); el.StrokeThickness = 4; el.StrokeStartLineCap = SysWinMedia.PenLineCap.Round; el.Fill = new SysWinMedia.SolidColorBrush(colorFill); return el; } else { UIShapes.Path path = new UIShapes.Path(); path.Stroke = new SysWinMedia.SolidColorBrush(new WinUI.Color() { A = 255, R = 76, G = 108, B = 76 }); path.StrokeThickness = 4; path.StrokeStartLineCap = SysWinMedia.PenLineCap.Round; path.Fill = new SysWinMedia.SolidColorBrush(colorFill); SysWinMedia.PathGeometry pathGeom = new SysWinMedia.PathGeometry(); SysWinMedia.PathFigureCollection figures = new SysWinMedia.PathFigureCollection(); pathGeom.Figures = figures; double halfWidth = element.Width / 2d; double halfHeight = element.Height / 2d; if (halfWidth == 0) halfWidth = element.ActualWidth / 2d; if (halfHeight == 0) halfHeight = element.ActualHeight / 2d; foreach (Fixture f in vertices) { if (f.Shape is PolygonShape) { SysWinMedia.PathFigure figure = new SysWinMedia.PathFigure(); PolygonShape p = f.Shape as PolygonShape; // first vertex, create the startpoint Vector2 ptStart = new Vector2((float)p.Vertices[0].X, (float)p.Vertices[0].Y); ptStart = PhysicsCanvas.BoundaryHelper.WorldSizeToScreenSize(ptStart); ptStart.X += (float)(halfWidth); ptStart.Y += (float)(halfHeight); figure.StartPoint = new SysWin.Point(ptStart.X, ptStart.Y); figure.Segments = new SysWinMedia.PathSegmentCollection(); pathGeom.Figures.Add(figure); for (int i = 1; i < p.Vertices.Count; i++) { SysWinMedia.LineSegment line = new SysWinMedia.LineSegment(); Vector2 pt = new Vector2((float)p.Vertices[i].X, (float)p.Vertices[i].Y); pt = PhysicsCanvas.BoundaryHelper.WorldSizeToScreenSize(pt); pt.X += (float)(halfWidth); pt.Y += (float)(halfHeight); line.Point = new SysWin.Point(pt.X, pt.Y); ; figure.Segments.Add(line); } } } path.Data = pathGeom; return path; } }
public void InitializeObjects() { _initialized = true; if (AutoAddCanvasObjects == true) { // Add _ALL_ named elements in the canvas as Physics objects. AddPhysicsBodyForCanvas(_parentCanvas); } if (Initialized != null) { Initialized(this); } // add a pick spring if selected by user _lineShowSpring = new Line(); _lineShowSpring.Stroke = new SolidColorBrush(Colors.Black); _lineShowSpring.Visibility = Visibility.Collapsed; _parentCanvas.Children.Add(_lineShowSpring); #if (DEBUG) // echo out the collection of points. This can be useful to set the PointCollection property // on the PhysicsController to save startup time. StringBuilder sb = new StringBuilder(); sb.Append("public static void ReadBoundaryCache(PhysicsController physicsController)\n"); sb.Append("{\n"); sb.Append(" physicsController.PointListCollection = new System.Collections.Generic.List<PointObject>();\n"); foreach (KeyValuePair <string, PhysicsSprite> item in PhysicsObjects) { PhysicsSprite physObject = item.Value; sb.Append(" physicsController.PointListCollection.Add(new PointObject(\""); sb.Append(physObject.OriginalElementName); sb.Append("\", new List<Point> { "); foreach (Point pt in physObject.OutlinePoints) { sb.Append("new Point("); sb.Append(pt.X); sb.Append(","); sb.Append(pt.Y); sb.Append(")"); if (physObject.OutlinePoints.IndexOf(pt) < physObject.OutlinePoints.Count() - 1) { sb.Append(", "); } } sb.Append("}));\n"); } sb.Append("}\n"); System.Diagnostics.Debug.WriteLine(sb.ToString()); #endif StartGameLoopTimer(); }
public List<Shape> CreateShapesFromElement(World simulator, PhysicsSprite entity, PhysicsSprite.ShapeTypes shapeType) { List<Shape> shapeDefs = new List<Shape>(); switch (shapeType) { case PhysicsSprite.ShapeTypes.Ellipse: xna.Vector2 worldRadius = ScreenSizeToWorldSize(new SysWin.Size(entity.Width / 2, entity.Width / 2)); CircleShape circleDef = new CircleShape(worldRadius.Y, 0.1f); shapeDefs.Add(circleDef); break; case PhysicsSprite.ShapeTypes.Rectangle: PolygonShape polygonRect = new PolygonShape(0.1f); SysWin.Rect rect = new SysWin.Rect(0, 0, entity.Width, entity.Height); xna.Vector2 pos = new xna.Vector2(0F, 0F); // does the box have a rotation? double angle = 0; if (entity.RenderTransform is RotateTransform) { angle = (entity.RenderTransform as RotateTransform).Angle; } else if (entity.RenderTransform is CompositeTransform) { angle = (entity.RenderTransform as CompositeTransform).Rotation; } float radAngle = (float)(Math.PI * angle / 180.0); xna.Vector2 worldSize = ScreenSizeToWorldSize(new SysWin.Size(rect.Width / 2, rect.Height / 2)); //polygonRect.SetAsBox(worldSize.X, worldSize.Y, new xna.Vector2(0,0), radAngle); polygonRect.SetAsBox(worldSize.X, worldSize.Y, new xna.Vector2(0, 0), 0); shapeDefs.Add(polygonRect); break; default: // Polygon via Path Vertices vertices = new Vertices(); UIShapes.Path pathBoundary = (entity as Canvas).Children[0] as UIShapes.Path; if (pathBoundary == null) { throw new Exception("The PhysicsSprite " + entity.Name + " has a Polygon ShapeType, but the first element in the PhysicsSprite must be a Path element that depicts the shape. Note you can set the Visibility of this Path to Collapsed if you do not want it shown in the Sprite."); } else { PathGeometry pathGeom = pathBoundary.Data as PathGeometry; if (pathGeom == null) { throw new Exception("The PhysicsSprite " + entity.Name + " contains a Path as the first element, but that Path has no PathGeometry defined."); } else { #if WINDOWS_PHONE || SILVERLIGHT PathConverter.StringToPathGeometryConverter cnv = new PathConverter.StringToPathGeometryConverter(); string geom = pathGeom.ToString(); if (geom != string.Empty) { pathGeom = cnv.Convert(geom); } #endif foreach (PathFigure figure in pathGeom.Figures) { SysWin.Point ptStart = figure.StartPoint; // adjust the position for origin at center ptStart.X = (ptStart.X - ((float)entity.Width / 2)); ptStart.Y = (ptStart.Y - ((float)entity.Height / 2)); // adjust the position for Canvas Left, Top ptStart.X = ptStart.X + Canvas.GetLeft(pathBoundary); ptStart.Y = ptStart.Y + Canvas.GetTop(pathBoundary); vertices.Add(ScreenSizeToWorldSize(ptStart)); foreach (PathSegment segment in figure.Segments) { if (segment is LineSegment) { LineSegment lineSegment = segment as LineSegment; SysWin.Point ptNext = lineSegment.Point; // adjust the position for origin at center ptNext.X = (ptNext.X - ((float)entity.Width / 2)); ptNext.Y = (ptNext.Y - ((float)entity.Height / 2)); // adjust the position for Canvas Left, Top ptNext.X = ptNext.X + Canvas.GetLeft(pathBoundary); ptNext.Y = ptNext.Y + Canvas.GetTop(pathBoundary); vertices.Add(ScreenSizeToWorldSize(ptNext)); } else if (segment is BezierSegment) { // HACK: This DOES NOT take into account a real Bezier Curve!! BezierSegment bezSegment = segment as BezierSegment; SysWin.Point ptNext = bezSegment.Point3; // adjust the position for origin at center ptNext.X = (ptNext.X + ((float)entity.Width / 2)); ptNext.Y = (ptNext.Y + ((float)entity.Height / 2)); // adjust the position for Canvas Left, Top ptNext.X = ptNext.X + Canvas.GetLeft(pathBoundary); ptNext.Y = ptNext.Y + Canvas.GetTop(pathBoundary); vertices.Add(ScreenSizeToWorldSize(bezSegment.Point2)); } } } List<Vertices> verticesDecomposed; // DEMO: (2): We need CONVEX shapes, but Decomposers are provided in Farseer. switch (DecomposerType) { case DecomposerTypes.CDT: verticesDecomposed = CDTDecomposer.ConvexPartition(vertices); break; case DecomposerTypes.Earclip: verticesDecomposed = EarclipDecomposer.ConvexPartition(vertices); break; case DecomposerTypes.Flipcode: verticesDecomposed = FlipcodeDecomposer.ConvexPartition(vertices); break; case DecomposerTypes.Melkman: verticesDecomposed = new List<Vertices>(); verticesDecomposed.Add(Melkman.GetConvexHull(vertices)); break; case DecomposerTypes.Giftwrap: verticesDecomposed = new List<Vertices>(); verticesDecomposed.Add(GiftWrap.GetConvexHull(vertices)); break; default: verticesDecomposed = BayazitDecomposer.ConvexPartition(vertices); break; } foreach (Vertices vertexDecomposed in verticesDecomposed) { if (vertexDecomposed.Count < 3) { //throw new Exception("The PhysicsSprite " + entity.Name + " contains a Path as the first element, but one of the Decomposed Polygons has " + vertexDecomposed.Count + " vertices. You must have at least 3 vertices for a polygon boundary."); } else { if (vertexDecomposed.Count > FarseerPhysics.Settings.MaxPolygonVertices) { // trim down the # of vertices double skipNum = (vertexDecomposed.Count - FarseerPhysics.Settings.MaxPolygonVertices); skipNum = Math.Round(Convert.ToDouble(vertexDecomposed.Count) / skipNum); for (int i = vertexDecomposed.Count - 1; i >= 0; i -= Convert.ToInt32(skipNum)) { vertexDecomposed.Remove(vertexDecomposed[i]); } } PolygonShape polygonDef = new PolygonShape(0.1f); polygonDef.Set(vertexDecomposed); shapeDefs.Add(polygonDef); } } } } break; } return shapeDefs; }
private void PhysicObject_MousePickCompleted(PhysicsSprite source, Microsoft.Xna.Framework.Vector2 ptMoveStart) { // Hide the contact card. HideContactCard(); }