home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 021.lha / robot / prgmr.doc < prev    next >
Text File  |  1986-11-10  |  6KB  |  143 lines

  1.                            Programmers Guide
  2.  
  3.  
  4.  
  5.  
  6.    3-D animation, particularily for articulated figures, is
  7. computationally expensive.  Homogenous (4-D) float coordinates are
  8. required for accuracy and for various perspective and hidden surface
  9. problems.  
  10.  
  11.    In addition 3-D modelling precludes the use of 2-D Bobs for
  12. animation.  Bobs are bitmap objects and cannot be rotated in 3-D.  To
  13. solve the problem of drawing into on-screen areas, double buffering
  14. can be used.
  15.  
  16.    The following 2 sections detail two Amiga specific techniques for
  17. dealing with the float calculation problem and the double buffering
  18. (in Intuition) issue.
  19.  
  20.  
  21.  
  22.                        Motorola FFP routines
  23.  
  24.                         
  25.    The speed of animation in this program is approximately 1 frame
  26. per second for a 160 vertex polygonal figure.  This includes simple
  27. hidden surface removal for solid viewing.  The use of the Motorola
  28. 68000 Fast Floating Point routines increased the floating point
  29. operations by a factor of *_10_*, over the equivalent Lattice C
  30. floating point routines. 
  31.  
  32.     A reasonably elegant way to deal with the "union hack" required
  33. when calling FFP routines (Lattice wants to convert all float
  34. function-arguments to double - a form unsuitable for the FFP
  35. routines) is to immediately convert all input data to FFP and store
  36. it in Lattice ints.  It is not necessary to store floats in a
  37. float/int union throughout the program, it makes for very messy code.
  38. All function arguments to FFP routines are henceforth "ints" and all
  39. values returned by FFP routines are stored in "ints".  The actual
  40. (bits) value stored in the "int" would be unrecognizable to Lattice
  41. as either integers or floats.  No matter.  When human readable output
  42. is required, or integer values for the screen drawing routines are
  43. required just convert to regular floats with "SPTieee()", or to
  44. integers with "SPFix()".  Internally, swapping back and forth between
  45. FFP floats and Lattice floats is unneccessary. 
  46.  
  47.     The "SPCmp()" routine can be used for "if" comparisons of FFP
  48. values.  Note that 1, -1 or 0 is returned by this function, not just
  49. "true" and "false". 
  50.  
  51.     The Addison-Wesley "RKM Libraries and Devices" p.461, has
  52. information on FFP trig functions, square roots etc... In particular
  53. the "SPSincos()" function is very efficient and indispensible for
  54. fast 3-D transformations. 
  55.  
  56.     For more detail on the FFP routines see "Compute!'s Amiga
  57. Programmer's Guide" by Stephen Levy, p.317, for an introduction, or
  58. the Addison-Wesley "RKM Libraries and Devices" Chapt. 17. "Math
  59. Functions".
  60.  
  61.  
  62.     An example in Lattice and it's equivalent in FFP may help. If it
  63. looks messy remember that order of decimal magnitude speed
  64. improvements are rare in software and well worth the effort.
  65.  
  66.      /*-----------------------------------------------------------*/
  67.      Lattice:
  68.                 float  x = 3.8,  y = 2.5,  z ;
  69.                 int  j ;
  70.  
  71.                 if (x > y)  {
  72.                     z  = x * y  +  x * x ;
  73.                     j  = (int) z ;
  74.                 }
  75.      /*-----------------------------------------------------------*/ 
  76.      equivalent FFP:   
  77.                 float  x = 3.8,  y = 2.5 ;
  78.                 union  {              /* for transfer of Lattice */
  79.                          float  f ;   /* floats to FFP "floats" */
  80.                          int    i ;
  81.                        }  ffp ;
  82.                 int  a,  b,  c ;      /* really FFP floats */
  83.                 int  j ;              /* j really IS an int */
  84.                 
  85.                 ffp.f  = x ;             /* do this once at the */
  86.                 a  = SPFieee (ffp.i) ;   /* start of the program */
  87.                 ffp.f  = y ;             /* for all INPUT floats */
  88.                 b  = SPFieee (ffp.i) ;   /* and float constants */
  89.                                          /* used in the program */
  90.  
  91.                 if (SPCmp (a, b) == 1)  { 
  92.                    c  = SPAdd (SPMul (a, b), SPMul (a, a)) ;
  93.                    j  = SPFix (c) ;       /* Lisp-like arithmetic */
  94.                 }
  95.      /*-----------------------------------------------------------*/
  96.  
  97.  
  98.  
  99.  
  100.                  Double Buffering in Intuition Screens
  101.  
  102.  
  103.     The Amiga is capable of double buffering, but using this feature
  104. within Intuition is not documented.  The advantage of doing it from
  105. an Intuition screen is of course that windows, menus, requesters, and
  106. gadgets can be opened on the screen.  When the "arm" or "flypast"
  107. menu items on the Animate menu are selected, the window (a
  108. GIMMEZEROZERO so that "SetRast()" leaves the borders alone) is closed
  109. and the double buffered screen is used for the animation.  In the
  110. source code, the "make_screen()" function in m.c and the
  111. "open_db_screen_for_animation()" routine in anim.c show how to use
  112. double buffering in an Intuition custom screen.
  113.  
  114.     Basically the procedure is as follows.  Allocate memory for 2
  115. sets of bitplanes, and create a rastport for each.  Open a custom
  116. screen with a custom bitmap and point the CustomBitMap field to the
  117. address of one of the set of bitplanes.  Get a pointer to the
  118. screen's ViewPort RasInfo structure for future use (ri  =
  119. &screen->ViewPort->RasInfo).  If you need temporary drawing areas for
  120. the graphics routines (AreaInfo, TmpRas etc) both rastports can share
  121. them. 
  122.  
  123.    All drawing is into the 2 rastports you set up.  The screen
  124. rastport is ignored.  Set the screen's bitmap to the 1st set of
  125. bitplanes.  Draw into the 2nd set of bitplanes, then swap screen
  126. bitmaps.  Draw into the 1st set of bitmaps (through it's very own
  127. rastport) while it is off screen.  Repeat.
  128.  
  129.    Heres how to swap the bitmaps:
  130.  
  131.    struct Screen  *screen ;
  132.    struct BitMap  bitmap_1 ;
  133.    struct RasInfo  *ri ;
  134.    
  135.    /* assume screen->RastPort.BitMap == &bitmap_2 */
  136.    
  137.    screen->RastPort.BitMap  = &bitmap_1 ;   /* swap to 1st bitmap */
  138.    ri->BitMap  = &bitmap_1 ;
  139.    MakeScreen (screen) ;
  140.    RethinkDisplay () ;     
  141.  
  142.    And that's all.  Simple, but not obvious.
  143.