<HTML>
<HEAD>
<TITLE>DirectX Media SDK DirectAnimation Tutorial</TITLE>
<LINK REL=STYLESHEET HREF="../../../../../webcd/da/tutorial.css">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso8859-1">
<META NAME="MS.LOCALE" CONTENT="EN-US">
<META NAME="ROBOTS" CONTENT="noindex">
</HEAD>
<BODY BGCOLOR="WHITE" LINK=#0033CC TOPMARGIN=0 LEFTMARGIN=20>
<!--TOOLBAR_START-->
<!--TOOLBAR_EXEMPT-->
<!--TOOLBAR_END-->

<DIV CLASS="flush">
<TABLE WIDTH=100% BORDER=0 BGCOLOR=#000000>
<TR ALIGN=RIGHT><TD VALIGN=TOP><FONT CLASS=desc1 SIZE=2>
<IMG SRC="../../../../../media/image/d_prev.gif"
 WIDTH=71 HEIGHT=16 BORDER=0 ALT="Previous Topic">
<A HREF="../../../../../webcd/da/tutorial_main.htm" TARGET="_top">
<IMG SRC="../../../../../media/image/d_home.gif" WIDTH=48 HEIGHT=16 BORDER=0 ALT="Tutorial Home Page"></A>
<IMG SRC="../../../../../media/image/d_next.gif" WIDTH=48 HEIGHT=16 BORDER=0 ALT="Next Topic">
</FONT></TD><TD WIDTH=30></TD></TR></DIV></TABLE>
<FONT CLASS=title><CENTER>GeoApplet1: A Spinning Cube</CENTER></FONT>
<BR>
<FONT CLASS=desc1>
This applet constructs a spinning cube to fit in the view window.  It
illustrates how to import a geometry, manipulate it, and view it
with a camera.
<BR>
</FONT><BR>

<TABLE WIDTH=100%><TR><TD WIDTH=5%><TD><FONT CLASS=code>

import com.ms.dxmedia.*;        </FONT><FONT CLASS=desc2> direct animation libraries</FONT><FONT CLASS=code><BR>
import java.awt.*;              </FONT><FONT CLASS=desc2> for getting the applet dimension</FONT><FONT CLASS=code><BR>
import java.net.*;              </FONT><FONT CLASS=desc2> for URLs</FONT><FONT CLASS=code><BR>
</FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> This class extends the DXMApplet class.  The model you set in this class,
 by calling the setModel() method, is the model that will be displayed.</TD></TR></FONT></TABLE>
<FONT CLASS=code>public class GeoApplet1 extends DXMApplet {<BR>
</FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Set the model in the init() method.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.125in">public void init() {<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Always call the super classes init first to ensure codeBase is set.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">super.init() ;<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Now set the model.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">setModel (new GeoModel(this));<BR>
</DIV><DIV STYLE="margin-left: 0.125in">}<BR>
</DIV>}<BR>
</FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> This class extends the Model class.  The createModel method in this class
 is where you construct your animation.</TD></TR></FONT></TABLE>
<FONT CLASS=code>class GeoModel extends Model {<BR>
</FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Get the size of the applet in the constructor, and stores it in the
 member variables.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.125in">GeoModel(DXMApplet dxma) {<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Get the size of the applet.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">Dimension dim = dxma.getSize();<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> The base unit of measure for DirectAnimation is the meter.
 Convert the size into meters by multiplying it with the pixelBvr.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">_halfWidthNum = mul(toBvr(dim.width*0.5),pixelBvr);<BR>
_halfHeightNum = mul(toBvr(dim.height*0.5),pixelBvr);<BR>
</DIV><DIV STYLE="margin-left: 0.125in">}<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> This function scales the geometry uniformly to fit in the unit box
 and centers it at the origin.  The bounding box of the resulting
 geometry will be -0.5 to 0.5 in its largest dimension.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.125in">GeometryBvr mapToCenteredUnitBox(GeometryBvr geo) {<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Find the extent and the center of the geometry.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">Bbox3Bvr bbx3 = geo.boundingBox();<BR>
Point3Bvr minPt3 = bbx3.getMin();<BR>
Point3Bvr maxPt3 = bbx3.getMax();<BR>
</DIV><BR>
<DIV STYLE="margin-left: 0.25in">Vector3Bvr extVec3 = sub(maxPt3, minPt3);<BR>
Point3Bvr centerPt3 = add(minPt3, extVec3.div(toBvr(2)));<BR>
</DIV><BR>
<DIV STYLE="margin-left: 0.25in">NumberBvr maxExtNum = max(extVec3.getX(),<BR>
</DIV><DIV STYLE="margin-left: 1.875in">max(extVec3.getY(),<BR>
</DIV><DIV STYLE="margin-left: 2.125in">extVec3.getZ()));<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Move the object to the origin, and resize it.
 Translate takes effect before scale is how compose works.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">Transform3Bvr normalizingXf3 =<BR>
