About Store Forum Documentation Contact



Post Reply 
Frame rate and Swing Detection
Author Message
SamNainocard Offline
Member

Post: #1
Frame rate and Swing Detection
I currently have a problem with swing detection using same as tutorial one at low frame rate results in some kind of wrap around.

This can be easily test in Swing Collision Detection.cpp, with rotateY (time*5) with spacebar pressed to simulate low fps.

So, is there a way to detect collision that isn't relies on FPS?
06-14-2012 05:37 PM
Find all posts by this user Quote this message in a reply
Harry Offline
Member

Post: #2
RE: Frame rate and Swing Detection
I've noticed it too. In my game I use phys body to detect if player is going inside or outside the building. When FPS is low it isn't always work as it should.
06-14-2012 08:31 PM
Visit this user's website Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #3
RE: Frame rate and Swing Detection
There is a way to detect collisions based on time and positions of 2 objects.
The good news is that it's not all that hard to do.
The bad news is that it requires a lot of math to understand and debug.
Another bit of bad news is that to be efficient, each basic shape(box, sphere, cylinder, tri, etc) should have its own formula. While the calculations themselves are not expensive, it's very easy to go overboard with them.
Try looking at some sites that talk about "Physics collisions" or "Time-based collisions". I'd recommend some material, but I'm old-school, and learned this stuff from good 'ol fashion printed books, and haven't researched it much online.

If you want to check out this book---which I HIGHLY recommend---it's Real Time Collision Detection by Christer Ericson. It goes into detail on a LOT of things[in addition to time-based collision detection] that will save you hours of effort and trial/error. It even goes into things such as spatial partitioning algorithms so that system only renders the sections of 'rooms' that can be seen. And at the end, it has a section on optimization and performing these calculations on the GPU to save CPU resources.
It's got something for everyone. I think even Esenthel could benefit from a lot of the material.
(This post was last modified: 06-15-2012 02:45 AM by Rubeus.)
06-14-2012 11:40 PM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #4
RE: Frame rate and Swing Detection
This seems to have a lot of problem than I think, after a hours of search, there's FPS based, timedelta based, and mixing of both.

(06-14-2012 11:40 PM)Rubeus Wrote:  There is a way to detect collisions based on time and positions of 2 objects.
The good news is that it's not all that hard to do.
The bad news is that it requires a lot of math to understand and debug.
Another bit of bad news is that to be efficient, each basic shape(box, sphere, cylinder, tri, etc) should have its own formula. While the calculations themselves are not expensive, it's very easy to go overboard with them.

Well, it's seem good things are all overcome by bad things. (For me)

I've thinking of the solution and come up these possible solution, but not sure if it's good.

1: Try restores skipped path by finding center of between old and new position and create a new position with same length. However, this can make a U swing become V swing. ( } become ] etc...)

2: Fixed time (like physics.precision()?) but separate game process into two (like client and server). So server could run at fixed time and produce an accurate results, despite how client lag.

3: Animation key, create triangle or shape based on position between key, looking for target orientation.

Edit: Also
Code:
http://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step

Still need more input.
(This post was last modified: 06-15-2012 02:13 PM by SamNainocard.)
06-15-2012 07:56 AM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #5
RE: Frame rate and Swing Detection
I think I see what you are saying. When there is too much of a time delta, the previous and current positions are too far apart to approximate a section of an arc. Instead of the nice arc, your collision turns into a straight line. (The principle that the further apart 2 points on a circle are, the less they approximate the edge of the circle.)
In this case, the collisions are still time-based, so you don't have to worry about the math there, unless you want to custom make a cuts() overload that takes a Bezier or some such.
As a sort of fix, you could try testing the delta value, and if it's so large that your fps is below 20 or so, test for a collision at both (CurrentRot += .5 * NewRotAmount) and (Current Rot += .5 * NewRotAmount). So instead of having just a line at low fps, you should have something closer to a tri(and an extra point on the circle to better approximate its curve). This method won't be expensive, especially if you skip the second collision test when the first is positive.

Is this what you were looking for?
06-15-2012 02:20 PM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #6
RE: Frame rate and Swing Detection
The problem is that skipping and become straight line as you say.

But what I'm thinking is, most of attack animation aren't fixed as arc shape, it could be zig-zag, stab, L shape, uppercut, or so on.

I also interesting on solution of this URL
Code:
https://love2d.org/forums/viewtopic.php?f=4&t=2039
about, Check and update collisions in a fixed time step, until it match timedelta. It could work on any FPS, but it also could give an extra calculation.

I also concern about desync in multiplayer, but that's another question.

