// /** 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() ; // Now set the model. setModel (new GeoModel1(this)); } } // This class extends the Model class. The createModel method in this class // is where you construct your animation. class GeoModel1 extends Model { // Get the size of the applet in the constructor, and stores it in the // member variables. GeoModel1(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))); } // max: returns max(x, y) public static NumberBvr max(NumberBvr x, NumberBvr y) { return (NumberBvr) cond(gt(y, x), y, x); } // min: returns min(x, y) public static NumberBvr min(NumberBvr x, NumberBvr y) { return (NumberBvr) cond(lt(y, x), y, x); } private NumberBvr _halfWidthNum, _halfHeightNum; } //