GeoApplet1: A Spinning Cube
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.
import com.ms.dxmedia.*; direct animation libraries
import java.awt.*; for getting the applet dimension
import java.net.*; for URLs
|
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. |
public class GeoApplet1 extends DXMApplet {
Set the model in the init() method. |
public void init() {
Always call the super classes init first to ensure codeBase is set. |
super.init() ;
setModel (new GeoModel(this));
}
}
This class extends the Model class. The createModel method in this class
is where you construct your animation. |
class GeoModel extends Model {
Get the size of the applet in the constructor, and stores it in the
member variables. |
GeoModel(DXMApplet dxma) {
Get the size of the applet. |
Dimension dim = dxma.getSize();
The base unit of measure for DirectAnimation is the meter.
Convert the size into meters by multiplying it with the pixelBvr. |
_halfWidthNum = mul(toBvr(dim.width*0.5),pixelBvr);
_halfHeightNum = mul(toBvr(dim.height*0.5),pixelBvr);
}
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. |
GeometryBvr mapToCenteredUnitBox(GeometryBvr geo) {
Find the extent and the center of the geometry. |
Bbox3Bvr bbx3 = geo.boundingBox();
Point3Bvr minPt3 = bbx3.getMin();
Point3Bvr maxPt3 = bbx3.getMax();
Vector3Bvr extVec3 = sub(maxPt3, minPt3);
Point3Bvr centerPt3 = add(minPt3, extVec3.div(toBvr(2)));
NumberBvr maxExtNum = max(extVec3.getX(),
max(extVec3.getY(),
extVec3.getZ()));
Move the object to the origin, and resize it.
Translate takes effect before scale is how compose works. |
Transform3Bvr normalizingXf3 =
compose(scale3(div(toBvr(1), maxExtNum)),
translate(sub(origin3, centerPt3)));
return geo.transform(normalizingXf3);
}
Create the animation in the createModel method. |
public void createModel(BvrsToRun blist) {
Build up a URL to import relative to. |
URL mediaBase = getImportBase();
URL geoBase = buildURL(mediaBase, "geometry/");
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. |
GeometryBvr geo = importGeometry(buildURL(geoBase, "cube.x"));
geo = mapToCenteredUnitBox(geo);
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. |
NumberBvr minHalfExtNum = min(_halfWidthNum, _halfHeightNum);
geo = geo.transform(compose(scale3(minHalfExtNum),
compose(rotate(yVector3, localTime),
rotate(zVector3, mul(localTime, toBvr(1.3))))));
Make the color time-varying. |
geo = geo.diffuseColor(colorHsl(mul(localTime, toBvr(0.3)),
toBvr(0.8), toBvr(0.6)));
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. |
NumberBvr maxZNum = mul(sqrt(toBvr(2)), minHalfExtNum);
NumberBvr projPointNum = mul(toBvr(5), maxZNum);
CameraBvr cam = perspectiveCamera(projPointNum, maxZNum);
Overlay the cube on top of the color image background,
and get the image displayed. |
setImage(overlay(union(geo, directionalLight).render(cam),
solidColorImage(blue)));
}
public static NumberBvr max(NumberBvr x, NumberBvr y) {
return (NumberBvr) cond(gt(y, x), y, x);
}
public static NumberBvr min(NumberBvr x, NumberBvr y) {
return (NumberBvr) cond(lt(y, x), y, x);
}
private NumberBvr _halfWidthNum, _halfHeightNum;
}
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.