How to calculate speed of animation base on FPS?

feanor91

18-09-2008 12:42:21

Hi

OK, I think all the question is in the subject...

I have a character to move x metters in y seconds and I have F Fps render in one second. So what is the formula to get speed I mus applied in my animation frame function?

(I know, it's certainly simple, but my brain is like gelee on that....)

feanor91

18-09-2008 14:59:28

Forget it, I have just seen that speed of movement is not linked to FPS. But, I don't manage to find a link between walking speed and distance to move. So, If I want to walk 10 meters in 10 seconds, my walking speed will be 1 m/s but how to translate it through walking speed?

It's important, because my character must move on music and timing is very important (a kind of ballet if you want).

GermanDZ

18-09-2008 22:26:12

You must know how much meters walk your anim every second.

So, you know the speed (the value that you choose), in every UpdateFrame cycle, you have the delta time. So, you can calculate the distance walked by your avatar (time * speed = distance).

The animation must math the speed. If your anim walks .20m/s, and your actual speed is .5 m/s you must addTime 2.5 faster to the anim than delta time.


Sorry, my english is not good and the explanation is some cumbersome.

feanor91

19-09-2008 11:14:17

Thanks for answer, but I don't understand (and it's not for your englis, that is at least as good as mine is...)

By the way, I think I've found....My calculations are false because I base it on a circle...I test with a line and for doing 10 meters in 10 seconds, my walk speed must b 1m/s (that is logic and wias as I expected to be)...I must see now, why it's not functionning on the circle movement but perhaps, I made a mistake in my computation. I will conduct more test.

paddy3k

25-09-2008 07:34:54

Hi feanor!

wasn't here for quite a time.... just back now and I have to manage the same problem. Just thought about it yesterday, but no solution so far. I will investigate that later and tell you 'bout my results (if I got some ;-)

cheers
paddy

feanor91

25-09-2008 11:33:48

Hi

So I continue to investigate. But It's so strange...

First, walking speed is not base on framerate. So if frame rate is verry low, animation is jerky, of course, but if frame rate is above 25 FPS, walking speed is the same on 30, 50 or even 250 FPS. Good Point.

Now, if my guy advance in right way and if I want it to do 20m in 10' , walking speed is equal to 2 (assuming scale of my scene is in meters).

So, we can say that all is fine, but in fact, no....

Know, I want my guy doing a circle say of 4 metters diameter. Formul pi*D give the circumference of 12.56m. So We can think that to make 12.56m in say 10' we mus walk at a speed of 12.56 / 10 = 1.256m/s... But it doesn't work, I must apply a speed of 1.60 m/s to achieve the circle in 10'...

Either I'm stupid or there's something strange somewhere but why a such behavior? If someoe can explain, I will be glad.

Beauty

25-09-2008 12:28:14

Maybe this affect (use 1.6 instead of 1.256 m/s) is caused by impreciseness of timing calculation.
Can you show your code where you calculate the new position?

By the way - if you want to have a continuous walking the calculation must be independent of frame rate. With 50 fps or with 300 fps - your gui should walk always 10s for one circle.

feanor91

25-09-2008 15:27:27

Hi Beauty

For the moment, I have no calculation of timing, I use a track brar to set speed and a chrono to show seconds pass. If I set 1 m/s on the circle I get 11s, with 1.6 m/s I obtain 10s. But, I think that my chhrono isn't accurate, I will try to see that way to obtain a more accurate one. (to have miilisecond pass, for example and check when I start and stop it). I pass not much time on this, because I had make all my animations since monday. I will conduc t more test tomorrow.

Beauty

25-09-2008 18:57:22

I don't know what is chrono. Somehow you have to calculate the position (if he walk steered by code).
Milliseconds can be to imprecise. Better use Ticks. It's precision is not really 0.1ns, but maybe works better.

If you want to know more about precise timing you can look to the links inside of [u]this thread[/u].

feanor91

25-09-2008 19:44:49

Chrono is a timer to time the displacement of my guy, i start it when he begins to move and stop it when he stop, it give me the time of the displacement. But as I say before, I must to check if this timer is accurate.

Netherless here's my code :

Public Function AnimationFrame(ByVal e As FrameEvent) As Boolean
Dim rnd As System.Random = New System.Random()
Dim i As Integer = rnd.Next(1, 6)
Static IdleOld As String = ""
Static Idle As String = ""

If bAnim Then

Try
myAnimationState.AddTime(-e.timeSinceLastFrame * (myWalkSpeed / 50))
If Not myBlender.Complete Then
myBlender.AddTime(e.timeSinceLastFrame)
Else
If Not BlenderInit Then
myBlender.Init(AnimEnCours)
BlenderInit = True
End If
End If
Catch ex As Exception

