home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////
- // BLOBDRAW.POC V 1.1 //
- // Animated Blob Generator for Autodesk Animator Pro. //
- // (c) 1994 James P. Hawkins //
- // 18 Marlpit Pl. //
- // Middletown, NJ 07748 //
- // //
- // See "3D Artist", issue #14 PP. 41-42 //
- // "Introduction to Blobs" by Alfonso Hermida //
- // //
- /////////////////////////////////////////////////////////////
-
- #pragma poco library "pdracces.poe" // extended picture I/O library
- #pragma poco stacksize 32k
- #include <errcodes.h>
-
- #define MAXBLOBS 100
-
- int color,
- numcol, // Screen width in pixels
- numrow, // Screen height in pixels
- curframe, // Current frame
- skip = 1.0, // Set skip > 1.0 for faster spaced out pixel plot
- num_frames, // Total number of frames
- color_mode = 1, // Color exponential gradient if default
- old_color_idx; // To save previous color
-
- // Blob space is 8 X 6 with 0 at center
-
- double xmin = -4.0,
- ymin = -3.0,
- xmax = 4.0,
- ymax = 3.0,
- threshold = 0.5;
-
-
- FILE *fp;
-
- ///////////////////////////////////////////////////////////////////
- // BLOB DATUM
- // x, y is the center in BLOB space (-4 < x < 4, -3 < y < 3)
- // dx, dy are the amount x and y are incremented or decremented
- // for motion to the next frame, they will be 0 if the blob is
- // stationary.
- // radius is the blob radius in BLOB space units
- // and strength is the max strength at the blob center.
- ///////////////////////////////////////////////////////////////////
-
- typedef struct {
- double x,y; // Center of blob
- double dx, dy; // animation motion deltas
- double radius, strength;
- } BLOB;
-
- BLOB blobs[MAXBLOBS];
- int bnum; // Blob number
-
- // Function prototypes
- void blobdemo(void);
- void blobinc(void);
- int blobinfo(void);
- void GrayPaletteInit(void);
-
- ////////////////////////////////////////////////////
- // MENUS
- char main_header[] = "Main menu";
- int main_choice;
- char *main_choices[] = {
- "CREATE BLOB SCENE",
- "DEMO",
- };
-
- enum {
- MAIN_DEMO,
- MAIN_BLOB_INFO,
- };
-
- //////////////////////////////////////////////////
- // MAIN //
- //////////////////////////////////////////////////
-
- main()
- {
-
- double r, t, x, y, temp;
- int i, j, k;
-
- int max_strength; // The highest strength possible (for color calc)
-
- GetPhysicalSize(&numcol, &numrow); // Get the screen res from anipro
-
- num_frames = GetFrameCount(); // Get number of frames available
-
- old_color_idx = GetColor(); // Save old color index
-
- // Display the main menu and act on the choice
- main_choice = Qmenu(main_choices, 2, main_header);
- switch (main_choice)
- {
- case MAIN_DEMO:
- blobdemo();
- break;
- case MAIN_BLOB_INFO:
- if(!blobinfo())
- return;
- }
-
- for(curframe = 1; curframe <= num_frames; curframe++)
- {
- Clear(); // clear screen
- printf("Generating frame %d of %d.", curframe, num_frames);
-
- for(j = 0;j <= numrow; j += skip) {
- y = j * (ymax - ymin) / numrow + ymin;
- for(i = 0; i <= numcol; i += skip) {
- x = i * (xmax - xmin) / numcol + xmin;
- t = 0.0;
- // Add the combined strengths of the blobs at this point
- for(k = 0; k < bnum; k++) {
-
- // Calculate distance from blob center
- r = sqrt((x - blobs[k].x) * (x - blobs[k].x) +
- (y - blobs[k].y) * (y - blobs[k].y));
- //
- // If distance is within blob radius calculate 't'
- // from: t = strength(1 - (r/radius)^2)^2
- //
- if( r <= blobs[k].radius ) {
- temp = r / blobs[k].radius;
- temp *= temp;
- temp = 1.0 - temp;
- temp *= temp;
- t += blobs[k].strength * temp;
- }
- }
-
- //
- // If the combined strength at this coordinate exceeds
- // the threshold, plot a point.
- // If color mode is on, the color is a function of
- // the strength, based on 256 color palette.
- //
- if (t >= threshold) {
- switch(color_mode) {
- case 0:
- color = GetColor();
- break;
- case 1:
- color = 255 * (1 - exp(-t));
- if(t == threshold) color /= 4;
- break;
- case 2:
- color = 255 * exp(-t);
- break;
- case 3:
- color = t * 255;
- if(color > 255)
- color = 255;
- break;
- case 4:
- // Calculate maximum possible strength for use
- // in computing color index
- for(k = 0, max_strength = 0.0; k < bnum; k++)
- max_strength += blobs[k].strength;
-
- color = ((int)((t/max_strength) * 255) % 255);
- break;
- case 5:
- color = t * 255;
- break;
-
- }
- SetColor(color);
- Dot(i, j);
- }
- }
- }
- NextFrame();
- blobinc();
- }
- SetColor(old_color_idx);
- unprintf();
- }
-
- ////////////////////////////////////////////////////////////
- // MOVE ALL BLOBS FOR NEXT FRAME
- //
-
- void blobinc(void)
- {
-
- int k;
-
- for(k = 0; k < bnum; k++)
- {
- blobs[k].x += blobs[k].dx;
- blobs[k].y += blobs[k].dy;
- }
- }
-
-
- //////////////////////////////
- // BLOB MENU DEFINITIONS //
- //////////////////////////////
- //
- int blob_choice = -1;
- char blob_header[] = "BLOB DATA ENTRY";
- char *blob_choices[] = {
- "Add A Blob",
- "Set Threshold Index (default = 5)",
- "Set Color Mode",
- "Set Palette to Grayscale",
- "GO!",
- };
-
- enum {
- BLOB_GO,
- BLOB_ADD_BLOB,
- BLOB_SET_THRESH,
- BLOB_SET_COLOR_MODE,
- BLOB_GRAY,
- };
-
- double tenths[21] = {-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2,
- -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0};
-
- ////////////////////////////////////////////////////////////////////////
- // ENTER YOUR OWN BLOB ANIMATION DATA
- //
- int blobinfo(void)
- {
-
- int i1, j1, i2, j2, radius, threshindex = 5, strengthindex = 10;
- double x1, x2, y1, y2;
- int go_flag = 0;
- int old_red, old_green, old_blue;
- int old_filled;
-
- #ifdef DEBUG
- fp = fopen("pdump.txt", "w");
- #endif
- // Temporarily put WHITE in index 1 and use it for
- // the blob placement and path, restore the old color in
- // index 1 when done.
- SetColor(1);
- GetColorMap(1, &old_red, &old_green, &old_blue);
- SetColorMap(1, 255, 255, 255);
- //
- // Temporarily set to NON-FILLED mode to make the
- // BLOB outlines and paths easier to see.
- //
- old_filled = GetFilled();
- SetFilled(0);
-
- bnum = 0;
-
- while (blob_choice != BLOB_GO)
- {
- blob_choice = Qmenu(blob_choices, 5, blob_header);
-
- switch (blob_choice)
- {
- case BLOB_GO:
- go_flag++;
- break;
- case BLOB_SET_THRESH:
- Qnumber(&threshindex, 0, 10, "SET THRESHOLD INDEX");
- threshold = tenths[threshindex + 10];
- break;
- case BLOB_SET_COLOR_MODE:
- Qnumber(&color_mode, 0, 5, "SET COLOR MODE");
- break;
- case BLOB_GRAY:
- GrayPaletteInit();
- GetColorMap(1, &old_red, &old_green, &old_blue);
- SetColorMap(1, 255, 255, 255);
- break;
- case BLOB_ADD_BLOB:
- if(RubCircle(&i1, &j1, &radius)) // Get center and radius
- Circle(i1, j1, radius); // Draw a circle
- else
- return(0);
-
- if(!RubLine(i1, j1, &i2, &j2)) { // Get motion path
- i2 = i1;
- j2 = j1;
- }
- Line(i1, j1, i2, j2); // Draw the path
- y1 = (double)j1 * (ymax - ymin) / numrow + ymin;
- y2 = (double)j2 * (ymax - ymin) / numrow + ymin;
- x1 = (double)i1 * (xmax - xmin) / numcol + xmin;
- x2 = (double)i2 * (xmax - xmin) / numcol + xmin;
-
- strengthindex = 10;
- Qnumber(&strengthindex, -10, 10, "SET BLOB STRENGTH INDEX");
- strengthindex += 10;
-
- blobs[bnum].x = x1;
- blobs[bnum].y = y1;
- blobs[bnum].radius = (double)radius * (ymax - ymin) / numrow;
- blobs[bnum].strength = tenths[strengthindex];
- blobs[bnum].dx = (x2 - x1) / num_frames;
- blobs[bnum].dy = (y2 - y1) / num_frames;
- bnum++;
- #ifdef DEBUG
- fprintf(fp,"\nblobs[%d].x = %f\n", bnum, blobs[bnum].x);
- fprintf(fp,"blobs[%d].y = %f\n", bnum, blobs[bnum].y);
- fprintf(fp,"blobs[%d].radius = %f\n", bnum, blobs[bnum].radius);
- fprintf(fp,"blobs[%d].strength = %f\n", bnum, blobs[bnum].strength);
- fprintf(fp,"blobs[%d].dx = %f\n", bnum, blobs[bnum].dx);
- fprintf(fp,"blobs[%d].dy = %f\n\n", bnum, blobs[bnum].dy);
- #endif
- break;
- }
- if(go_flag){
- break;
- }
-
- }
- #ifdef debug
- fprintf(fp,"\nbnum = %d\n", bnum);
- fclose(fp);
- #endif
- // Restore old color in index 1 and old filled mode.
- SetFilled(old_filled);
- SetColorMap(1, old_red, old_green, old_blue);
- if(!color_mode)
- SetColor(old_color_idx);
- return(1);
- }
-
- /////////////////////////////////////////////////////////////
- // DEMONSTRATION
- //
-
- void blobdemo(void)
- {
- //
- // DEMO BLOBS
- //
- // define blob #1
- blobs[0].x = -3.0;
- blobs[0].y = 0;
- blobs[0].radius = 1.0;
- blobs[0].strength = 1.0;
- blobs[0].dx = 0.25;
- blobs[0].dy = 0.0;
-
- // define blob #2
- blobs[1].x = -1.375;
- blobs[1].y = 0.64952;
- blobs[1].radius = 1.0;
- blobs[1].strength = 1.0;
- blobs[1].dx = 0.0;
- blobs[1].dy = 0.0;
-
- // define blob #3
- blobs[2].x = -1.375;
- blobs[2].y = -0.64952;
- blobs[2].radius = 1.0;
- blobs[2].strength = 1.0;
- blobs[2].dx = 0.0;
- blobs[2].dy = 0.0;
-
- // define blob #4
- blobs[3].x = 0.625;
- blobs[3].y = 0.64952;
- blobs[3].radius = 1.0;
- blobs[3].strength = 1.0;
- blobs[3].dx = 0.0;
- blobs[3].dy = 0.0;
-
- // define blob #5
- blobs[4].x = 0.625;
- blobs[4].y = -0.64952;
- blobs[4].radius = 1.0;
- blobs[4].strength = 1.0;
- blobs[4].dx = 0.0;
- blobs[4].dy = 0.0;
-
- // define blob #6
- blobs[5].x = 2.625;
- blobs[5].y = 0.64952;
- blobs[5].radius = 1.0;
- blobs[5].strength = 1.0;
- blobs[5].dx = 0.0;
- blobs[5].dy = 0.0;
-
- // define blob #7
- blobs[6].x = 2.625;
- blobs[6].y = -0.64952;
- blobs[6].radius = 1.0;
- blobs[6].strength = 1.0;
- blobs[6].dx = 0.0;
- blobs[6].dy = 0.0;
-
- bnum = 7;
- color_mode = 4;
- }
-
-
-
-
- //////////////////////////////////////////////////////////////////////////
- //
- //
- void GrayPaletteInit(void)
- {
-
- int index;
- int Palette_Map[256][3];
-
- for (index = 0; index < 256; index++)
- {
-
- // Gray Gradient
- Palette_Map[index][0] = index;
- Palette_Map[index][1] = index;
- Palette_Map[index][2] = index;
- }
-
- // Set the palette for all frames, then reset to the first frame
- SetFrame(0);
- for(curframe = 1; curframe <= num_frames; curframe++) {
- SetScreenColorMap(GetPicScreen(), &Palette_Map[0][0]);
- NextFrame();
- }
- SetFrame(0);
-
- }
-
-