Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
Offline sgoldyaev  
#1 Posted : Sunday, March 25, 2012 11:06:44 PM(UTC)
sgoldyaev

Joined: 3/20/2012(UTC)
Posts: 3

Thanks: 1 times
Hi Benjamin,

Could you tell me how can I find the PhysicBody by UI coordinates. (eg. for drag and drop feature) Is there any analog for Physics.FindRayCast(...) for 2D. (I found Physics.FindRayCast2D and it wasnt helpfull to me in that case)

I know Farseer has World.TestPoint(Vector v) method wich return fixture in specified coordinate then I could try your code in FindBodyByFixture. But I believe you know the better approach for that case.



Thanks
Sergey

Edited by user Monday, March 26, 2012 5:37:49 AM(UTC)  | Reason: Not specified

Wanna join the discussion?! Login to your forum accountregister a new account. Or Connect via Facebook Twitter Google

Offline Benjamin  
#2 Posted : Monday, March 26, 2012 11:27:39 AM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Hi Sergey,

You pretty much answered your own question. If you look above the FindBodyByFixture method you see it is called by RayCastImpl2D, which is called by Physics.FindRayCast2D:
http://help.deltaengine....hysics_FindRayCast2D.htm

There is also a unit test showing you how to use FindRayCast2D. You can maybe write a simpler helper method for yourself if all you are interested in is a single point and the 2D physics body to be returned, please post it or fork it so we can implement it as well :) Sadly we have not used 2D Physics much since ZombieParty in 2010.
Code:

		/// <summary>
		/// Tutorial: 2D Physics Tutorial 4: Ray Casting in 2D
		/// Difficulty: Easy
		/// Description: Simple 2d ray cast with a box.
		/// Image: http://DeltaEngine.net/Icons/Physics2DTutorial4.png
		/// </summary>
		[Test, Category("Visual")]
		public static void RayCasting2D()
		{
			Physics.Gravity = new Vector(0f, 0.0981f, 0f);
			// Enable debug drawing
			Physics.DebugEnabled = true;

			// set our ground
			Rectangle groundRect = new Rectangle(0.6f, 0.4f, 0.2f, 0.2f);
			PhysicsBody ground = Physics.CreateRectangle(groundRect.Width,
				groundRect.Height, 1f);
			ground.Position = new Vector(groundRect.Center, 0.0f);
			ground.IsStatic = true;
			ground.Friction = 1.0f;
			ground.DebugColor = Color.Yellow;

			Point rayStart = new Point(0f, 0.5f);
			Point rayEnd = ScreenSpace.DrawArea.TopRight;

			Application.Start(delegate
			{
				// Draw the ray.
				Line.Draw(rayStart, rayEnd, Color.Green);

				// And perform the ray cast.
				PhysicsBody foundObject;
				Point normal;
				float fraction;
				if (Physics.FindRayCast2D(rayStart, rayEnd, out foundObject,
					out normal, out fraction))
				{
					ground.Rotation += 10f * Time.Delta;
				}

				// Update the ray movement.
				rayEnd.Y += 0.1f * Time.Delta;
				if (rayEnd.Y >= ScreenSpace.DrawArea.Bottom)
				{
					rayEnd.Y = ScreenSpace.DrawArea.Top;
				}
			});
		}
Offline sgoldyaev  
#3 Posted : Monday, March 26, 2012 6:35:03 PM(UTC)
sgoldyaev

Joined: 3/20/2012(UTC)
Posts: 3

Thanks: 1 times
Hi Benjamin,

Thanks for your reply, but Physics.FindRayCast2D cannot be used here :). Let me clarify the use case

1. User picks the object by mouse click or gesture
2. Physics.FindRayCast2D cannot be used, since it finds objects wich are *intersected* with the vector from point1 and point2.
3. If I set point1 equals point2 and put it into Physics.FindRayCast2D no objects were found because no intersections between vector and objects here (vector is entirely in object).
4. If I set point1 (for example center of the screen or 0,0) I got undesired objects. Wich is not selected by user.