</DIV><DIV STYLE="margin-left: 1.3125in">compose(scale3(div(toBvr(1), maxExtNum)),<BR>
</DIV><DIV STYLE="margin-left: 1.8125in">translate(sub(origin3, centerPt3)));<BR>
</DIV><BR>
<DIV STYLE="margin-left: 0.25in">return geo.transform(normalizingXf3);<BR>
</DIV><DIV STYLE="margin-left: 0.125in">}<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Create the animation in the createModel method.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.125in">public void createModel(BvrsToRun blist) {<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Build up a URL to import relative to.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">URL mediaBase = getImportBase();<BR>
URL geoBase = buildURL(mediaBase, "geometry/");<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Import a cube, scale it to the unit cube and center it at the origin.
 The resulting cube has a bounding box of -0.5 to 0.5 in all 3 dimensions.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">GeometryBvr geo = importGeometry(buildURL(geoBase, "cube.x"));<BR>
geo = mapToCenteredUnitBox(geo);<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Spin the cube around the origin.  Find the smaller of the halfWidth and
 halfHeight of the view window, and use it to scale the cube so that the
 rendered image for the cube will be about half the size of the viewport.
 The part of the cube that's exactly on the viewing plane (Z = 0) will
 be exactly half the size of the viewport, the part that's behind the
 plane will be smaller, and the part that's in front will be bigger.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">NumberBvr minHalfExtNum = min(_halfWidthNum, _halfHeightNum);<BR>
geo = geo.transform(compose(scale3(minHalfExtNum),<BR>
</DIV><DIV STYLE="margin-left: 1.625in">compose(rotate(yVector3, localTime),<BR>
</DIV><DIV STYLE="margin-left: 1.75in">rotate(zVector3, mul(localTime, toBvr(1.3))))));<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Make the color time-varying.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">geo = geo.diffuseColor(colorHsl(mul(localTime, toBvr(0.3)),<BR>
</DIV><DIV STYLE="margin-left: 2.25in">toBvr(0.8), toBvr(0.6)));<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> The near plane should be bigger than the max Z (in this case,
 sqrt(2)*minHalfExtNum after the cube is scaled to fit half viewport)
 of the bounding box of the spinning cube, so the cube doesn't get
 clipped out. The projection point determines the amount of perspective
 you'll see. The farther away it is from the viewing plane, the less
 perspective will result.  Here, it's set to 5 times the near plane.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">NumberBvr maxZNum = mul(sqrt(toBvr(2)), minHalfExtNum);<BR>
NumberBvr projPointNum = mul(toBvr(5), maxZNum);<BR>
CameraBvr cam = perspectiveCamera(projPointNum, maxZNum);<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> Overlay the cube on top of the color image background,
 and get the image displayed.</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.25in">setImage(overlay(union(geo, directionalLight).render(cam),<BR>
</DIV><DIV STYLE="margin-left: 1.3125in">solidColorImage(blue)));<BR>
</DIV><DIV STYLE="margin-left: 0.125in">}<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> max: returns max(x, y)</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.125in">public static NumberBvr max(NumberBvr x, NumberBvr y) {<BR>
</DIV><DIV STYLE="margin-left: 0.25in">return (NumberBvr) cond(gt(y, x), y, x);<BR>
</DIV><DIV STYLE="margin-left: 0.125in">}<BR>
</DIV></FONT>
<BR>
<TABLE><TR><TD WIDTH=500><FONT CLASS=desc1> min: returns min(x, y)</TD></TR></FONT></TABLE>
<FONT CLASS=code><DIV STYLE="margin-left: 0.125in">public static NumberBvr min(NumberBvr x, NumberBvr y) {<BR>
</DIV><DIV STYLE="margin-left: 0.25in">return (NumberBvr) cond(lt(y, x), y, x);<BR>
</DIV><DIV STYLE="margin-left: 0.125in">}<BR>
</DIV><BR>
<DIV STYLE="margin-left: 0.125in">private NumberBvr _halfWidthNum, _halfHeightNum;<BR>
</DIV>}<BR>
</TABLE><BR>
</FONT><FONT CLASS=link><A ID=cpslug HREF="../../../../../help/da/dalegal.htm" TARGET="_top">&#169; 1997 Microsoft Corporation. All rights reserved. Terms of Use.</A></FONT>
</TABLE>
<BR>
<BR>
<DIV CLASS="flush">
<TABLE WIDTH=100% BORDER=0 BGCOLOR=#000000>
<TR ALIGN=RIGHT><TD VALIGN=TOP><FONT CLASS=desc1 SIZE=2>
<IMG SRC="../../../../../media/image/d_prev.gif"
 WIDTH=71 HEIGHT=16 BORDER=0 ALT="Previous Topic">
<A HREF="../../../../../webcd/da/tutorial_main.htm" TARGET="_top">
<IMG SRC="../../../../../media/image/d_home.gif" WIDTH=48 HEIGHT=16 BORDER=0 ALT="Tutorial Home Page"></A>
<IMG SRC="../../../../../media/image/d_next.gif" WIDTH=48 HEIGHT=16 BORDER=0 ALT="Next Topic">
</FONT></TD><TD WIDTH=30></TD></TR></DIV>

</BODY>
</HTML>
