home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / BSP Tree 1.2 / Sources / BSP Tree Demo / source / view.cp < prev   
Encoding:
Text File  |  1995-04-06  |  13.7 KB  |  212 lines  |  [TEXT/MMCC]

  1. //------------------------------------------------------------------------------
  2. //    File:                    view.cp
  3. //    Date:                    9/18/94
  4. //    Author:                Bretton Wade
  5. //
  6. //    Description:    this file contains the class methods for a view of space
  7. //
  8. //------------------------------------------------------------------------------
  9.  
  10. #include    "view.h"
  11. #include    "arcball.h"
  12. #include    "colors.h"
  13. #include    "bsptree_3d.h"
  14.  
  15. //------------------------------------------------------------------------------
  16. //    static variables
  17. //------------------------------------------------------------------------------
  18. view    *view::current = 0;                                                                                                                //    part of the current drawing environment
  19.  
  20. //------------------------------------------------------------------------------
  21. //    constructor
  22. //------------------------------------------------------------------------------
  23. view::view (window *w) : gworld (w),                                                                                        //    view constructor
  24. transformation (matrix_3d::identity),                                                                                        //    matrix_3d constructor
  25. inverse (matrix_3d::identity),                                                                                                    //    matrix_3d constructor
  26. cam (point_3d (R(0.0), R(0.0), R(5.0)), ORIGIN_3D, LensToFOV (50))                            //    camera_3d constructor
  27. {                                                                                                                                                                //    begin
  28.     gui = new arcball (ORIGIN_2D, R(0.95));                                                                                //    make the arcball interface
  29.     eye = cam.Eye ();                                                                                                                            //    assign the untransformed eye point_3d
  30. }                                                                                                                                                                //    end
  31.  
  32. //------------------------------------------------------------------------------
  33. //    destructor
  34. //------------------------------------------------------------------------------
  35. view::~view (void)                                                                                                                            //    destructor
  36. {                                                                                                                                                                //    begin
  37.     delete gui;                                                                                                                                        //    clean up the interface object
  38. }                                                                                                                                                                //    end
  39.  
  40. //------------------------------------------------------------------------------
  41. //    Move the pen to a point
  42. //------------------------------------------------------------------------------
  43. void        view::MoveToPt (const point_2d &vp) const                                                                //    move to a point_2d
  44. {                                                                                                                                                                //    begin
  45.     Point    p = vdctodc (vp);                                                                                                                //    figure out the screen point that corresponds to the desired point
  46.     MoveTo (p.h, p.v);                                                                                                                        //    move the pen there
  47. }                                                                                                                                                                //    end
  48.  
  49. //------------------------------------------------------------------------------
  50. //    Draw a line to a point
  51. //------------------------------------------------------------------------------
  52. void        view::LineToPt (const point_2d &vp) const                                                                //    draw a line to a point_2d
  53. {                                                                                                                                                                //    begin
  54.     Point    p = vdctodc (vp);                                                                                                                //    figure out the screen point that corresponds to the desired point
  55.     LineTo (p.h, p.v);                                                                                                                        //    draw a line there
  56. }                                                                                                                                                                //    end
  57.  
  58. //------------------------------------------------------------------------------
  59. //    Draw a circle
  60. //------------------------------------------------------------------------------
  61. void        view::Circle (const point_2d &a, const point_2d &b) const                                //    draw a circle defined by the rectangle 'ab'
  62. {                                                                                                                                                                //    begin
  63.     Point    p1 = vdctodc (a),                                                                                                                //    figure out the screen location
  64.                 p2 = vdctodc (b);                                                                                                                //    figure out the screen location
  65.     Rect    r;                                                                                                                                            //    a rectangle
  66.     SetRect (&r, p1.h, p2.v, p2.h + 1, p1.v + 1);                                                                    //    set up the rectangle for the oval
  67.     EraseOval (&r);                                                                                                                                //    fill the oval with the background color
  68.     FrameOval (&r);                                                                                                                                //    draw the oval outline
  69. }                                                                                                                                                                //    end
  70.  
  71. //------------------------------------------------------------------------------
  72. //    Draw the cursor crosshair
  73. //------------------------------------------------------------------------------
  74. void        view::CrossHair (const point_2d &vp) const                                                            //    draw a crosshair at the specified location
  75. {                                                                                                                                                                //    begin
  76.     Point    p = vdctodc (vp);                                                                                                                //    figure out the screen location
  77.     MoveTo (p.h - 5, p.v);                                                                                                                //    move to the left
  78.     LineTo (p.h + 5, p.v);                                                                                                                //    line to the right
  79.     MoveTo (p.h, p.v - 5);                                                                                                                //    move to the top
  80.     LineTo (p.h, p.v + 6);                                                                                                                //    line to the bottom
  81. }                                                                                                                                                                //    end
  82.  
  83. //------------------------------------------------------------------------------
  84. //    Draw a polygon
  85. //------------------------------------------------------------------------------
  86. void        view::DrawPolygon (polyptr poly)                                                                                //    draw a polygon (transformed by the camera_3d)
  87. {                                                                                                                                                                //    begin
  88.     if ((eye | poly->Plane ()) > R(0.0))                                                                                    //    if the polygon is not a backface
  89.     {                                                                                                                                                            //    begin
  90.         static    vector_3d light = vector_3d (4, 8, 6).Normalize ();                                    //    lighting vector
  91.         real    shade = (poly->Plane () | light) * 0.8 + 0.2;                                                    //    compute the lighting on this polygon
  92.         if (shade < 0.2) shade = 0.2;                                                                                                //    clamp it to the ambient factor
  93.         if (shade > 1.0) shade = 1.0;                                                                                                //    and no brighter than white
  94.         RGBColor    color;                                                                                                                        //    the screen color
  95.         color.red = color.blue = color.green = 65535.0 * shade;                                            //    set the screen color to be the right shade of grey
  96.         RGBBackColor (&color);                                                                                                            //    set the background color
  97.         PolyHandle    polyh = OpenPoly ();                                                                                        //    get ready to draw the polygon
  98.         point_3d    pt = poly->Vertex (poly->Count () - 1) * viewing;                                    //    compute the screen location of the last point
  99.         MoveToPt (point_2d (pt[X], pt[Y]));                                                                                    //    move there
  100.         for (short i = 0; i < poly->Count (); i++)                                                                    //    for all points
  101.         {                                                                                                                                                        //    begin
  102.             pt = poly->Vertex (i) * viewing;                                                                                    //    compute the screen location
  103.             LineToPt (point_2d (pt[X], pt[Y]));                                                                                //    line to there
  104.         }                                                                                                                                                        //    end
  105.         ClosePoly ();                                                                                                                                //    finished drawing the polygon
  106.         ErasePoly (polyh);                                                                                                                    //    fill it with the computed shade
  107.         FramePoly (polyh);                                                                                                                    //    draw an outline
  108.         KillPoly (polyh);                                                                                                                        //    release the memory
  109.         RGBBackColor (&WHITE);                                                                                                            //    reset the background color to be friendly
  110.     }                                                                                                                                                            //    end
  111. }                                                                                                                                                                //    end
  112.  
  113. //------------------------------------------------------------------------------
  114. //    Draw the whole scene
  115. //------------------------------------------------------------------------------
  116. void        view::DrawScene (void)                                                                                                    //    draw the scene that this view is for
  117. {                                                                                                                                                                //    begin
  118.     viewing = transformation * cam.Transform ();                                                                    //    compute the viewing transformation
  119.     eye = cam.Eye () * inverse;                                                                                                        //    and the eye location
  120.     gui->DrawBackground ();                                                                                                                //    draw the interface background, so it's always there
  121.     extern    bsptree    *world;                                                                                                                //    the world is not defined here...
  122.     world->Draw (eye);                                                                                                                        //    draw the scene
  123. }                                                                                                                                                                //    end
  124.  
  125. //------------------------------------------------------------------------------
  126. //    Handle a mouse down event in the user area
  127. //------------------------------------------------------------------------------
  128. void        view::HandleClick (EventRecord &event)                                                                    //    handle mouse down/up
  129. {                                                                                                                                                                //    begin
  130.     HideCursor ();                                                                                                                                //    prevent flicker of the mouse cursor
  131.     sum = transformation;                                                                                                                    //    copy the transformation
  132.     gui->Click (dctovdc (event.where));                                                                                        //    tell the interface object about the click
  133.     Point    last_pt;                                                                                                                                //    place store the current location of the mouse
  134.     do                                                                                                                                                        //    loop
  135.     {                                                                                                                                                            //    begin
  136.         GetMouse (&event.where);                                                                                                        //    check the current mouse location
  137.         if (*(long *) &(event.where) != *(long *) &(last_pt))                                                //    if the mouse has moved
  138.         {                                                                                                                                                        //    begin
  139.             transformation = sum * gui->Drag (dctovdc (event.where));                                    //    set up the current transformation
  140.             inverse = transformation.Inverse ();                                                                            //    compute its inverse
  141.             StartDrawing ();                                                                                                                    //    prepare the offscreen drawing world
  142.             //gui->DrawBackground ();                                                                                                    //    draw the interface background
  143.             DrawScene ();                                                                                                                            //    draw the scene
  144.             gui->DrawForeground ();                                                                                                        //    draw the interface foreground
  145.             StopDrawing ();                                                                                                                        //    clean up the offscreen drawing world and update the screen
  146.         }                                                                                                                                                        //    end
  147.         last_pt = event.where;                                                                                                            //    copy the current mouse location
  148.     }                                                                                                                                                            //    end
  149.     while (StillDown ());                                                                                                                    //    loop until the user releases the mouse button
  150.     StartDrawing ();                                                                                                                            //    prepare the offscreen drawing world
  151.     DrawScene ();                                                                                                                                    //    draw the image
  152.     StopDrawing ();                                                                                                                                //    clean up the offscreen drawing world and update the screen
  153.     ShowCursor ();                                                                                                                                //    give the user back the cursor
  154. }                                                                                                                                                                //    end
  155.  
  156. //------------------------------------------------------------------------------
  157. //    Change the size of the user area
  158. //------------------------------------------------------------------------------
  159. void        view::Resize (EventRecord &event)                                                                                //    recompute sizing information from parent
  160. {                                                                                                                                                                //    begin
  161.     gworld::Resize (event);                                                                                                                //    default behavior
  162.     Rect    rect = (*region)->rgnBBox;                                                                                            //    temporary to simplify code
  163.     real    width = rect.right - rect.left,                                                                                    //    compute the width of the window
  164.                 height = rect.bottom - rect.top;                                                                                //    compute the hight of the window
  165.     ysize = height / R(2.0);                                                                                                            //    compute the y halfsize
  166.     xsize = width / R(2.0);                                                                                                                //    compute the x halfsize
  167.     aspect = (width > height) ? ysize : xsize;                                                                        //    set the aspect to be the smaller of the two
  168.     StartDrawing ();                                                                                                                            //    set up the drawing environment
  169.     DrawScene ();                                                                                                                                    //    redraw the image
  170.     StopDrawing (DONT_UPDATE);                                                                                                        //    reset the drawing environment
  171. }                                                                                                                                                                //    end
  172.  
  173. //------------------------------------------------------------------------------
  174. //    convert a screen location to the range (-1..1, -1..1)
  175. //------------------------------------------------------------------------------
  176. point_2d        view::dctovdc (const Point &p) const                                                                //    map screen coordinates to virtual device coordinates
  177. {                                                                                                                                                                //    begin
  178.     short    x = p.h - (*region)->rgnBBox.left,                                                                            //    adjust the location to the edge of the view
  179.                 y = p.v - (*region)->rgnBBox.top;                                                                                //    adjust the location to the edge of the view
  180.     return point_2d ((x - xsize) / aspect, (y - ysize) / -aspect);                                //    return the converted point_3d
  181. }                                                                                                                                                                //    end
  182.  
  183. //------------------------------------------------------------------------------
  184. //    convert a point in the range (-1..1, -1..1) to a screen coordinate
  185. //------------------------------------------------------------------------------
  186. Point        view::vdctodc (const point_2d &p) const                                                                    //    map virtual device coordinates to screen coordinates
  187. {                                                                                                                                                                //    begin
  188.     Point    pt;                                                                                                                                            //    storage for the return value
  189.     pt.h = (short) ((p[X] * aspect) + xsize);                                                                            //    convert the x coordinate to screen coordinates
  190.     pt.v = (short) ((p[Y] * -aspect) + ysize);                                                                        //    convert the y coordinate to screen coordinates
  191.     return pt;                                                                                                                                        //    return the converted point_3d
  192. }                                                                                                                                                                //    end
  193.  
  194. //------------------------------------------------------------------------------
  195. //    start drawing to the gworld
  196. //------------------------------------------------------------------------------
  197. void        view::StartDrawing (gw_erase e)                                                                                    //    lock down the gworld and set the port appropriately
  198. {                                                                                                                                                                //    begin
  199.     current = this;                                                                                                                                //    set the current drawing world
  200.     gworld::StartDrawing (e);                                                                                                            //    do the parental thing
  201. }                                                                                                                                                                //    end
  202.  
  203. //------------------------------------------------------------------------------
  204. //    stop drawing to the gworld
  205. //------------------------------------------------------------------------------
  206. void        view::StopDrawing (gw_update u)                                                                                    //    unlock the gworld and reset the port
  207. {                                                                                                                                                                //    begin
  208.     current = 0;                                                                                                                                    //    make sure the current drawing world is empty
  209.     gworld::StopDrawing (u);                                                                                                            //    do the parental thing
  210. }                                                                                                                                                                //    end
  211.  
  212. //------------------------------------------------------------------------------