|
This article assumes you're familiar with HTML,
Jscript, Graphics & Media Download
the code (3KB)
|
Adding Theatrical Effects to Everyday Web
Pages with DirectAnimation Salim AbiEzzi and Pablo Fernicola
|
Integrated with Internet Explorer 4.0 and Dynamic
HTML, DirectAnimation provides easy support for rich
animation effects through a COM-based interface.
|
DirectAnimation can be
used both as a standalone API and as an integrated
component of the Microsoft® Internet Explorer (IE) 4.0
minimal install. This provides unprecedented animation
and multimedia capabilities built into a major Internet
browser (and no special download is needed).
DirectAnimation is integrated with Dynamic HTML (DHTML),
and hence is especially suitable for adding compact,
lightweight animation effects to Web pages. DirectAnimation is the component of the
DirectX™ API
family that provides animation and integrated media
support for Web pages, CD-ROM titles, and multimedia
applications. DirectAnimation supports many media types,
including 2D vector graphics, 3D graphics, sprites,
audio, and video. It also provides a timing and event
model that lets you synchronize events, and can be
applied uniformly across different media types. The COM-based DirectAnimation API and runtime
can be accessed in different ways by different user
groups. HTML authors can integrate animation using the
DirectAnimation multimedia controls. Developers using
VBScript, JScript™, or Java applets can program animations for Web
pages with DHTML integration. And if you're working with
Java, Visual Basic®, or C++, you can develop interactive
ActiveX™
controls or applications. Although the examples here are
written in JScript, the concepts are equivalent for the
other supported languages.
Programming Multimedia Animations is Hard
If you want to develop a multimedia title or
integrate different media types in your application,
you'll soon find that this is fairly demanding of both
time and effort. Traditionally, there are four classes
of multimedia/animation API developed by four different
communities: 2D vector graphics, sprite animation, 3D
graphics, and audio/video. Not only do you have to be
proficient in each of these APIs for the different media
types (with their different programming models), but you
also have to integrate the different outputs and provide
a runtime engine that manages and controls the
animation. On top of that, making the content ready for
deployment on the Web (using the Web as either the
primary platform or as a teaser for a title) means quite
a bit of extra work. One alternative is going outside your code and
creating content using one of the commercial multimedia
authoring tools, or prepackaging the media-rich part of
the content into a canned movie. But content created
through an authoring tool or in the form of a movie is
hard to integrate with other code components, such as
displaying live data or getting user input for
interactivity. In other words, this becomes a black box
piece of media with restrictions that are not compatible
with the flexibility of computers and interactive
animation.
Introducing DirectAnimation
DirectAnimation brings new possibilities,
especially when it comes to combining different types of
media in the same content. With DirectAnimation,
programmers need to learn only a few concepts that they
will be able to apply repeatedly across different media
types. As our examples will illustrate, programmers need
only specify the high-level details of the animation
declaratively; they don't need to deal with the fine
details of managing the animation since this is provided
by the DirectAnimation runtime. DirectAnimation provides three key services to
developers: an animation runtime engine accessible
through a high-level API; a common programming model for
different media types; and advanced animation features,
resolution independence, and runtime optimizations.
DirectAnimation also supports a number of media formats
including 2D vector graphics and text (these types are
intrinsic to the library), sprites (BMP, GIF, animated
GIF, plus all image types supported by IE 4.0), 3D
models (.X files and VRML), all sound formats supported
by DirectShow, and all streamed media types supported by
DirectShow, including upcoming NetShow support. DirectAnimation is a COM API. A set of
convenience classes is also included for Java
developers, providing useful abstractions on top of the
COM API and taking advantage of some of Java's features.
Since it's COM-based, the API is accessible from
JScript, Visual Basic, VBScript, and C/C++ simply by
importing the COM interfaces (Visual Basic 5.0 and
Visual C++® 5.0
are recommended). The API is also accessible to HTML
page authors through the DirectAnimation controls
provided with IE 4.0. DirectAnimation is implemented on top of
DirectShow and the DirectX foundation APIs, including
DirectDraw®,
Direct3D®, and
DirectSound®.
DirectAnimation content benefits from any hardware
acceleration of these underlying technologies. Also, by
building on the capabilities of DirectShow (previously
known as ActiveMovie™), DirectAnimation can support different media
stream formats and can be extended through DirectShow
codec filters.
The DirectAnimation Programming Model
Creating DirectAnimation content consists of
two steps: defining the model and running it. You can
think of the first step as setting up a spreadsheet or
(if you're already multimedia savvy) creating a scene
graph for a retained-mode API. This model-creation step
specifies which DirectAnimation behavior objects to use
and their relationships to each other, their responses
to user input, and how the objects change over time.
While the model is being executed, callbacks into
application code can be triggered and applications have
the ability to modify the model, dynamically altering
the animation. |
|
|
Figure 1: Basic use of
DirectAnimation |
Let's take a look at a "Hello World" example
(see Figure 1) to go over some basic concepts. In
Figure 2, note that the
animation description is inlined with the HTML in a
single file. We start this example by instantiating the
DirectAnimation unified media control. This control can
be used in any environment supporting ActiveX
components. In particular, the DirectAnimation unified
media control can be used in IE 3.0 or 4.0, where it can
be used as either a windowed or windowless
control. From the control, we extract a library of
methods that we call m (for media). Through this library
we access the DirectAnimation functionality. For this
simple example, we defined the "Hello World" string,
drew it in red, and overlaid it on a blue background. At
this point, all the parts for the animation have been
defined. The animation will be played by the control
once we give it the command to start. Note that this
animation contains only constant elements; nothing is
changing over time (not a very exciting animation, but a
valid use of the API nevertheless). The unified media control has two very
important properties. The first is the Image property,
used to set the image to be displayed by the control.
The second is the Sound property, used to set the sound
the control will play. Although the control takes only
one image and one sound, it is very easy to combine
several images or different sounds into single ones. The
Start method causes the control to execute the animation
and to look for and react to user input. The examples throughout this article build on
this simple one. The code fragments shown plug directly
into this same basic framework. If you don't have access
to the media that accompanies this article, you can
easily substitute your own media files instead. Building animation models in DirectAnimation
involves a process of using values in expressions to
construct new values. This is akin to the numeric
arithmetic expressions common in all programming
languages. Technically, common DirectAnimation calls
don't produce side-effects; each call returns a new
value/object. For example, the following line is useless
because the returned value is not assigned to anything,
and hence can't be used later:
|
font.Size(64); // not useful |
font = font.Size(64); //font now has a new size of 64
|
In the "Hello World" example, we came across
number, color, string, font, and image values. We used a
numeric size and a color value to produce a font. We
then combined a string and a font to produce an image.
This image was combined with a solid blue background to
produce the final image passed to the control. We will
show later how DirectAnimation extends this familiar
process of using expressions on values to produce new
values, and how it applies it to time-varying values and
a rich set of media types.
Behaviors
DirectAnimation makes it easy to represent
entities that vary over time and the temporal relations
between them. It does so by introducing the notion of a
behavior as a family of data types of time-varying
values. In this section we'll illustrate some key points
about behaviors by making use of the simplest and most
malleable one, number behaviors. The following code constructs a number that
starts at 0.0 and increases by 1 unit every second
(since this is a floating point value, you get
fractional increments, not just integers):
|
We use this time-varying number to
produce a time-varying color, defined by its hue,
saturation, and luminance. This is known as an Hsl
color. |
textClr = m.ColorHslAnim(hueNum, m.DANumber(0.5), m.DANumber(0.5));
|
Try using this color in the earlier
"Hello World" example: |
font = m.DefaultFont.Color(textClr).Size(48);
|
Note that number behaviors like HueNum
are of type DANumber (the DA stands for
DirectAnimation). The method m.DANumber converts a
regular number to a DANumber. The Anim suffix in some
methods, such as the one in ColorHslAnim in the earlier
example, indicates variations of functions that take
behaviors as parameters, as opposed to constants like
the method ColorHsl would. For those cases where you are
not going to animate parameters, you can use the
functions without the Anim suffix. In that case,
m.ColorHsl(0.3,0.5,0.5) would yield a constant
color. The HueNum number behavior that we've
constructed here cycles through all the color hues in
one second. Let's slow it down by doing some arithmetic
on the number behaviors. All commonly supported floating
point operations are available to DANumbers. These are
provided as method invocations that take DANumbers as
parameters: |
period = 3; // in seconds
timeNum = m.Div(m.LocalTime, m.DANumber(period)); // m.LocalTime/period
|
Unfortunately, the syntax is awfully
verbose for doing simple arithmetic with number
behaviors. This is an aspect of the host language
JScript, and not of DirectAnimation. In languages that
support operator overloading and automatic type casting,
the expression would simply be:
|
timeNum = m.LocalTime/period;
|
Another useful facility for constructing a
number behavior is: |
sizeNum = m.SlowInSlowOut(36, 64, 3, 0).RepeatForever();
font = m.DefaultFont.Color(textClr).SizeAnim(sizeNum);
|
SlowInSlowOut constructs a number that
interpolates between two values over a specified period
of time. It also takes a sharpness parameter, which at
0.0 (like the previous example) gives linear
interpolation, at 1.0 gives maximum slow-in-slow-out,
and at -1.0 gives maximum fast-in-fast-out. The DANumber class provides the ToString
method, which allows us to construct time-varying
strings from number behaviors:
|
textImg = m.TextImageAnim(m.LocalTime.ToString(2), font);
|
This gives us the time relative to when
the animation was started to a 0.01 second precision.
(The ToString parameter specifies the decimal places of
precision, in this case 2.) Combining all the snippets
above, we end up with a time-varying color, size, and
string combined into a time-varying image. DirectAnimation provides an extensive set of
methods for constructing and manipulating number
behaviors. Such behaviors are used to construct
higher-level behaviors like we've seen here with the
color behavior and the string behavior. We will also see
them used for controlling position, orientation, angles,
image opacity, and 2D and 3D transforms. There are some other number behaviors that
we'll define here and use throughout the examples for
convenience: |
negOneNum = m.DANumber(-1);
zeroNum = m.DANumber(0);
halfNum = m.DANumber(0.5);
oneNum = m.DANumber(1);
twoNum = m.DANumber(2);
|
Note that these are constant number
behaviors since their value does not change over time.
On the other hand, when doing animation it is useful to
have number behaviors that do vary over time. With this
in mind, we also defined a number behavior called
oscillatingNum. This number is constructed based on the
sine function (Sin), which returns values ranging from
-1 to 1. As input to the sine function, we will use
localTime, which will be interpreted as an
ever-increasing angular value, in radians. The result
will be a number that varies continuously from 0, to 1,
to -1, and back to 0. |
oscillatingNum = m.Sin(m.LocalTime);
|
Sometimes we want values that show
noncontinuous variation. For example, we may want a
number behavior that starts at 0, goes to 3, and then
restarts at 0. We can easily construct such a behavior
by using the modulo function. Modulo is an operation
that divides two numbers, an operand and a base, and
returns the remainder. This operation guarantees a
result that ranges from 0 to the value of the base.
|
// this gives a number that starts at 0
// increases to 3 and restarts at 0 again
modNumber = m.Mod(m.LocalTime, m.DANumber(3));
|
These two repeating, animated number
behaviors, oscillatingNum and modNum, are extremely
useful for controlling the motion of or animating
elements in content. Usually you need to scale the value
to suit your needs.
Basic Primitives
DirectAnimation is an object-oriented API, with
one of its most important base classes being the
Behavior class. Most of the raw media used in
DirectAnimation content is created through external
tools, then imported into DirectAnimation and abstracted
as a behavior of the respective type. This encapsulation
allows different media to be treated uniformly,
independent of its type or origin. Media files are
imported by specifying their relative paths or URLs. A
few media types, namely text and 2D vector graphics, can
be created directly through DirectAnimation
calls. One of the most frequently used classes derived
from the Behavior class is the Image behavior through
which content is displayed. The Image behavior type
provides some basic 2D image manipulation capabilities
such as clipping, cropping, opacity, and transforms. It
also supports the aggregation of image components. Other
visual types such as 3D geometry or 2D vectors have
rendering methods that produce images. 2D Images Importing
image files creates an Image behavior. DirectAnimation
determines whether the image is supported based on the
file's extension. Image behavior objects can be used as
background pictures, sprites, or even as textures for 3D
objects. |
// import the sprite
spriteImage = m.ImportImage("image.jpg");
// animate the opacity of the sprite since
// the oscillating number
// ranges from -1 to 1, add 1
// to it (making it 0 to 2), then
// divide by 2 (making it vary from 0 to 1).
transparentImg = spriteImage.OpacityAnim(
m.Div(m.Add(oscillatingNum, oneNum),twoNum) );
|
In addition to the opacity method shown in this
example, the Image behavior class provides methods that
allow you to clip the image with a polygon or with a
behavior known as a matte, to crop the image with a
rectangle, to cause the image to repeat by tiling it,
and to transform the image with a 3 X 2 matrix (allowing for scaling, translation, and
shear). Lines and Polygons
DirectAnimation provides a set of 2D vector construction
methods. The supported primitives include lines, arcs,
ovals, and gradient fills. In general, the drawing
methods take as a parameter an array of points. It is
also possible to specify time-varying number behaviors
as points, resulting in animated 2D primitives. The
simple example shown in Figure 3 builds the
house shown in Figure
4.
|
|
Figure 4: Building with 2D Primitives
|
The Fill method allows you to specify whether
the primitive should be stroked, filled, or both at the
same time. Through the LineStyle object, you can control
parameters such as line width, joint style, and line
color. Sound As
was the case for 2D images, the file's extension
determines if a sound file is supported or not. When a
sound file is imported, it returns a DAImportation
object. From DAImportation object, you can extract the
Sound behavior. DAImportation object also contains other
useful information such as the length of the sound.
|
// Bring in the media
mySndObj = m.ImportSound("sound.wav");
mySnd = mySnd.SoundObj.PanAnim(oscillatingNum);
|
The Sound behavior class provides methods that
cause the sound to loop and control the sound's phase,
pan, and gain. Note that you have to set the sound
property on the control for sound to be played in your
animation. |
DAControl.Sound = mySnd.Loop(); // pass a looping sound
|
Movies When imported,
movies create two behaviors: an Image and a Sound. As
was the case with importing sounds, a
DAImportationObject is created. In the case of a movie,
the DAImportationObject contains both a Sound and an
Image behavior. |
movie = m.ImportMovie("movie.avi");
// A movie is treated as an image and a sound
// Here we make the movie's video track loop, by
// only allowing time to range from 0 to the duration
// of the movie
movieImg = movie.Image.SubstituteTime(m.mod(m.LocalTime,movie.Duration));
// now we make the movie's sound loop
// sound is a continuous media, so all we need to do is
// create a looping version of the sound track
movieSnd = movie.Sound.Loop();
// set the image to be displayed and sound to play
DAControl.Image = movieImg;
DAControl.Sound = movieSnd;
|
DirectAnimation makes extensive use of
DirectShow when dealing with streamed media. Any file
type or codec supported by DirectShow works with
DirectAnimation. The movie doesn't have to be a physical
file, but can actually be a live feed streamed over the
network. Depending on its contents, importing a movie
may return just an Image or a Sound behavior. You would
get an EmptyImage or Silence as the behavior for the
corresponding missing media. If you want to, you can
ignore either the video or soundtrack after importing a
movie. The Image behavior created by importing a movie
is time-varying. Depending on the value of time, the
Image behavior takes on a different value (a different
picture). This time-varying characteristic of the Image
behavior is key when trying to make a movie play in a
loop; we make time cycle from zero to the length of the
movie, then restart at zero. For this we can use the
modulo operation discussed earlier, as shown in the
following code: |
movie.Image.SubstituteTime(m.mod(m.LocalTime,movie.Duration));
|
Independent of its time-varying nature, the
Image behavior created by the importMovie method can be
used in the same manner as the Image behavior returned
by importing 2D images, including combining it with
other images and using it as a texture on 3D
objects. Text Text is
constructed by associating a string with a DAFontStyle.
The DAFontStyle object allows you to specify several
different aspects of the text such as the size, color,
and font to be used. If the specified font is not
available in the target machine, a default font is
substituted. |
fontStyle = m.Font("Times", 64, m.Red);
mediaTextImg = m.TextImage("Media", fontStyle.Italic());
//Let's animate the opacity of the text
mediaTextImg = mediaTextImage.OpacityAnim(m.Add(halfNum,
m.Mul(halfNum, oscillatingNum)));
|
Once you create an Image behavior by using the
TextImage method, you can use the resulting image object
as you would any other image. In the previous example we
varied the opacity of the text. You may have noticed that in all the examples,
media importation was done synchronously.
DirectAnimation does allow for asynchronous importation
of media, with a proxy being displayed while the media
is loading. Check the DirectAnimation SDK for
examples.
Units of Measurement and Coordinate
Systems
At this point you've seen how to construct
different media types and change some of their
attributes over time. Now let's see how we can
coordinate and control the movement of media in the page
over time. We will start by examining the coordinate
system used by DirectAnimation, so that you can
understand how to apply transformations later
on. The basic units of measure in DirectAnimation
are the meter (for distance), the second (for time), and
radians (for angles). There are also convenience
functions that let you specify quantities in terms of
other units. For instance, there are variations of
functions that take angle parameters in degrees, and
facilities for specifying measures in pixel
units. DirectAnimation provides the tools to specify
animations in a resolution-independent fashion.
Alternatively, you can use resolution-dependent
techniques so that the animation size varies with the
resolution setting. The DirectAnimation coordinate
system is meter-based, center-origin, and right-handed
(positive y goes upward). DirectAnimation also provides facilities for
pixel specification. These are basically auxiliary
classes that convert from user-specified parameters in
pixels to the internal meter-based representation. These
include a pixel construction mode provided through
PixelLibrary and a conversion factor that converts from
pixels to meters. The latter is called Pixel and is a
DANumber. An interesting side-effect of Pixel being a
number behavior is that, if the monitor's resolution
changes dynamically—either because the user selected a
new mode or because the window was moved to a monitor
with different characteristics (under
Windows®
98)—your animation adapts to the change automatically
without your intervention. In the pixel construction mode, all positional
infor- mation is specified in terms of pixels in
relation to the pixel coordinate system. This coordinate
system is similar to the DirectAnimation coordinate
system but is left-handed (positive y goes down). It is
intended to be similar to that of Dynamic HTML, only the
latter is upper-left-corner centered, so the conversion
between the pixel coordinate system in DirectAnimation
and the DHTML coordinate system is a simple translation.
To illustrate, let's contrast two pixel and
meter versions of basically the same animation (see Figure 5 and Figure 6). We use the meter
library (see Figure 6), where the minor
changes are shown in blue. Be careful when using the pixel mode; it is a
construction mode only and is intended as a convenience
for simple 2D animation. For advanced animation it's
more appropriate to use the meter mode. For example, in
doing 3D or in situations where the animation needs to
extract behaviors from previously specified ones, it's
better to use the meter mode, whereas the Pixel
conversion factor comes in handy for explicitly mapping
pixel values to meters.
Transformations
Transformations are the movers and shakers of
animations. DirectAnimation provides a wide set of
facilities for constructing both 2D and 3D behavior
transformations. The traditional affine (4 X 3) and projective (4 X 4) transformations are supported, including ways
to combine them and to formulate hierarchical,
articulate structures based on them. When an image is imported, the resulting image
is centered at the origin. If we want to slide the image
so that it is left-aligned with the origin, we would
have to apply a translation. So, starting with the
finalImage from the previous example, we first find out
its size by getting the bounding box of the image. The
bounding box is defined in terms of two DAPoint2
behaviors, Min and Max, each with an x and a y
coordinate. |
finalImgBBox = finalImg.BoundingBox;
|
We then determine how much translation the
image needs along the x axis. Since this example is
based on the meter version of the library being used,
the bounding box is always returned in meters. If you
were using the pixel-based library, you would have to
divide the value of the bounding box by m.Pixel.
|
translationNum = finalImgBBox.Max.X;
|
Unless the image is empty, its Max
coordinate will have positive x and y values (remember
that imported images are centered at 0,0). So, to move
to the right, we will translate the image by this x
coordinate. Next, we apply that translation to the image:
|
FinalImg = finalImg.Transform(
m.Translate2Anim(
translationNum, zeroNum));
|
Based on these basic concepts of position and
translation, Figure 7 and 8 show a
collage of 2D graphic primitives with animate affine
transformations applied to them. This code is pretty
much self-explanatory after the material that we covered
earlier, which is a testament to the simplicity with
which animation can be expressed in DirectAnimation. We
use a sinusoidal number behavior that oscillates from 0
to 1, -1, and back to 0 in a specified period. From this
number we construct a variety of transform behaviors. We
use it for scale, translation, shear, and sinusoidal
(rotational) motion.
|
|
Figure 8: 2D Graphic Transformations
|
This animation has two parameters that could be
easily tweaked: period, which controls the speed of the
animation, and dim, which controls its size.
DirectAnimation supports time and its manipulation as
traditional graphics systems do for spatial
dimensions. DirectAnimation provides a way to use affine 3D
transforms on 2D primitives. We used this feature
already in Figure 5 and Figure 6. For the fun of it,
let's use that same 3D rotation and apply it to
finalImage. We can do so by adding the following two
lines: |
rotXf = m.Rotate3RateDegrees(m.Vector3(1,1,1),
45).ParallelTransform2();
finalImg = finalImg.Transform(rotXf);
|
ParallelTransform2 takes a 3D affine
transform and con- verts it to a 2D transform, which
then can be applied to 2D entities. (An orthographic
camera is assumed in doing this conversion.) This is a good example of the modularity and
reuse provided in DirectAnimation. The key point here is
that a whole animation with all its details is
encapsulated as a single behavioral value, finalImg (an
image behavior), which in turn is used as a value for
constructing a higher-level animation in a
straightforward and simple fashion. In addition, what we just did illustrates a
simple hierarchical articulation. Each shape animates in
its local coordinate system, and then a global transform
is applied to animate the combined parts in a global
coordinate system.
Reactive Behaviors
So far we've seen how behaviors are
time-varying values that we combine in expressions to
produce new higher-level values. In this section we will
show how behaviors can also react to events and switch
from one behavioral value to another. A behavior is
capable of encapsulating not only time variability, but
also event reactivity, so in the broad sense they are
reactive behaviors. Let's say we would like the time-varying text
color above to switch to red when we press the left
mouse button. We can achieve this using the Until method
as follows: |
textClr = m.ColorHslAnim(hueNum, m.DANumber(0.5),
m.DANumber(0.5));
textClr = m.Until(textClr, m.LeftButtonDown, m.Red);
|
Until takes two behaviors and an event.
It constructs a value that starts as the first behavior
until the event occurs, at which point it switches to
the second behavior. Clearly, both behaviors need to be
of the same type. This is the simplest form of a reactive
behavior and is sufficient for most situations. For
advanced users, we'll give a quick summary of more
complex reactive behaviors. The following shows how to snapshot the value
of a behavior at the time an event happens:
|
textClr = m.UntilEx(textClr, m.LeftButtonDown.SnapShot(textClr));
|
UntilEx (for extended) takes a starting
behavior and an event that produces the behavior that
gets invoked. In this case it is a SnapShot event since
it produces a snapshot (a constant behavior) of its
parameter. The following shows how to cycle through two
behaviors: |
basicClr = m.ColorHslAnim(hueNum, m.DANumber(0.5), m.DANumber(0.5));
textClr = new ActiveXObject("DirectAnimation.DAColor");
textClr.Init(m.Until(basicClr, m.LeftButtonDown,
m.Until(m.Red, m.LeftButtonDown, textClr)));
|
Basically, a cyclic behavior starts with one
value, switches to the second, and then goes back to the
first. To do this we need to forward declare a behavior,
and use it in constructing the cyclic graph. (Fans of
C++ will be familiar with this dilemma.) Furthermore,
notice the nested use of Until. Since it returns a
behavior, it is possible to use an Until expression in
place of a behavior of the same
type.
Model Construction and Performance Issues
As we mentioned earlier, there are two distinct
steps in a DirectAnimation program: creating the model
and executing the animation. Now let's go into this
concept in more detail. During the creation of the model, the behaviors
are defined, but no actual rendering takes place. For
example, the overlay function, which takes two image
behaviors and combines them, does not create a bitmap of
the rendering of the two images when it executes the
overlay statement. The call merely constructs an
internal data structure that indicates the manner in
which the two images should be combined. The actual
processing of this data structure takes place when the
animation is running. This allows DirectAnimation to
perform optimizations if the media is changing and cache
those images that remain constant, even if they're only
constant for certain intervals. Also, it can skip the
rendering of parts that are not visible
altogether. Given this retained model approach, the heavy
work is done in the animation engine, when the animation
model is processed for display. Thus, high-level
languages such as VBScript and JScript are only involved
in the definition of the model. This means that you will
get the same runtime performance regardless of the
language you use. The only exception to this is when
there are callbacks from your animation into your code,
in which case the performance will be influenced by the
application code that executes and the host language.
3D Geometry
Geometry behaviors are constructed by importing
prefabricated models in .X or .wrl file formats. These
models can then be transformed, textured with images
(including animated and interactive images), assigned
material properties, lit, and projected via a camera
into image behaviors, which then get displayed. Consider the example in Figure 9. We construct a
perspective camera and a point light, and then we import
a cube that we color and spin. We then light the cube
and render it via the camera. This illustrates the
high-level abstraction in DirectAnimation and how it
hides a lot of the details that in traditional 3D
systems get in the way of all but a handful of highly
experienced programmers. 3D should not be that
difficult, and it isn't if you use DirectAnimation. In
DirectAnimation, the number of concepts that the
programmer needs to deal with corresponds roughly to the
ones in the targeted animation
itself.
Putting It All Together
We highly recommend that you download the
examples and media that go along with this article.
We've combined the simple examples shown above in a
single page. We have also included quite a bit of
additional code, even showing off some tricks to achieve
functionality not described in this article. Given the modularity and reuse in
DirectAnimation, we simply cut and pasted the different
media animations as images, translated each image into a
desired position, and then combined all of them into a
single animation that shows 2D vector, sprites, movies,
3D, texturing, text effects, and audio. The DirectAnimation SDK includes an extensive
set of documents and samples; it's available for
download from http://www.microsoft.com/msdn/sdk/inetsdk
as part of the Internet SDK, and for online browsing
from
http://www.microsoft.com/msdn/sdk/inetsdk/ Samples/DirectAnimation/Default.htm. We've set up public newsgroups on the
msnews.microsoft.com NNTP server as a forum for the
DirectAnimation user community. Any questions you have
about DirectAnimation can be posted on
microsoft.public.multimedia.directx.danimation.controls
(for users of the DirectAnimation controls), or
microsoft.public.multimedia.directx.danimation.programming
(for programmers of the DirectAnimation API).
|
| | |