Runtime: Frame Update Cycle
Qt 3D Studio presents a simple, elegant interface for creating interactive 3D content. Concepts like Slides, Components, Actions, Events, Behaviors, Eye-Toggles, and the Animation Timeline are highly intuitive and represent a very accessible interface for controlling what is a necessarily complex real-time runtime system for managing interactive 3D content.
The Qt 3D Studio Runtime operates with a deterministic set of rules that bring the content created with Qt 3D Studio to life. This document outlines what happens in a single frame in terms of the runtime to make this happen.
The calculations and order of operations involved in each frame are fairly complex; in order to explain things more clearly it is helpful to think of each frame being made up of several logical stages. Here is the full overview of the different conceptual stages.
A frame is kicked off by calling
CRuntime::UpdatePresentations; this immediately results in a call to
CInputEngine::GetInputFrame. A subclass of
CInputEngine will take this opportunity to poll the state of the various input devices and fire events indicating user interaction. The base class version of
HandleInputEvent which can be used to do this simply.
Stage 0: Time Distribution
This stage is opaque and will be relatively invisible to you. Before any real calculations for this frame can begin, various time related activities need to be complete. For instance, each presentation itself can be playing or paused. This stage manages this and other time related things.
Stage 1: Process Events
The next result of calling
CRuntime::UpdatePresentations is the processing of events.
The Runtime maintains a first-in/first-out queue of events that are waiting to be processed. When event processing starts this queue will contain events that were fired during the input stage as described above as well as any events that were fired on the previous frame after event processing was completed.
The critical rule of event processing is that all events will be processed before this stage ends and the next stage begins. This includes events that are fired during event processing. This contract allows the Runtime to support chained events, meaning that any event fired as a result of processing another event will be handled in the same frame. This contract helps to ensure consistent presentation state.
It is interesting to note that because slide changes can only be affected as a result of processing events; all slide changes will take place during this stage.
Stage 2: Active Scan
Once all the events for this frame have been processed, and the event queue is empty, a full scan of the graph of elements is performed to find out which elements will be active this frame. The processing of events will result in slide changes and changes to properties which will affect the appearance of the presentation. During this stage, a definitive list of which elements are active is created and this list will be used by subsequent stages to efficiently do their jobs.
It is interesting to note that because this `active list' is created here, and is used by all further stages, changes to the active state of any elements made after this stage will not take effect until the next frame (when the list is calculated again). By clearly drawing this line at this stage we can avoid many of the "doing various things before (or after) you exist" paradoxes inherent in a complex frame rhythm.
Stage 3: Animation
After the list of active elements for this frame has been decided, the Runtime calculates new values for any animated properties on active elements, and applies the new values.
Stage 4: Script Callbacks
The final act of
CRuntime::UpdatePresentations is to call the special active dependent script callbacks. By comparing this frame's active list with the active list from the previous frame the Runtime can determine which elements are becoming active or inactive. The Runtime uses this information to initiate the following script callbacks:
First, any behaviors which were active last frame that are not active this frame will have their
onDeactivate handler called. If multiple behaviors match this the callbacks for parent elements will occur before their children/descendants.
On the very first frame a behavior is active it will have its
onInitialize handler called. If multiple behaviors match this the callbacks for parent elements will occur before their children/descendants. Note that each behavior will only have its
onInitialize handler called once, even if it is deactivated and later reactivated.
Next, any behaviors which were not active last frame that are active this frame will have their
onActivate handlers called. If multiple behaviors match this the callbacks for parent elements will occur before their children/descendants.
Finally, any behaviors that are active this frame will have their
onUpdate handler called. If multiple behaviors match this the callbacks for parent elements will occur before their children/descendants.
Stage 5: Scene Graph Update
The next call you will make is
CRuntime::UpdateScenes. All the activity before this has performed the calculations in the Runtime to ensure the presentation is in a newly updated state for this frame. Calling
UpdateScenes will first result in any changed attributes being communicated through the scene graph to your application through calls to
CRenderEngine::SetAttributes. Then, a recursive update is done on the assets in the scene graph to calculate updated global matrices and hierarchical opacity values.
Stage 6: Render
Finally you will call
CRuntime::Render. This stage consumes all the calculated values produced by the previous stages and translates them into calls on your engine specific subclass of
CRenderEngine. This includes calls like
SetTransform which will communicate the updated global matrices to you and
DrawItem which will indicate that you need to draw a specific item in the scene.
Available under certain Qt licenses.
Find out more.