Home   Donators   Contact Us       

<< Previous Tutorial     Next Tutorial >>

Tutorial 17 - Keyframe interpolation



Theory

It is recommended that your first complete Tutorial 16 - The key in frames before you commence with this tutorial.

Now that your engine has the capability to capture keyframes of your scenes, the next step is to move smoothly between these frames. This is achieved by using a technique better known as interpolation.

When we study the above illustrations, you'll notice that we are working with two keyframes that contain a bone structure with three joints (red, green and blue vertices). Interpolation is the intermediate step between rendering the two keyframes. Instead of rendering frame one and directly thereafter frame two, we render an intermediate scene before rendering frame two. This intermediate step results in a more fluent animation flow between the two keyframes.

The red line in the image below represents the timetrack of our animation. When we render a scene with an interpolation value of 0, then frame one is rendered. When we render our scene with an interpolation value of 1, then frame two is rendered. Using any real value in between 0 and 1 results in an interpolated scene being rendered, based on the given value. E.g. rendering with an interpolation value of 0.5 will render an interpolated scene halfway between frame one and two.

In a similar fashion to how we interpolate rotations of joints, we can interpolate the rotation, position or scale of any model in our scene.

Tutorial Steps
Tutorial created with Real Studio 2011 Release 4.3.
1. Copy the project folder of the previous tutorial to a new folder or download and extract the content of Tutorial 16 to a new folder.
2. Open the project with Real Studio.
3. Reduce the height of the listbox on Window1 to make space for another button.
4. Add a second PushButton control to Window1.
5. Rename the PushButton to "cmdPlay" and position it below the cmdSaveKeyframe button. Make sure that the button does not overlap with the OpenGLSurface control.
6. Set the caption of cmdPlay to "Play".
7. Change the Position settings of cmdPlay to LockTop and LockRight (LockLeft and LockBottom should not be ticked).

Your form should now look as follow:



8. Add a second Timer control to Window1.
9. Change the Period property of Timer2 from 1000 to 75.
10. Remove R3Scene, R3Model and R3Joint from the project.
11. Download the following files and save them next to your project file:
12. Import the classes into your project file. (Select File > Import... from the main menu)
13. Add a property named "Interpolation" of type Double to Window1.
14. Add a property named "KeyframeIndex" of type Integer to Window1.
15. Add a property named "Playing" of type Boolean to Window1.
16. Replace the code in the Window1.Open event with the following code:
Dim model As R3Model ' temporary model object
Dim cube As R3Model ' temporary cube model
Dim i As Integer
Dim light As R3LightSource  ' light source
Dim cam As R3Camera ' camera used in our scene

me.Maximize ' maximize the window
me.MouseCursor = REALbasic.System.Cursors.StandardPointer ' set mouse cursor

' instantiate the Scene object

Scene = new R3Scene
Scene.BackgroundColor.SetValue(1, 1, 1) ' white background

' load textures used in scene

Scene.Texture.Append new R3Texture(imgFinger)
Scene.Texture.Append new R3Texture(imgPrint)
Scene.Texture.Append new R3Texture(imgCube1)
Scene.Texture.Append new R3Texture(imgCube2)

' add front light source

light = new R3LightSource
light.Position.SetValue(1, 0, 3)
Scene.LightSource.Append light

' add camera

cam = new R3Camera
cam.DollyOut 30 ' move back so that we can get the model in our view
Scene.Camera.Append cam

Scene.ActiveCamera = 0 ' set the index of the active camera

' instantiate a new hand model

model = R3_Tut00016Hand

' add the model to our scene

Scene.AppendModel model

' add cubes

for i = 0 to 2
cube = R3_Tut00016Cube
Scene.AppendModel cube
next i

' starting status of all fingers are erected

FingerErected.Append true  ' pinky
FingerErected.Append true  ' index finger
FingerErected.Append true  ' middle finger
FingerErected.Append true  ' ring finger
FingerErected.Append true  ' thumb


' disable animation timers

Timer1.Enabled = false
Timer2.Enabled = false

FingerIndex = -1 ' no finger selected

OpenGLSurface1.Render ' refresh OpenGL surface
17. Add the following code to the Action event of Timer2:
' do we have enough frames to interpolate with?
if Keyframe.Ubound > 0 then

  ' yes, so set up the scene with interpolation between keyframes

  Scene.SetKeyframe Keyframe(KeyframeIndex), Keyframe(KeyframeIndex + 1), Interpolation

  OpenGLSurface1.Render ' refresh the OpenGL surface

  Interpolation = Interpolation + 0.1 ' go to the next interpolated frame

  if Interpolation >= 1 then
  
    KeyframeIndex = KeyframeIndex + 1
    Interpolation = 0.1
  
    if KeyframeIndex > (Keyframe.Ubound - 1) then
	  KeyframeIndex = 0
    end if
  
  end if

end if
18. Add the following code to the Action event of cmdPlay:
' are we busy playing the keyframes?

if Playing then

  ' yes, so stop playing the keyframes

  Timer2.Enabled = false

  cmdPlay.Caption = "Play" ' change caption of play button

  ' enable controls

  cmdSaveKeyframe.Enabled = true
  lstKeyframes.Enabled = true

  Playing = false ' indicate that we are not busy playing the keyframes

else


  ' no, so start playing the keyframes

  ' first disable controls while playing keyframes

  cmdSaveKeyframe.Enabled = false
  lstKeyframes.Enabled = false

  cmdPlay.Caption = "Stop" ' change caption of play button

  KeyframeIndex = 0
  Interpolation = 0

  Timer2.Enabled = true

  Playing = true ' indicate that we are busy playing the keyframes

end if
19. Save and run the project.
  • Click and drag on the white background to rotate the hand.
  • Click on any finger to open or close the finger.
  • Click on any cube to give it a partial rotation.
  • To save the scene's current keyframe, click the "Save Keyframe" button.
  • Set up a couple of keyframes, then click on the play button to interpolate between them.
Code Analysis

In the previous tutorial we changed the scene by passing a R3SceneKeyframe object to the R3Scene.SetKeyframe method. This instantly changed the scene to the given keyframe.

The new R3Scene class used in this tutorial has a second SetKeyframe method, with the difference being that a start keyframe, end keyframe and interpolation value is passed in as parameters. This method will automatically interpolate the scene, using the given keyframes and interpolation value.

On line 6 of the Timer2.Action event you can see how we use this new method to generate an interpolated scene from two keyframes. On line 10 we increase our interpolation value by 0.1 until it reaches 1. When the interpolation value reaches 1, we make the current end keyframe the new start keyframe and we make the next keyframe in our array the new end keyframe. The interpolation value is also reset to 0.1.

The Timer2.Action basically loops through all the captured keyframes, and goes back to the first keyframe as soon as we reach the end of the keyframe array.

A new SetKeyframe method is also added to our R3Model class to assist with the interpolation of individual models.

The R3Joint class got a new method named Interpolate that serves the same purposes as the SetKeyframe methods of the R3Scene and R3Model classes.

Study the logic of the Timer2.Action event until you feel comfortable with how the new interpolation methods can be used to create a smooth animation effect between different keyframes.

Project Downloads

<< Previous Tutorial     Next Tutorial >>


 
All the content on Real 3D Tutorials, with the exception of the SyntaxHighlighter which is licensed under the MIT License, is provided to the public domain and everyone is free to use, modify, republish, sell or give away this work without prior consent from anybody. Content is provided without warranty of any kind. Under no circumstances shall the author(s) or contributor(s) be liable for damages resulting directly or indirectly from the use or non-use of the content.
Should you find the content useful and would like to make a contribution, you can show your support by making a donation.