home *** CD-ROM | disk | FTP | other *** search
- Programmers Guide
-
-
-
-
- 3-D animation, particularily for articulated figures, is
- computationally expensive. Homogenous (4-D) float coordinates are
- required for accuracy and for various perspective and hidden surface
- problems.
-
- In addition 3-D modelling precludes the use of 2-D Bobs for
- animation. Bobs are bitmap objects and cannot be rotated in 3-D. To
- solve the problem of drawing into on-screen areas, double buffering
- can be used.
-
- The following 2 sections detail two Amiga specific techniques for
- dealing with the float calculation problem and the double buffering
- (in Intuition) issue.
-
-
-
- Motorola FFP routines
-
-
- The speed of animation in this program is approximately 1 frame
- per second for a 160 vertex polygonal figure. This includes simple
- hidden surface removal for solid viewing. The use of the Motorola
- 68000 Fast Floating Point routines increased the floating point
- operations by a factor of *_10_*, over the equivalent Lattice C
- floating point routines.
-
- A reasonably elegant way to deal with the "union hack" required
- when calling FFP routines (Lattice wants to convert all float
- function-arguments to double - a form unsuitable for the FFP
- routines) is to immediately convert all input data to FFP and store
- it in Lattice ints. It is not necessary to store floats in a
- float/int union throughout the program, it makes for very messy code.
- All function arguments to FFP routines are henceforth "ints" and all
- values returned by FFP routines are stored in "ints". The actual
- (bits) value stored in the "int" would be unrecognizable to Lattice
- as either integers or floats. No matter. When human readable output
- is required, or integer values for the screen drawing routines are
- required just convert to regular floats with "SPTieee()", or to
- integers with "SPFix()". Internally, swapping back and forth between
- FFP floats and Lattice floats is unneccessary.
-
- The "SPCmp()" routine can be used for "if" comparisons of FFP
- values. Note that 1, -1 or 0 is returned by this function, not just
- "true" and "false".
-
- The Addison-Wesley "RKM Libraries and Devices" p.461, has
- information on FFP trig functions, square roots etc... In particular
- the "SPSincos()" function is very efficient and indispensible for
- fast 3-D transformations.
-
- For more detail on the FFP routines see "Compute!'s Amiga
- Programmer's Guide" by Stephen Levy, p.317, for an introduction, or
- the Addison-Wesley "RKM Libraries and Devices" Chapt. 17. "Math
- Functions".
-
-
- An example in Lattice and it's equivalent in FFP may help. If it
- looks messy remember that order of decimal magnitude speed
- improvements are rare in software and well worth the effort.
-
- /*-----------------------------------------------------------*/
- Lattice:
- float x = 3.8, y = 2.5, z ;
- int j ;
-
- if (x > y) {
- z = x * y + x * x ;
- j = (int) z ;
- }
- /*-----------------------------------------------------------*/
- equivalent FFP:
- float x = 3.8, y = 2.5 ;
- union { /* for transfer of Lattice */
- float f ; /* floats to FFP "floats" */
- int i ;
- } ffp ;
- int a, b, c ; /* really FFP floats */
- int j ; /* j really IS an int */
-
- ffp.f = x ; /* do this once at the */
- a = SPFieee (ffp.i) ; /* start of the program */
- ffp.f = y ; /* for all INPUT floats */
- b = SPFieee (ffp.i) ; /* and float constants */
- /* used in the program */
-
- if (SPCmp (a, b) == 1) {
- c = SPAdd (SPMul (a, b), SPMul (a, a)) ;
- j = SPFix (c) ; /* Lisp-like arithmetic */
- }
- /*-----------------------------------------------------------*/
-
-
-
-
- Double Buffering in Intuition Screens
-
-
- The Amiga is capable of double buffering, but using this feature
- within Intuition is not documented. The advantage of doing it from
- an Intuition screen is of course that windows, menus, requesters, and
- gadgets can be opened on the screen. When the "arm" or "flypast"
- menu items on the Animate menu are selected, the window (a
- GIMMEZEROZERO so that "SetRast()" leaves the borders alone) is closed
- and the double buffered screen is used for the animation. In the
- source code, the "make_screen()" function in m.c and the
- "open_db_screen_for_animation()" routine in anim.c show how to use
- double buffering in an Intuition custom screen.
-
- Basically the procedure is as follows. Allocate memory for 2
- sets of bitplanes, and create a rastport for each. Open a custom
- screen with a custom bitmap and point the CustomBitMap field to the
- address of one of the set of bitplanes. Get a pointer to the
- screen's ViewPort RasInfo structure for future use (ri =
- &screen->ViewPort->RasInfo). If you need temporary drawing areas for
- the graphics routines (AreaInfo, TmpRas etc) both rastports can share
- them.
-
- All drawing is into the 2 rastports you set up. The screen
- rastport is ignored. Set the screen's bitmap to the 1st set of
- bitplanes. Draw into the 2nd set of bitplanes, then swap screen
- bitmaps. Draw into the 1st set of bitmaps (through it's very own
- rastport) while it is off screen. Repeat.
-
- Heres how to swap the bitmaps:
-
- struct Screen *screen ;
- struct BitMap bitmap_1 ;
- struct RasInfo *ri ;
-
- /* assume screen->RastPort.BitMap == &bitmap_2 */
-
- screen->RastPort.BitMap = &bitmap_1 ; /* swap to 1st bitmap */
- ri->BitMap = &bitmap_1 ;
- MakeScreen (screen) ;
- RethinkDisplay () ;
-
- And that's all. Simple, but not obvious.
-