# 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.

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

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.
I'm totally tired ...

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.