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

Notification

Icon
Error

Options
Go to last post Go to first unread
Offline mc-kay  
#1 Posted : Saturday, November 26, 2011 4:19:06 PM(UTC)
mc-kay

Medals: Admin

Joined: 8/24/2011(UTC)
Posts: 138
Location: Hannover

Thanks: 1 times
Was thanked: 12 time(s) in 7 post(s)
I'am currently developing a small game where you have the ability to shot a projectile with a specific power and angle.
This works every things fine for me to last days until now.
I added a Font.Default.DrawTopLeft() to view some values and executed the code - and then my physics was broken.
Whenever I shoot the projectile moves a different distance....sometimes the shot is very long (outside the window), then the projectile is hitting the ground immediately.
First I thought I accidentally changed some lines too and reverted all my changes in Visual Studio until I opened the solution (where its definitely working) but still the same problem.
Then I created a new project to test only the physic with this code:
Code:
using Delta.Engine;
using Delta.Engine.Dynamic;
using Delta.Utilities.Datatypes;
using Delta.InputSystem;
using Delta.PhysicsEngines;

namespace SimpleGame1
{
    class Game : DynamicModule
    {
        public Game()
            : base("Simple Game", typeof(Application))
        {
            Physics.Gravity = new Vector(0f, 1f, 0f);
            Physics.DebugEnabled = true;
            PhysicsBody projectile = Physics.CreateRectangle(0.06f, 0.01f, 1f);
            projectile.Position2D = new Point(0.205f, 0.66f);
            projectile.Friction = 1f;
            projectile.DebugColor = Color.Red;
            projectile.IsActive = false;

            Rectangle groundRect = new Rectangle(0f, 0.74f, 1f, 0.01f);
            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;

            Input.Commands[Command.UIClick].Add(delegate(CommandTrigger input)
            {
                projectile.Rotation = 0f;
                projectile.Position2D = new Point(0.205f, 0.66f);
                projectile.AngularVelocity2D = 0f;
                projectile.LinearVelocity = new Vector(new Point(665f, -746f), 0f);
                projectile.IsActive = true;
            });
        }

        public override void Run()
        {
        }
    }
}


Same problem.
Finally I used another PC to test it but with the same result.
I still checked all the "projectile" and "Physics" properties if there any changes from shot to shot but everything look right.
What the hell is wrong with my code?

Edited by user Saturday, November 26, 2011 5:29:36 PM(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 : Saturday, November 26, 2011 11:59:58 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)
That is a hard bug to track down. I tried creating new instances of the projectile and setting every single value both on the PhysicsBody and then directly on the FarseerBody with no effect. Then I went ahead and hacked setters for all values of the Farseer Body.cs class, which still did not result in any improvements. Outputing the values was also always the same after setting them (no extra inertia, force, or velocity, it is always the same).

Only after outputting the LinearVelocity every frame with (false means no duplicates will be skipped like normally, makes logging really slow, but precise):
Code:

				Log.Info("LinearVelocity=" + projectile.LinearVelocity, false);


This is what happens for the first shoot (with my very fast PC):
Code:

01.543 LinearVelocity=(665000.0000, -746000.0000, 0.0000)
01.543 AngularVelocity=(0.0000, 0.0000, 0.0000)
01.543 Restitution=0
01.550 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:9027.744 Y:-10127.36}, Time.Delta=0.0008111016
01.550 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:1640.852 Y:-1840.567}, Time.Delta=0.02212895
01.551 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:60.54733 Y:-67.10026}, Time.Delta=0.0002217467


The time in the second frame after shooting is MUCH higher (100 times more than in all other frames). After that the linear velocity is reduced a lot!

When shooting another projectile this happens:
Code:

02.545 LinearVelocity=(665000.0000, -746000.0000, 0.0000)
02.545 AngularVelocity=(0.0000, 0.0000, 0.0000)
02.545 Restitution=0
02.546 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:9951.513 Y:-11163.65}, Time.Delta=0.00029701
02.546 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:4480.852 Y:-5026.505}, Time.Delta=0.002524429
02.547 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:527.3392 Y:-591.2585}, Time.Delta=0.0001648328
02.547 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:527.3392 Y:-591.0936}, Time.Delta=0.0001480385
02.547 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:527.3392 Y:-590.9456}, Time.Delta=0.0001396413
02.547 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:527.3392 Y:-590.806}, Time.Delta=0.0001399524


