## Using Models

This section discusses how to use models in DirectAnimation. A model is the set of behaviors actually displayed. It is composed of images and sounds. This section contains the following topics:

- Models in DirectAnimation
- Setting Preferences
- DXMApplet and DXMCanvas
- Causing External Side Effects upon Java Events

### Models in DirectAnimation

In DirectAnimation, a model is the set of behaviors actually displayed for the application. A model typically consists of viewing an image behavior and a sound behavior.

In scripting, the model is automatically set when you invoke DAViewerControl's Start subroutine. Whatever image or sound is attached to the control object at the time Start is called is what is displayed. For example:

    DAMyControl.Image = MyImage;
    DAMyControl.Sound = MySound;
    DAMyControl.Start();

DirectAnimation for Java provides a Model class to standardize the construction of DirectAnimation models. In order to view a behavior, an instance of this Model class must be provided as input when constructing a DirectAnimation viewer inside a DXMApplet or DXMCanvas subclass. This is the relevant portion of the Java definition of the Model class:

    public abstract class Model extends Statics
    {
       // This is to be overridden by the application
       public abstract void createModel(BvrsToRun blist);

       // These are to be invoked by the application
        public void setImage(ImageBvr im1);
        public void setSound(SoundBvr snd);

        // These are invoked by the application to get and set the URL for importing files
        public URL getImportBase();
        public void setImportBase(URL url);

    }

Applications override this class and implement at least the createModel method. This method creates the set of behaviors to be displayed, then calls setImage and setSound on the image and sound behaviors that are intended to be viewed.

The following is an example model that simply constructs a red image. This model has no sound.

    public class RedImg extends Model {
        public void createModel(BvrsToRun blist) {
            ImageBvr im = solidColorImage(red);
            setImage(im);
        }
    }

### Setting Preferences

Occasionally, the programmer constructing the model, or the application controlling the viewer, will want to provide explicit rendering/viewing preference settings to DirectAnimation. Such preferences can include texture mapping quality, output audio format, maximum frames per second, polygon fill mode, and so on.

The Preferences object is the means by which these settings are made. A model can set preferences upon model construction, and the application can set them at any time by querying the viewer for them, setting them, and then submitting them back to the viewer.

To set preferences, first create a Preferences object, as shown in the following JScript code:

     p = DAControl.View.Preferences;

When the application is run, the Preferences object will be set to the default preferences in the registry. You can override these settings by calling the Preferences class PutPreference method. For example:

     p = DAControl.View.Preferences;
     oldvalue = p.GetPreference("FILL_MODE");
     p.PutPreference("FILL_MODE", FILL_MODE_SOLID);

Note also that, through the system registry, the user has an opportunity to establish preferences that become the default set of preferences for viewing a model. Changes made by the model or the application override these defaults. Because of this, setting of preferences should be something that both the model and the application approach conservatively, and only do if it is truly appropriate for the situation.

Also see the reference entry for the Java Preferences Class.

### DXMApplet and DXMCanvas

In DirectAnimation, a model is the set of behaviors actually displayed and sampled for the application. A model typically consists of some combination of image behaviors and sound behaviors. DirectAnimation for Java provides a Model class to standardize the construction of DirectAnimation models. For example:

    public class RedImg extends Model {
        public void createModel(BvrsToRun blist) {
            ImageBvr im = solidColorImage(red);
            setImage(im);
        }
    }

In order to view a behavior, an instance of this Model class must be provided as input when constructing a DirectAnimation viewer inside a DXMApplet or DXMCanvas subclass.

DirectAnimation for Java provides the DXMApplet and DXMCanvas classes that extend the standard AWT Applet and Canvas classes and provide applets and canvases specifically for displaying behaviors. Each of these requires a Model upon construction, and each overrides the necessary methods on Applet and Canvas in order to view that model.

By default, DXMApplet and DXMCanvas provide their own frame-loop so the application needn't provide one explicitly (though it may choose to do so by overriding this default behavior). See the GeoApplet2 template in the Samples\DA\Java\Templates\Applet\GeoApplet2 directory.

Here is an example of using the DXMApplet class to view a model:

    public class MyApplet extends DXMApplet {
        public void init() {
           // Always call the superclass's init() first to ensure codeBase is set
           super.init();
           // Now set the model
           setModel(new MyModel());
        }
    }

