Fanning Software Consulting

Animating Graphical Displays with Object Instancing

QUESTION: I wish to animate just a portion of my object graphical display. I really don't want to render each object in the display every time I change the position of just one object. I've heard object instancing is what I want to do, but I don't understand how it works. Can you help?

ANSWER: Object instancing is useful when only one object in a group of objects is being changed. Rather than render each object in the scene every time the scene changes by just a little bit, all the unmoving objects are "grouped" or "instanced" together and rendered almost like an unchanging backdrop to the moving object. Depending upon how complicated your object scene is to render, you can obtain significant speed advantages by object instancing.

The trick, if there is one, to object instancing is to put your moving object (or objects) into one model and your unmoving objects into another. There does not have to be just two models; there can be many. The point, however, is to have the things that move in their own separate model or models. And the things that don't move in their own separate model or models. This is done so that the models that move can be separated from the models that don't move when the object instancing is done.

I've written an example program named Rotate_Surface to show you how this is done. Although the entire surface can be rotated with the cursor, the rotations performed via the Rotation menu selection are done with object instancing.

The essential elements of the program are that the surface object and the lights that illuminate the surface are placed in one model, named the changingModel in the code, and the axes are placed in another model, named the unchangingModel. The buttons under the Rotation menu item are all handled by the same event handler, named Rotate_Surface_Instancing. This is the event handler that performs the object instancing. I think the best way to explain object instancing to you is to explain each step in the event handler.

Here is the entire code of the event handler. In the code, the info variable is the information structure that holds the program information needed to run the program. Inside the info are the variables thisWindow and thisView, which are the window and view objects for the program, respectively.

 1 PRO Rotate_Surface_Instancing, event
 3 ; This event handler illustrates the proper way to instance
 4 ; a changing part of the view.
 6 Widget_Control,, Get_UValue=info, /No_Copy
 8     ; What axis should rotation be about?
10 Widget_Control,, Get_UValue=thisRotation
11 CASE thisRotation OF
13    'X Axis': rotAxis = [1,0,0]
14    'Y Axis': rotAxis = [0,1,0]
15    'Z Axis': rotAxis = [0,0,1]
19    ; Put up hourglass.
21 Widget_Control, /Hourglass
23    ; Hide the changing surface model.
25 info.changingModel->SetProperty, Hide=1
27    ; Create an instance of the rest of the graphical display
29 info.thisWindow->Draw, info.thisView, /Create_Instance
31   ; Hide the unchanging model and expose the changing model.
33 info.unchangingModel->SetProperty, Hide=1
34 info.changingModel->SetProperty, Hide=0
36    ; Set the transparent property of the view so both the changing
37    ; and the instance data can be seen at the same time.
39 info.thisView->SetProperty, Transparent=1
41   ; Rotate the surface. And draw the unchanging portion as well.
43 FOR j=0,359, 3 DO BEGIN
44   info.changingModel->Rotate, rotAxis, 3.0, /Premultiply
45   info.thisWindow->Draw, info.thisView, /Draw_Instance

47   ; Set everything back to the way it was.
49 info.thisView->SetProperty, Transparent=0
50 info.unchangingModel->SetProperty, Hide=0
52   ; Redraw the graphic.
54 info.thisWindow->Draw, info.thisView
56    ; Put the info structure back.
58 Widget_Control,, Set_UValue=info, /No_Copy
59 END

Event Handler Explanation

Preliminaries (Lines 1-17)

In these lines the info structure is obtained and the button that caused the event is identified. Button identification occurs via the user values of the three buttons that can generate events. The proper rotational array is set up to perform the surface rotations to follow.

Establishing an Hourglass (Lines 18-22)

Because the rotations will take some time, an hourglass cursor is established to warn the user that processing is going on.

Hiding the Changing Model (Lines 23-26)

The first step in instancing is to hide the changing model. The idea is to take a snap-shot, if you like, of the unchanging elements of the scene. This will be the back-drop that will be rendered along with the changing elements. Rendering all the unchanging elements as a unit can be much faster than rendering each element individually. Here the changing model is hidden by setting the Hide keyword to 1.

Creating the Instance Data (Lines 27-30)

These are the lines that create the back-drop or instance of the scene. The Create_Instance keyword is used in the Draw method of the window object. Note that nothing appears on the display as a result of this operation. The instance is created internally.

Hiding the Unchanging Model (Lines 31-35)

These lines hide the unchanging model and make the changing model visible again. As we do the animation, we are going to view the changing model against the unchanging back-drop or instance we have just created.

Making the View Transparent (Lines 36-39)

In order to view the changing model on top of the instance data, we have to make the view transparent. Otherwise, we wouldn't be able to see the changing model on top of the instance data.

Rotating the Changing Model (Lines 40-46)

These lines perform the rotation of the surface about the specified axis. Note that the instance data has to be rendered each time through the loop, but this is almost always faster than completely re-rendering the scene. The instance data is rendered by using the Draw_Instance keyword to the Draw method.

Restoring the Changes (Lines 47-51)

In these lines we put everything back the way it was. In this case, it means turning view transparency off and making sure the unchanging model is visible again.

Cleaning Up (Lines(52-59)

In these lines we simply redraw the view in the window and make sure the info structure is stored away in the user value of the top-level base.

Web Coyote's Guide to IDL Programming