The second frame after the shoot is still slower, but not 100 times, now it is "only" 10 times slower. The LinearVelocity is around 500 after that and stays in this range for a long while (x for almost 2 seconds until it hits the ground, which is much different from the 50-60 from the first shot).

And finally shooting a third time or any more shots always results in this output:
Code:

04.104 LinearVelocity=(665000.0000, -746000.0000, 0.0000)
04.104 AngularVelocity=(0.0000, 0.0000, 0.0000)
04.104 Restitution=0
04.104 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:8970.965 Y:-10063.67}, Time.Delta=0.0002540913
04.104 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:5237.712 Y:-5875.54}, Time.Delta=0.0002251678
04.104 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:5237.712 Y:-5875.314}, Time.Delta=0.0001464835
04.104 GetDebugInfo=FarseerBody: Inertia=185000, Mass=1, LinearVelocity={X:5237.712 Y:-5875.168}, Time.Delta=0.0001436844


Now it makes not much of a difference (maybe farseer is internall optimized to handle this case now quicker) and the LinearVelocity is always way too high. This is what I noticed when looking at your code anyway, using that high values is usually no good, it was very strange that it was so slow in the first 1-2 shots.

I am no expert in Farseer and I have never worked with it. Maybe our expert Amer can sheet some light on it. I think the main problem here (which we need to fix from the engine side in one of the next releases) is to update the physics way too often (as much as you have fps). 30 updates/second should be enough. We already have a setting for this on mobile platforms, but we also need to test and use it on PC to avoid those problems.

What you can do now (except for not using farseer) is one of several things:

The easiest option is to just limit your application a certain framerate, you don't need to update physics thousands of times per frame. If you just set
Code:

			Settings.Extra.LimitFramerateNumber = 60;