Here is my understanding of Physics.FindRayCast2D works

1. I had a UIClick handler

Code:

			Input.Commands[Command.UIClick].Add(delegate(CommandTrigger command)
			{
				// Create a ray from the input position (mouse, touch, whatever)
				Ray ray = ScreenSpace.GetRayFromScreenPoint(command.Position);
				// And try to grab the box we hit
				PhysicsBody grabBody;
				Point hitNormal;
				float fraction;
				//if (Physics.FindRayCast(ray, false, out grabBody, out hitNormal, out fraction) && grabBody != null)
				startRay = new Point(0.5f, 0.5f);
				endRay = new Point(command.Position.X, command.Position.Y);
				if (Physics.FindRayCast2D(startRay, endRay, out grabBody, out hitNormal, out fraction) && grabBody != null)
				{
					// Activate that body and push it in the direction we are looking
					grabBody.ApplyLinearImpulse(new Vector(0, -300, 0) * 1f);
					grabBody.DebugColor = Color.Red;					
				}
			});



2. Screenshot with comments to geometry in attach.

How did you handle user clicking in ZombyParties? can you post a little code here, please.

Edited by user Monday, March 26, 2012 7:37:25 PM(UTC)  | Reason: Not specified

sgoldyaev attached the following image(s):
findraycast2d.png (61kb) downloaded 7 time(s).

You cannot view/download attachments. Try to login or register.
Offline sgoldyaev  
#4 Posted : Monday, March 26, 2012 7:42:44 PM(UTC)
sgoldyaev

Joined: 3/20/2012(UTC)
Posts: 3

Thanks: 1 times
I added this code to FarseerPhsics (not committed)
Code:


		public PhysicsBody TestPoint(Point point)
		{
			PhysicsBody foundBody = null;
			var fixture = farseerPhysicsWorld.TestPoint(FarseerDatatypesMapping.Convert(ref point) * ScaleFactor);
			if (fixture != null)
			{
				foundBody = FindBodyByFixture(fixture);
			}
			return foundBody;
		}



than I use it in my code

Code:

... somewhere in UI click handler ...
				//TODO [sgoldyaev]: Benjamin will fix it later.
				var farseer = Physics.Instance as FarseerPhysics;
				grabBody = farseer.TestPoint(command.Position);

				if (grabBody != null)
				{
					// Activate that body and push it in the direction we are looking
					grabBody.ApplyLinearImpulse(new Vector(0, -300, 0) * 1f);
					grabBody.DebugColor = Color.Red;
				}
Offline Benjamin  
#5 Posted : Monday, March 26, 2012 11:28:34 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Yes you are right, as I said I did not use Physics much in the last 1-2 years, so I am a bit rusty. I will add a unit test for v0.9.5 and make sure FindRayCast2D works great for a single point as well. I also noticed some methods can be simplified greatly (currently way too many out parameters are used, which are usually not that interesting).

I just checked the code of ZombieParty, and it looks like most click checks where done without physics since we know the position of each object and its size and only round or rectangular objects where used:

Code:

					if (IsPointInside(Input.Touch.Touches[touchIndex].Position, 0.05f) &&
						Input.Touch.Touches[touchIndex].State == InputState.Pressed)
					{
						touchId = Input.Touch.Touches[touchIndex].Id;
						break;
					}
...

This was then used to do something with the pressed/clicked object (in this case a bubble in the main menu gets a force to jump around).

I would probably do it a bit different today and rely more on the physics implementation. We did also use a custom physics implementation in some games of ZombieParty, e.g. Hockey used a physics engine I wrote in a few hours (does not need much and was about 10 times faster than Farseer).

Edited by user Monday, March 26, 2012 11:34:09 PM(UTC)  | Reason: Not specified

thanks 1 user thanked Benjamin for this useful post.
sgoldyaev on 3/27/2012(UTC)
Rss Feed  Atom Feed
Users browsing this topic
OceanSpiders 2.0
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2018, Yet Another Forum.NET
This page was generated in 0.118 seconds.