Given a model, this is all that is needed to construct an applet to view that model.

The use of DXMCanvas is identical, except, you need to position the canvas inside of an application frame, just as you would any other canvas. For an example of how to use DXMCanvas, see the Java code in Samples\DA\Java\Templates\Application.

#### Dynamically Changing the Java Model

The DXMApplet and DXMCanvas classes are defined such that once an applet or canvas is built, the model cannot be changed. This is intentional. If there is a need to change the model dynamically, this should be reflected in changes to the behaviors that make up the model, and not by switching to another model. If an application really needs to switch to an entirely different model, it can construct a new applet or canvas.

#### The Java Viewer Interface

DirectAnimation for Java provides a Java interface called Viewer that encapsulates operations common to all displayers of behaviors. Because it is an interface, it is not constructed directly by applications. Instead, it is provided through concrete classes such as the DXMApplet and DXMCanvas classes. However, it does have a set of methods that can be used by applications.

Most applications never need to call any of these methods or, for that matter, ever need know about the Viewer interface. This is only for more explicit control of the running of behaviors, and for non-default ways of dealing with error handling and preference establishment.

Here are the relevant portions:

    public interface Viewer {
        public abstract double getCurrentTime();
        public abstract double getCurrentTickTime();
        public abstract Preferences getPreferences();
        public abstract ErrorAndWarningReceiver registerErrorAndWarningReceiver(ErrorAndWarningReceiver w);
        public abstract void startModel();
        public abstract void stopModel();
        public abstract void tick();
        public abstract void tick(double timeToUse);
    }

The viewer gets its model via a mechanism not shown here (it is not meant to be called by applications). The relevant methods are:

- The startModel() method which starts the behaviors associated with the model at global time 0. This is when the globalTime behavior starts. Incidentally, startModel() is also what causes the createModel() method on the model itself to get invoked.
- The tick(double timeToUse) method which explicitly does a single sampling and display of the model with timeToUse as the global time.
- The tick() method, which is shorthand for tick(getCurrentTime()), and is the easiest way to explicitly sample and display the model, thus providing a real-time clock for global time.
- The rrentTime() method returns the number of seconds since startModel was invoked.
- The getCurrentTickTime() method returns the time provided for the most recent call to tick, or 0 if it hasn't yet been called.
- The registerErrorAndWarningReceiver() method which allows the application to register an object that will have its methods invoked upon asynchronous errors encountered when DirectAnimation is controlling the frame loop, or when recoverable warnings occur when sampling and displaying the model.
- The getPreferences/setPreferences methods which allow the application to dynamically modify the viewer preferences.

#### Explicit Control of the Frame Loop

The implementations of DXMApplet and DXMCanvas implement a thread that repeatedly calls the tick() method, and thus have a built-in frame loop. If an application wants to explicitly control the frame loop, it must override these classes and provide different implementations that invoke tick() in their application-specific way.

### Causing External Side Effects upon Java Events

Sometimes an application wants to cause an external action when an event occurs in DirectAnimation for Java. For instance, the application may want to display a GUI window when the mouse moves past a certain region of the window. This capability is supported by the registerCallback method available on events. The registerCallback method takes an object that implements the EventCallbackObject interface (along with some other parameters), and returns an Object that can later be used to unregister that callback. Whenever that event occurs, the invoke method of the callback is called with the event data produced by that event.

Here is an example:

    class MyCallback implements EventCallbackObject {
        MyCallback(...);

        public void invoke(Object eventData) {
            ... pop up my GUI window ...
        }
    }
    //... elsewhere ...
    ev = predicate(gte(mousePosition.getX(), toBvr(0.05)));
    Object cookie = ev.registerCallback(new MyCallback(...),
                                        startTime,
                                        false);  // not a one-shot event
    // ... from this point, every occurrence of ev will trigger "invoke"
    ...
    // at some later point, unregister the callback
    unregisterCallback(cookie);

Registering callbacks can be thought of as a complement to AppTriggeredEvent. The former causes an application action to occur upon a DirectAnimation event, while the latter is an application action triggering a DirectAnimation event.

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.