home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 14 / IOPROG_14.ISO / soft / sdkjava / dxma.exe / DXMA05.cab / samples / da / java / showcase / Magnify / Magnify.java next >
Encoding:
Java Source  |  1997-11-13  |  13.8 KB  |  315 lines

  1. // Magnify.java
  2. // DirectAnimation Java Demo 
  3. //
  4. // Copyright (c) 1997 Microsoft Corporation
  5.  
  6. import com.ms.dxmedia.*;
  7. import java.awt.*;
  8. import java.net.*; //added to support URL's
  9.  
  10. class MagnifyTest extends Model implements UntilNotifier 
  11. {
  12.     GeometryBvr     cylinder;
  13.     GeometryBvr     cube;
  14.     GeometryBvr     cone;
  15.     ImageBvr cloudImage;
  16.     ImageBvr waterImage;
  17.     CameraBvr theCamera;
  18.     
  19.     // string pairs
  20.     StringBvr actionsTxt[] = {toBvr("DirectAnimation"),
  21.                             toBvr("Left Click"),
  22.                             toBvr("Right Click"),
  23.                             toBvr("Mouse Moves"),
  24.                             toBvr("Space Bar"),
  25.                             toBvr("Up Arrow"),
  26.                             toBvr("Down Arrow"),
  27.                             toBvr("Left Arrow"),
  28.                             toBvr("Right Arrow")};
  29.  
  30.  
  31.     StringBvr resultsTxt[] = {toBvr("Magnifier"),
  32.                             toBvr("To Speed Up"),
  33.                             toBvr("To Slow Down"),
  34.                             toBvr("Minifies"),
  35.                             toBvr("Textures"),
  36.                             toBvr("Enlarges Window"),
  37.                             toBvr("Shrinks Window"),
  38.                             toBvr("Magnifies"),
  39.                             toBvr("Minifies")};
  40.          
  41.     ArrayBvr actionsArray = new ArrayBvr(actionsTxt);
  42.     ArrayBvr resultArray  = new ArrayBvr(resultsTxt);
  43.     NumberBvr speedNumber;
  44.     DXMEvent  changeSpeedEvent;
  45.  
  46.   public void createModel(BvrsToRun blst) {
  47.  
  48.     URL mediaBase = getImportBase();
  49.     URL imgBase = buildURL(mediaBase,"image/");
  50.     URL geoBase = buildURL(mediaBase,"geometry/");
  51.     URL sndBase = buildURL(mediaBase,"sound/");
  52.  
  53.         // import sound  
  54.         SoundBvr switchSound    =
  55.             importSound(buildURL(sndBase,"etherial.mp2"),null).loop();
  56.  
  57.         // import geometry 
  58.         GeometryBvr sphere      =
  59.             importGeometry(buildURL(geoBase,"sphere.x"));
  60.  
  61.         cube = importGeometry(buildURL(geoBase,"cube.x"));
  62.               cylinder = 
  63.           importGeometry(buildURL(geoBase,"cylinder.x"));
  64.               cone = 
  65.           importGeometry(buildURL(geoBase,"cone.x"));
  66.  
  67.         // import images
  68.         cloudImage              =
  69.             importImage(buildURL(imgBase,"lake.jpg"));
  70.                 //cloudImage = cloudImage.transform(scale2(toBvr(1.25)));
  71.         waterImage              =
  72.             importImage(buildURL(imgBase,"mshingle.jpg"));
  73.         ImageBvr starsImage     =
  74.             importImage(buildURL(imgBase,"stars.jpg"));
  75.  
  76.         ImageBvr lightningImage =
  77.             importImage(buildURL(imgBase,"metalic.jpg")).tile();
  78.  
  79.         // Crop the lightning image to the same size as the applet.
  80.         // We get these pixel values from the HTML page.
  81.         NumberBvr halfX = mul(toBvr(386/2),pixelBvr);
  82.         NumberBvr halfY = mul(toBvr(256/2),pixelBvr);
  83.         lightningImage = lightningImage.crop(point2(neg(halfX),neg(halfY)),
  84.                                              point2(halfX,halfY));
  85.                 
  86.                 
  87.         // time varying transforms 
  88.         Transform3Bvr funkyXf1 =
  89.             compose(scale(add(div(abs(sin(div(localTime,toBvr(5)))), toBvr(2)),toBvr(0.3)),
  90.                           add(div(abs(sin(div(localTime,toBvr(7)))), toBvr(2)),toBvr(0.3)),
  91.                           add(div(abs(sin(div(localTime,toBvr(9)))), toBvr(2)),toBvr(0.3))),
  92.                     compose(rotate(yVector3,div(localTime,toBvr(4))),
  93.                             rotate(zVector3,div(localTime,toBvr(7)))));
  94.  
  95.         Transform3Bvr funkyXf2 =
  96.             compose(scale(add(abs(sin(add(div(localTime,toBvr(9)),div(toBvr(Math.PI),toBvr(3))))),toBvr(0.3)),
  97.                           add(abs(sin(add(div(localTime,toBvr(11)),div(toBvr(Math.PI),toBvr(2))))),toBvr(0.3)),
  98.                           add(abs(sin(div(localTime,toBvr(17)))),toBvr(0.3))),
  99.                     compose(rotate(xVector3, div(localTime,toBvr(8))),
  100.                             compose(rotate(yVector3, div(localTime, toBvr(9))),
  101.                                     rotate(zVector3, div(localTime, toBvr(11))))));
  102.  
  103.         // create the needed camera
  104.         theCamera = parallelCamera(toBvr(1)).
  105.             transform(compose(translate(toBvr(0),toBvr(0),toBvr(0.1)),
  106.                               scale(toBvr(1),toBvr(1),toBvr(1e8))));
  107.  
  108.  
  109.         DXMEvent evLeftButton  = leftButtonDown.attachData(new Integer(1));
  110.         DXMEvent evRightButton = rightButtonDown.attachData(new Integer(-1));
  111.         changeSpeedEvent       = orEvent(evLeftButton,evRightButton);
  112.         speedNumber            = (NumberBvr) untilNotify(toBvr(-1),changeSpeedEvent, this);
  113.                 
  114.         // Sound
  115.         SoundBvr snd1 = switchSound.rate(switchTime());
  116.         SoundBvr snd  = mix(snd1.pan(toBvr(-1.0)),
  117.                             (snd1.rate(toBvr(1.1))).pan(toBvr(1.0)));
  118.  
  119.         // time varing color
  120.         ColorBvr col = colorHsl(div(localTime,toBvr(30)),
  121.                                 add(mod(div(localTime,toBvr(20)),toBvr(0.5)),toBvr(0.5)),
  122.                                 toBvr(0.5));
  123.  
  124.         // ... and its RGB complement
  125.         ColorBvr invCol    = colorRgb(sub(toBvr(1),col.getRed()),
  126.                                       sub(toBvr(1),col.getGreen()),
  127.                                       sub(toBvr(1),col.getBlue()));
  128.  
  129.         ImageBvr textImage = textStr(col,invCol);
  130.  
  131.         // Initial "source" image is the text over the geometry over the
  132.         // background.  "Start" all the images so they don't reset when
  133.         // switched to.
  134.         Point2Bvr lightnngMin = (lightningImage.boundingBox()).getMin();
  135.         Point2Bvr lightnngMax = (lightningImage.boundingBox()).getMax();
  136.  
  137.         ImageBvr sourceImg1   = overlay(textImage,
  138.                                         overlay(geometryImage(invCol, switchTime()),
  139.                                                 lightningImage));
  140.  
  141.         // next source image is the initial textured onto an object, then rendered
  142.         Point2Bvr cloudMin        = (cloudImage.boundingBox()).getMin();
  143.         Point2Bvr cloudMax        = (cloudImage.boundingBox()).getMax();
  144.  
  145.         ImageBvr sourceImg2   = textureIt(sourceImg1.crop(lightnngMin,lightnngMax),
  146.                                           compose(scale3(toBvr(0.05)),funkyXf1),
  147.                                           sphere,
  148.                                           cloudImage);
  149.  
  150.         ImageBvr sourceImg3       = textureIt(sourceImg2.crop(cloudMin,cloudMax),
  151.                                               compose(scale3(toBvr(0.025)),funkyXf2),
  152.                                               cube,
  153.                                               starsImage);
  154.  
  155.         // Source to really uses swaps between these three
  156.         // set up the Cycle behavior
  157.         ImageBvr behaviors[] = {sourceImg1,sourceImg2,sourceImg3};
  158.         Cycler  cyl          = new Cycler(behaviors,keyDown(32) );
  159.         ImageBvr sourceImage = (ImageBvr)cyl.getBvr();
  160.  
  161.         // Come up with magnification ranges and factors based on keystokes
  162.         NumberBvr magnifyRange     = add(toBvr(0.4),sub(keyIntegral(Event.UP,toBvr(0.1)),keyIntegral(Event.DOWN,toBvr(0.1))));
  163.         NumberBvr magnifyFactor    = add(toBvr(2.0),sub(keyIntegral(Event.RIGHT,toBvr(0.5)),keyIntegral(Event.LEFT,toBvr(0.5))));
  164.  
  165.  
  166.         // Magnifying image relies on magIM func applies to original image and
  167.         // reactive parameters to change magnification attributes.
  168.         ImageBvr magnifyingImage = magIm(sourceImage, magnifyFactor, magnifyRange);
  169.  
  170.         // Total model is the magnifying glass over the image being magnified,
  171.         // and the same sound on each channel, with one slightly faster than
  172.         // the other, just for kicks
  173.         setSound(snd); 
  174.  
  175.         setImage(overlay(magnifyingImage,overlay(sourceImage,solidColorImage(white))));
  176.                 
  177.     }       
  178.     public void cleanup() {
  179.       super.cleanup();
  180.       speedNumber=null;
  181.     }
  182.  
  183.  
  184.     NumberBvr keyIntegral(int key, NumberBvr amtPerSec)
  185.     {
  186.         NumberBvr change = (NumberBvr) cond(keyState(key),amtPerSec,toBvr(0));
  187.         return(integral(change));
  188.     }
  189.  
  190.  
  191.     // Speed
  192.     NumberBvr switchTime()
  193.     {       
  194.         return(pow(toBvr(2),speedNumber));
  195.     }
  196.  
  197.     // Take a str pair and two colors, and render an image consisting
  198.     // of one over the other
  199.     ImageBvr textStr(ColorBvr col1, ColorBvr col2)
  200.     {
  201.             NumberBvr index         = mod(localTime,toBvr(resultsTxt.length));
  202.       FontStyleBvr fs1 = defaultFont.color(col1).bold();
  203.       FontStyleBvr fs2 = defaultFont.color(col2).bold();
  204.       
  205.       ImageBvr im1 = stringImage((StringBvr)actionsArray.nth(index), fs1);
  206.       ImageBvr im2 = stringImage((StringBvr)resultArray.nth(index), fs2);
  207.         
  208.       Point2Bvr ext1          = (im1.boundingBox()).getMax();
  209.       ImageBvr composite = overlay(im1,im2.transform(translate(toBvr(0),mul(neg(ext1.getY()),toBvr(2)))));
  210.  
  211.         return(composite.transform(scale2(2.0)));
  212.     }
  213.  
  214.     // Build up the geometry to be displayed
  215.     ImageBvr geometryImage(ColorBvr col, NumberBvr velocity)
  216.     {
  217.                 
  218.         // Raw geometries
  219.         GeometryBvr rg1 = cylinder.texture(waterImage.mapToUnitSquare());
  220.         GeometryBvr rg2 = cube.texture(cloudImage.mapToUnitSquare());
  221.         GeometryBvr rg3 = cone.diffuseColor(col);
  222.  
  223.         // Use integral to determine angle since the velocity may be
  224.         // changing and we want to avoid jumps and jerks.
  225.         NumberBvr angle = integral(velocity);
  226.  
  227.         // Arrange along the circle, with different rotational characteristics
  228.         GeometryBvr g1 = make(angle,                            div(angle,toBvr(1.15)), 
  229.                               div(angle,toBvr(1.3)),div(toBvr(Math.PI),toBvr(2)), rg1);
  230.         GeometryBvr g2 = make(div(angle,toBvr(2)),  div(angle,toBvr(1.8)), 
  231.                               angle,                            add(div(toBvr(Math.PI),toBvr(2)), mul(toBvr(2),div(toBvr(Math.PI),toBvr(3)))), rg2);
  232.         GeometryBvr g3 = make(angle,                        div(angle,toBvr(3.2)), 
  233.                               div(angle,toBvr(4)),  add(div(toBvr(Math.PI),toBvr(2)), mul(toBvr(4),div(toBvr(Math.PI),toBvr(3)))), rg3);
  234.                 
  235.         // ... composed into a single result and set into a circular motion
  236.         GeometryBvr circlingGeo = (union(g1,union(g2,g3))).transform(rotate(zVector3, div(localTime,toBvr(10))));
  237.  
  238.         // return the resultant image, also thowing in a light
  239.         return( (union(circlingGeo,directionalLight)).render(theCamera));
  240.  
  241.     }
  242.  
  243.     // takes x,y,z angles, rotation around the containing circle, and an underlying geo, and 
  244.     // the positions the geo accordingly
  245.     GeometryBvr make(NumberBvr xAng, NumberBvr yAng, NumberBvr zAng, NumberBvr rot, GeometryBvr geo)
  246.     {
  247.         NumberBvr radius = toBvr(0.03);
  248.         NumberBvr xXlt   = mul(cos(rot),radius);
  249.         NumberBvr yXlt   = mul(sin(rot),radius);
  250.  
  251.         return(geo.transform(compose(translate(xXlt,yXlt,toBvr(0)),
  252.                                      compose(rotate(xVector3, xAng),
  253.                                              compose(rotate(yVector3, yAng),
  254.                                                      compose(rotate(zVector3, zAng),
  255.                                                              scale3(toBvr(0.01))))))));
  256.     }
  257.  
  258.     // helper function to take an image, texture it onto a transforming geo, render
  259.     // the results, and put it over a background
  260.     ImageBvr textureIt( ImageBvr orig, Transform3Bvr xf, GeometryBvr textureOnto, ImageBvr background)
  261.     {
  262.         GeometryBvr texturedGeo =union((textureOnto.texture(orig.mapToUnitSquare())).transform(xf),
  263.                                        directionalLight);
  264.  
  265.         return(overlay(texturedGeo.render(theCamera), background));
  266.     }
  267.  
  268.     // now create a magnifying image by taking an image, a magnification
  269.     // factor, and a range of coverage...
  270.     ImageBvr magIm(ImageBvr im, NumberBvr magFac, NumberBvr rangePct)
  271.     {
  272.  
  273.  
  274.         // Always follow the mouse, and determine extent based on the range percentage
  275.         Vector2Bvr extent    = sub(point2(0.05,0.05),origin2).mul(toBvr(0.7));
  276.         Vector2Bvr magExtent = extent.mul(rangePct);
  277.  
  278.         // Create a orange-ish background to put the mag image over...this gives
  279.         // the appearance of a border
  280.         Vector2Bvr bkgndExtent = magExtent.mul(toBvr(1.1));
  281.         ImageBvr bkgnd             = solidColorImage(colorRgb(0.8,0.5,0.2)).crop(sub(mousePosition, bkgndExtent),
  282.                                                                                                       add(mousePosition, bkgndExtent));
  283.  
  284.         // Create magnified image by scaling, cropping, and placing over "border" background
  285.         return(overlay(scaleAroundPoint(im,mousePosition, magFac).crop(sub(mousePosition,magExtent),add(mousePosition,magExtent)),
  286.                        bkgnd));
  287.                                           
  288.     }
  289.  
  290.     // scales about a particular point
  291.     ImageBvr scaleAroundPoint(ImageBvr im, Point2Bvr center, NumberBvr magFac)
  292.     {
  293.         return(im.transform(compose(translate(sub(center,origin2)),
  294.                                     compose(scale2(magFac),
  295.                                             translate(sub(origin2,center))))));
  296.     }
  297.  
  298.   // Handle the change the speed, via the mouse buttons
  299.   public Behavior notify(Object eventData,
  300.                          Behavior currentRunningBvr,
  301.                          BvrsToRun blst) {
  302.  
  303.       NumberBvr currentNum = (NumberBvr)currentRunningBvr;
  304.       int increment            = ((Integer)eventData).intValue();     
  305.       NumberBvr newValue   = add(currentNum,toBvr(increment));
  306.       return untilNotify(newValue,changeSpeedEvent,this);
  307.   }
  308.   
  309. }
  310.  
  311.                 
  312. public class Magnify extends DXMApplet {
  313.         public Magnify() { setModel(new MagnifyTest()); }
  314. }
  315.