End Try
If myDirection = Vector3.ZERO Then
If NextLocation() Then
'J'arrête l'animation précédente avant de démarrer l'idle.
'myAnimationState.Loop = False
'myAnimationState.Enabled = False
'Set walking animation
myBlender.Blend("Marche0", AnimationBlender.BlendingTransition.BlendWhileAnimating, 1, True)
BlenderInit = False
myAnimationState = myEntity.GetAnimationState("Marche0")
AnimEnCours = "Marche0"
myAnimationState.Loop = True
myAnimationState.Enabled = True
myWalkSpeed = frmclOgre.trkMoveFactor.Value
Else
'Set Idle Animation
'frmclOgre.TimerChrono.Enabled = False
'If BlenderInit Then
' Idle = "Idle" + i.ToString
' myBlender.Blend(Idle, AnimationBlender.BlendingTransition.BlendWhileAnimating, 5, True)
' BlenderInit = False
' myAnimationState = myEntity.GetAnimationState(Idle)
' AnimEnCours = Idle
' myWalkSpeed = frmclOgre.trkMoveFactor.Value
'End If
'frmclOgre.bAnim = False
End If
Else
Dim move As Single = myWalkSpeed * e.timeSinceLastFrame
MyDistance -= move


If MyDistance <= 0 Then
myNode.Position = myDestination
myDirection = Vector3.ZERO
'Set animation base on if the robot has another point to walk to
If Not NextLocation() Then
'Set Idle Animation
'J'arrête l'animation précédente avant de démarrer l'idle.
Idle = "Idle" + i.ToString
myBlender.Blend(Idle, AnimationBlender.BlendingTransition.BlendWhileAnimating, 1, True)
BlenderInit = False
myAnimationState = myEntity.GetAnimationState(Idle)
AnimEnCours = Idle
myWalkSpeed = 60
End If
Else
'Move Entity
myNode.Translate(myDirection * move)
End If

End If
Dim src As Mogre.Vector3
Dim quat As Quaternion = myNode.Orientation
CVNode.ResetOrientation()
CVNode.Rotate(quat)
src = myNode.Orientation * New Mogre.Vector3(1, 500, -100) + myNode.Position
CVNode.Position = src
CVNode.Yaw(New Mogre.Degree(180))
CVNode.Pitch(New Mogre.Degree(180))

End If

Return True
End Function


As you can see, it's an adaptation of the code taken in the mogre wiki.

The trkMove.value is the track bar that I use to set speed of displacement of my guy.

An image of my test interface :



The trkMove is the trackbar that name 'Vitesse de déplacement' on upper left

Beauty

26-09-2008 01:12:01

hehe, nice screenshot. It's like in my school.
But I can't help you now.
I'm totally tired ... :cry:

feanor91

26-09-2008 12:09:32

lol....

I conduct more test, now, I use a mogre timer to get time. I start it when my anim start and stop it when my anim stop (so strange no?...).

I get 10 mesures and take the average of them, I test on 4 circles with diameters of 2,4, 6 and 8 meters, and I get this :

The speed is constant, I mesure the time to run the circle

Diameter (cm) Speed of walk (cm/s) Distance to run (cm) Time (milliseconds) Real speed (cm/s)
200 100 628,3185307 8929,6 70,36356956
400 100 1256,637061 14100,1 89,12256377
600 100 1884,955592 20475,7 92,05817589
800 100 2513,274123 27815,3 90,35581579


I have a gap of about 2 seconds on each circle. Perhaps it's due to computation of position, and orientation, because the only thing different when my man go straight way is orientation that didn't change....

Now, The time is constant (10s) and I search real speed to run circle in 10s.
Diameter (cm) Speed of walk theorical (cm/s) Distance to run (cm) Time (milliseconds) Real speed (cm/s) Speed Difference
200 62,83185307 628,3185307 10 69 6,168146928
400 125,6637061 1256,637061 10 138 12,33629386
600 188,4955592 1884,955592 10 202 13,50444078
800 251,3274123 2513,274123 10 276 24,67258771

Apparenttly, I must add about 6*(diameter/2) (in meters) to get the real speed (for a time of 10 seconds)

I must conduct more test to see for 20 seconds for exemple, and so on...

Here's my computation of the circle :

For i As Integer = 0 To 360 Step 2
x = r * System.Math.Cos(i / 57.3)
z = r * System.Math.Sin(i / 57.3)
Coord.x = x
Coord.y = 20
Coord.z = z
If i = 0 Then
My.Application.myOgre.OgreSceneManager.GetSceneNode("Pilote").SetPosition(Coord.x, Coord.y, Coord.z)
End If
myAnimation.WalkList.Enqueue(Coord)
Next


As you can see, I have 180 diferent positions, as I want a smooth circle.

I try to optimize my animationframe function by getting out severall variables declaration that I not need to do every time, but it's change nothing. I try to remove Kites displacement too, same effect, I save about 100 milliseconds on one circle....I don't know where to look at.