At the beginning of your application (before firing any projectiles) the problem goes almost way (still there, but you won't notice, now your Time.Deltas are not 0.000014 anymore, but 1/60 = 0.016 (which is 1000 times higher).

Obviously your application is now limited to 60fps. If you want to use different times for rendering and physics just change the code in FarseerPhysics.UpdateSimulation (this code is for 30 physics updates per second):
Code:

		protected override void UpdateSimulation(float timeStep)
		{
			// Update profiling update time also
			profilingInfo.UpdateTime = farseerPhysicsWorld.UpdateTime;

			if (IsPaused == false)
			{
				//orginial code: farseerPhysicsWorld.Step(timeStep);
				if (Delta.Engine.Time.CheckEvery(1.0f / 30.0f))
				{
					farseerPhysicsWorld.Step(1.0f/30.0f);
				}
			}
		}

If you change Delta.PhysicsEngines.FarseerPhysics, make sure to change your assembly reference to a project reference in your project to use your updated code.

Hope that helps to make your app and physics a little more predicable.
Offline mc-kay  
#3 Posted : Monday, November 28, 2011 10:34:43 PM(UTC)
mc-kay

Medals: Admin

Joined: 8/24/2011(UTC)
Posts: 138
Location: Hannover

Thanks: 1 times
Was thanked: 12 time(s) in 7 post(s)
Hmm you're right it have something to do with a too high LinearVelocity value.
However it seems to work now but I have no idea why.
I changed my force multiplier to a lower value and then back to original.
The test application is still broken but my main application is now working again Confused Confused Confused
I only have the problem that the first shot have no much power but I bypass this with a fake shot when the game starts up.
Changing the "LimitFramerateNumber" and updating the "UpdateSimulation()" doesn't work for me because everything is now super slow and the projectile seems to have no power and "lagging" (hitting the ground after a few centimeter (should fly outside the visible screen)).
Offline Benjamin  
#4 Posted : Monday, November 28, 2011 10:46:45 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)
Originally Posted by: Hendrik Go to Quoted Post
Changing the "LimitFramerateNumber" and updating the "UpdateSimulation()" doesn't work for me because everything is now super slow and the projectile seems to have no power and "lagging" (hitting the ground after a few centimeter (should fly outside the visible screen)).


That sounds really bad. You must be doing something wrong if it only works in high fps scenarios. You cannot expect more than 30 or 60 fps on mobile devices or consoles and a game should run the same way if it has only 15fps, 30, 60 or 6000fps.

You are also saying "LimitFramerateNumber" AND "UpdateSimulation", maybe you are doing too much? Only one of those options should be used. I suggest only trying out LimitFramerateNumber, which helps testing a lot (you can set it to 5 or even 1 for extreme scenarios und see what happens if you only update once per second).
Offline Amer  
#5 Posted : Tuesday, November 29, 2011 9:37:00 AM(UTC)
Amer

Joined: 8/21/2011(UTC)
Posts: 28

Thanks: 1 times
Hi,
I think the problem is probably related on Delta engine quadric space to farseer space conversion, during setting of LinearVelocity the value is not mulitplied or divided by 1000.0f, so probably thats why your linear velocity (angular too) is so high.

So you can try to perform conversion on your side and maybe that can be reported on Farseer implementation into Delta engine later.

Hope this helps,

Amer
Offline Benjamin  
#6 Posted : Tuesday, November 29, 2011 12:29: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)
Good to know, I reported a bug so we can fix and test that later.

Even with that bug fixed, I still think Farseer gets strange in high fps scenarios (>10000fps) and will result in a different simulation than just having a fixed 30fps or 60fps. We will fix that bug and test if limiting all physics (maybe with a flag) helps sorting out most problems.
Offline Amer  
#7 Posted : Tuesday, November 29, 2011 12:46:52 PM(UTC)
Amer

Joined: 8/21/2011(UTC)
Posts: 28

Thanks: 1 times
Correct me if i'm wrong, but at the moment physics simulation is limited by framerate, probably something like this would provide better result:

Code:
private const float timestep = 1.0f / 60.0f;

// Update Physics
while (dtime > 0.0f)
{
	float dt = dtime >= timestep ? timestep : dtime;
	farseerPhysicsWorld.Step(dt);
	dtime -= dt;
}


This should limit world step for fixed 60 frame per second step.
Hope this helps.
Offline Benjamin  
#8 Posted : Tuesday, November 29, 2011 12:53:46 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, that is exactly what should be done, but some testing is required to make much it works well with 30fps or 60fps and we need to make this customizable for the user, but otherwise it will be like the code you posted. Maybe we could test first if physics is much different when doing 5 updates with 1/60 seconds or just doing one update 5/60 (it will be different, but the question is how much).
Offline tidalWave  
#9 Posted : Tuesday, December 6, 2011 1:50:10 AM(UTC)
tidalWave

Joined: 11/29/2011(UTC)
Posts: 15
Location: Ohio, USA

Farseer should definitely be run with a fixed time step. Using a variable time step with large velocity's causes problems do to floating point rounding errors. To get the best results you need to run Farseer in with a fixed time step like Glenn Fiedler uses in his blog article's on physics. Then interpolate the result to achieve a smooth result at any frame rate, even when the physics frame rate drops to < 20.

PS: I am one of the developers for Farseer and with XNA possibly becoming discontinued I think Delta Engine is going to take it's place in my arsenal. C# is by far the best prototyping language and with an engine like this there is no reason to drop C# for game dev! Keep up the good work!
Offline Benjamin  
#10 Posted : Tuesday, December 6, 2011 2:01:17 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)
Wow, nice of you to drop by. Great to see one of the developers of Farseer Cool

Yes the article is really good, thanks for the link. As Amer was already posting we had a few similar solutions in previous games (e.g. ZombieParty ran with 30fps physics and interpolated between steps, which really ran great on iOS with hundreds of objects at 60fps on iPad 1).

Btw: I don't think XNA is going anywhere, it is here to stay. I was XNA MVP for 4 years and XNA has not changed much. This is good for people using it (Students, WP7, Xbox 360 Arcade, etc.), but at the same rate it does not help people XNA is not targeting (and probably never will): Professional PC (and Console) Game Developers. For the Delta Engine it does not matter, we like XNA as much as SlimDX or SharpDX or OpenTK, all runs great.
Offline Wanton  
#11 Posted : Wednesday, December 21, 2011 1:36:36 AM(UTC)
Wanton

Joined: 12/21/2011(UTC)
Posts: 1

Originally Posted by: Benjamin Nitschke (DeltaEngine) Go to Quoted Post
(e.g. ZombieParty ran with 30fps physics and interpolated between steps, which really ran great on iOS with hundreds of objects at 60fps on iPad 1).


I'm planning to do a small mobile game and was wondering how did you implement that frame rate interpolation.
I was planning to implement it like below, but not sure if there is something much better way to implement it?

_delta and this.UpdateFrequency are both double's;

Code:
float amount = (float)(_delta / this.UpdateFrequency);
Vector2 position;
Vector2.Lerp(ref this.PreviousPosition, ref this.Position, amount, out position);


Update loop looks something like this..

Code:
_delta += current;
while (_delta >= this.UpdateFrequency)
{
// Update stuff here
_delta -= this.UpdateFrequency;
}
Offline Benjamin  
#12 Posted : Wednesday, December 21, 2011 1:49:57 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)
Yes, basically just use Time.Delta to figure out how much time has passed and advance objects this far. If you don't worry about lag you could also use a simplified formula (lastPosition+targetPosition)/2, which makes everything more smooth. You could either update targetPosition each frame too (predicting where it should go) or just leave it as is (I think we did so in ZombieParty, ran good enough).

Another way is to make sure your game objects are updated often enough (30 or 60 times) and ignore any interpolation because it looks good enough anyway. This works fine for some projects, but really looked bad for ZombieHockey on WP7, which needed a lot of interpolation and effects to appear smooth. Basically we interpolated 5 steps in between each frame and faded them out over time. This made the game feel a bit more laggy, but much more smooth and as an extra benefit it was easier to predict where the ball is going at high speeds (like a video with 24fps or 30fps looks still natural and smooth because of motion blur).

For our strategy game Arena Wars 2 we just use 5 game updates per second (every 200ms) and interpolate depending on how many fps you have (can be in the thousands). Because it is a strategy game it does not matter and due effects and sounds and local rotations happen immediately it feels just right. For a first person shooter game this obviously would not work!

In any case, it always comes down to trying around a bit or relying on prior experience to make your game look as smooth as possible. The easiest way is obviously having lots of fps and interpolating or update positions of your game objects as much as possible, but performance wise a cap at 60fps or 30fps might be better for some platforms (mobile and consoles especially).
Offline tidalWave  
#13 Posted : Wednesday, December 21, 2011 3:14:26 AM(UTC)
tidalWave

Joined: 11/29/2011(UTC)
Posts: 15
Location: Ohio, USA

When I coded up my version of interpolation I ensured that it would work with a variable time step. This greatly increases the smoothness when the physics engine has to take larger steps because it's getting bogged down. I was able to get 2500+ boxes to stack up and render at several 100 fps (no rendering optimization was done) and still look fairly smooth even thought the physics needed 60-90ms a step. Setting this style of interpolation up is overkill in all but the most extreme cases, I was just trying to see how smooth I could get my simulation looking with a huge number of objects.

On a side note,

Is is possible to run the built in physics on another thread?

Physics Video

Edited by user Wednesday, December 21, 2011 3:17:52 AM(UTC)  | Reason: Not specified

Offline Benjamin  
#14 Posted : Wednesday, December 21, 2011 4:26:38 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)
Sure, you can run physics on another thread. All the engine currently does is to call Physics.Run, which will execute the implementations UpdateSimulation method. Here you could just return and do all work in an extra thread. Some physic engines also support running in multiple threads, e.g. Jitter, which can be enabled via:

Code:

Physics.Multithreading = true;


If a physics implementation does not support multithreading it is currently ignored, but in the future it will run in an extra thread and the engine will try to separate out unrelated parts of the physics engine to run in multiple threads as well (or at least run in an extra thread).

If you have more suggestions or what to change anything feel free to ask (we might even add Delta.PhysicsEngine in one of the next releases so it is easier to modify it). We currently do not work much on physics as most projects either don't need it much or are fine with the existing feature set. Most work went into physics because of several tech demos, but the game projects don't use much yet ...
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.267 seconds.