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