Edit: I'll test tomorrow.
(This post was last modified: 06-15-2012 05:02 PM by SamNainocard.)
06-15-2012 04:57 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #7
RE: Frame rate and Swing Detection
These are actually 2 separate issues here. What they are talking about is something like "Is object x on object y" each frame; if the fps is too low and the object has already passed the collideable object, it is still not colliding because it's on the other side(although ideally, it should have collided).
What's happening here is that it is checking the beginning and ending positions of the objects. This works perfect for things like a bullet. The issue here, if you look, is that because the club is rotating, if the club goes 180 degrees in one frame, the start and end positions of the club are going to be a straight line.
Use this image for reference: http://i48.tinypic.com/s6m3gn.jpg
This is a 2 dimensional representation of what is happening. Under normal FPS, P1 and P2 is what you will see with the collision happening on the line between, P2 - P1(it's actually a tri that is being tested, but it complicates the math and this should help you). The hit detection will never be perfect on an arc--as we say in the gaming industry: "Close enough." To use that in real life measurements, it would be like the last .5 inch of your 3ft club doesn't make contact mid swing. But anything that makes contact on that line or below(towards the point of the angle) will be counted as a collision, even if both objects have an endpoint that does not collide.
The problem is when the samples are to far apart, like if the club strikes at P3 from P1, giving you the P3-P1 collision vector. Not very useful! It would be like your 3ft club only making contact with the first 3 inches. No good at all.
Now, let's say that P1 had a rotation that came out to 160 degrees over the course of the one frame to get to P3. If you do a test on the time delta and see that it is unusually high(resulting in P3-P1), then you can break the rotation down into 2 or more 'steps'. Imagine if instead of P3-P1, you had this:
http://i46.tinypic.com/2j14psh.jpg
So basically, instead of rotating 160, you rotate by 160 / 3, check, rotate by 160 / 3, check, etc. This would be the simplest way to solve the issue with the club. Each type of movement and object will have it's own way you will have to fix it. There's no silver bullet for this kind of issue.
If you are talking about using animations for attacks, you would have to add in a lot of code to make sure the animation is not passing a key frame and zigging, making the attack miss when it shouldn't. I'm not familiar enough with the animation system in Esenthel yet to give pointers... but using a bounding volume(or more than one) the size of the attack should yield acceptable results.

And as far as the time goes... it's not something you have to worry about. Having a lower FPS does not affect the timer at all. In fact, the timer is there mainly for the purpose of making sure things DO run at the same speed. Just make sure that everything that moves is multiplied by time delta.
(This post was last modified: 06-15-2012 05:59 PM by Rubeus.)
06-15-2012 05:58 PM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #8
RE: Frame rate and Swing Detection
It's still same problem about phases through things and fail check.
Unless I'm wrong, but motion update is already based on timedelta, the swing hit check got to make it fixed time.

I just tested above method, it seems to work on paper, but the problem is animation won't update until next update frame, so it's just keep calculate at same vector.

Edit: The problem is I can't find the way to receive position. (like Q1/Q2 of you second pic) Unless I use method of #1 to rebuild it by average of each end position.
(This post was last modified: 06-16-2012 01:26 PM by SamNainocard.)
06-16-2012 12:47 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #9
RE: Frame rate and Swing Detection
If you make the swing check fixed time, then that means that if the objects aren't currently colliding during a frame, it won't count. In the tutorial, the whole thing with the tris is so that if the collision happens between frames, it still counts. The trick is making sure area the tris cover is close enough to your motion.

I'm not sure what you mean by that second part... why wouldn't it update the animation until the next frame? Just do the animation/motion updates before the collision detection... Takes a few extra lines of code, but my method does work.
06-16-2012 01:34 PM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #10
RE: Frame rate and Swing Detection
PHP Code:
// Motion
// FPS_TD_CAP=1.0/60.0
// Inside animate();
Flt timeFrame;
    
timeFrame=timedelta;
while(
timeFrame>0)
{

if (
timeFrame<=FPS_TD_CAP)
{
   
mot.updateIn((mot.mot_blendIn*timeFrame)/timedelta, (mot.mot_Spd*timeFrame)/timedelta);
}
else
{
   
mot.updateIn((mot.mot_blendIn*FPS_TD_CAP)/timedelta, (mot.mot_Spd*FPS_TD_CAP)/timedelta);
}
timeFrame-=(FPS_TD_CAP);
cskel.animate(mottrue);
...
check collision...

With debug code, it's show vector of detection remains same (even this loop run 4-5 times at ~15 fps)
(This post was last modified: 06-16-2012 01:59 PM by SamNainocard.)
06-16-2012 01:58 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #11
RE: Frame rate and Swing Detection
Keep in mind that if you add this to the tutorial, the visual representation is drawn only based on the initial and final positions of the object, so visually it should look the same (unless you modify weapon_sweep to hold start, end, and any interim positions). The real test is if it detects a collision.
Also,
timeFrame=timedelta;
then you use *timeFrame)/timedelta
(x*y)/y=x This will cause desync issues.
Try playing around with this in a unit test(or just the tutorial) so you can really see what is happening with the changes you make.
06-16-2012 03:02 PM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #12
RE: Frame rate and Swing Detection
I test this on my game, debugging with display of vec, I also update position of detecting and tri as well.

If this desync mean animation speed at different FPS, it's matched Time.d() (timedelta) with this formula. Because at 60 FPS motion will update once with x1 speed , while 15 FPS it update 4 times with x0.25 each.

Edit: I just add these line into code and vec seems changing, testing.
PHP Code:
cskel.animate(mottrue);
{
     
C Int j=i;
     
REPA(mot.skel_anim->animation()->bones)
     
cskel.updateMatrixChildren(cskel.findBoneI(mot.skel_anim->animation()->bones[i].name));

Edit2: It's seems to detect where it's miss at low fps now, but there's slightly side effect though, character animation may stutter while blend in.

Edit3: Small edit and test before go, cskel.updateMatrixChildren("Body"); seems to be enough, it's no longer stutter and only blur character head a little.

Edit4: Everything seem to be working right now, it can be solved, but still haven't test with non-human character yet. (for side effects).
(This post was last modified: 06-17-2012 05:12 PM by SamNainocard.)
06-16-2012 03:19 PM
Find all posts by this user Quote this message in a reply
Post Reply