GRASS Programmer's Manual  6.4.2(2012)
GK2.c
Go to the documentation of this file.
00001 
00019 #include <stdlib.h>
00020 
00021 #include <grass/gis.h>
00022 #include <grass/glocale.h>
00023 #include <grass/gstypes.h>
00024 #include <grass/keyframe.h>
00025 #include <grass/kftypes.h>
00026 
00027 
00028 static int _add_key(Keylist *, int, float);
00029 static void _remove_key(Keylist *);
00030 
00031 static Keylist *Keys = NULL;
00032 static Keylist *Keytail = NULL;
00033 static Viewnode *Views = NULL;
00034 static float Keystartpos = 0.0;
00035 static float Keyendpos = 1.0;
00036 static float Tension = 0.8;
00037 static int Viewsteps = 0;
00038 static int Numkeys = 0;
00039 static int Interpmode = KF_SPLINE;
00040 static int Fmode = 0;
00041 
00042 /* next & prior already initialized to NULL */
00043 static int _add_key(Keylist * newk, int force_replace, float precis)
00044 {
00045     Keylist *k, *tempk, *prev;
00046     int found;
00047 
00048     found = 0;
00049     prev = NULL;
00050 
00051     /* if(Viewsteps) precis = 0.5/Viewsteps; */
00052     for (k = Keys; k; k = k->next) {
00053         if (k->pos >= newk->pos - precis && k->pos <= newk->pos + precis) {
00054             if (force_replace) {
00055 
00056                 if (k->prior) {
00057                     k->prior->next = newk;
00058                     newk->prior = prev;
00059                 }
00060                 else {
00061                     Keys = newk;
00062                 }
00063 
00064                 newk->next = k->next;
00065                 newk->prior = k->prior;
00066                 tempk = k;
00067                 k = newk;
00068                 free(tempk);
00069             }
00070             else {
00071                 free(newk);
00072             }
00073 
00074             return (-1);
00075         }
00076     }
00077 
00078     if (Keys) {
00079         if (newk->pos < Keys->pos) {
00080             /* new will be first */
00081             newk->next = Keys;
00082             Keys->prior = newk;
00083             Keys = newk;
00084         }
00085         else {
00086             prev = k = Keys;
00087             while (k && !found) {
00088                 if (k->pos > newk->pos) {
00089                     prev->next = newk;
00090                     newk->next = k;
00091                     newk->prior = prev;
00092                     k->prior = newk;
00093                     found = 1;
00094                 }
00095 
00096                 prev = k;
00097                 k = k->next;
00098             }
00099             if (!found) {
00100                 Keytail = prev->next = newk;
00101                 newk->prior = prev;
00102             }
00103         }
00104     }
00105     else {
00106         Keys = Keytail = newk;
00107     }
00108 
00109     ++Numkeys;
00110     return (1);
00111 }
00112 
00113 static void _remove_key(Keylist * k)
00114 {
00115     if (k->prior) {
00116         k->prior->next = k->next;
00117         if (k->next) {
00118             k->next->prior = k->prior;
00119         }
00120         else {
00121             Keytail = k->prior;
00122         }
00123     }
00124     else {
00125         Keys = k->next;
00126         if (k->next) {
00127             k->next->prior = NULL;
00128         }
00129     }
00130     k->next = k->prior = NULL;
00131 
00132     return;
00133 }
00134 
00143 int GK_set_interpmode(int mode)
00144 {
00145     if (KF_LEGAL_MODE(mode)) {
00146         Interpmode = mode;
00147         return (1);
00148     }
00149 
00150     return (-1);
00151 }
00152 
00158 void GK_set_tension(float tens)
00159 {
00160     Tension = tens > 1.0 ? 1.0 : (tens < 0.0 ? 0.0 : tens);
00161 
00162     /* for now */
00163     if (Views) {
00164         GK_update_frames();
00165         GS_set_draw(GSD_BACK);
00166         GS_ready_draw();
00167         GS_clear(GS_background_color());
00168         GS_alldraw_wire();
00169 
00170         gk_draw_path(Views, Viewsteps, Keys);
00171 
00172         GS_done_draw();
00173     }
00174 
00175     return;
00176 }
00177 
00178 void GK_showtension_start(void)
00179 {
00180     return;
00181 }
00182 
00190 void GK_showtension_stop(void)
00191 {
00192     return;
00193 }
00194 
00198 void GK_update_tension(void)
00199 {
00200     if (Views) {
00201         GK_update_frames();
00202     }
00203 
00204     return;
00205 }
00206 
00212 void GK_print_keys(const char *name)
00213 {
00214     Keylist *k;
00215     FILE *fp;
00216     int cnt = 1;
00217 
00218     if (NULL == (fp = fopen(name, "w"))) {
00219         G_fatal_error(_("Unable to open file <%s> for writing"), name);
00220     }
00221     /* write a default frame rate of 30 at top of file */
00222     fprintf(fp, "30 \n");
00223 
00224     for (k = Keys; k; k = k->next) {
00225 
00226         fprintf(fp,
00227                 "{%f {{FromX %f} {FromY %f} {FromZ %f} {DirX %f} {DirY %f} {DirZ %f} {FOV %f} {TWIST %f} {cplane-0 {{pos_x 0.000000} {pos_y 0.000000} {pos_z 0.000000} {blend_type OFF} {rot 0.000000} {tilt 0.000000}}}} keyanimtag%d 0} ",
00228                 k->pos, k->fields[KF_FROMX], k->fields[KF_FROMY],
00229                 k->fields[KF_FROMZ], k->fields[KF_DIRX], k->fields[KF_DIRY],
00230                 k->fields[KF_DIRZ], k->fields[KF_FOV] / 10.,
00231                 k->fields[KF_TWIST], cnt);
00232         cnt++;
00233     }
00234 
00235     fclose(fp);
00236     return;
00237 
00238 }
00239 
00246 void GK_update_frames(void)
00247 {
00248     Keylist *k;
00249     int loop = 0;
00250 
00251     if (Keys) {
00252         if (Numkeys > 1) {
00253             k = Keytail;
00254             Keyendpos = k->pos;
00255 
00256             if (k->fields[KF_FROMX] == Keys->fields[KF_FROMX] &&
00257                 k->fields[KF_FROMY] == Keys->fields[KF_FROMY] &&
00258                 k->fields[KF_FROMZ] == Keys->fields[KF_FROMZ]) {
00259                 loop = 1;
00260             }
00261         }
00262 
00263         Keystartpos = Keys->pos;
00264     }
00265 
00266     if (Interpmode == KF_LINEAR && Numkeys > 1) {
00267         if (Views) {
00268             free(Views);
00269             Views = NULL;
00270         }
00271 
00272         Views = gk_make_linear_framesfromkeys(Keys, Numkeys, Viewsteps, loop);
00273 
00274         if (!Views) {
00275             G_warning(_("Check no. of frames requested and keyframes marked"));
00276         }
00277     }
00278     else if (Numkeys > 2) {
00279         if (Views) {
00280             free(Views);
00281             Views = NULL;
00282         }
00283 
00284         Views = gk_make_framesfromkeys
00285             (Keys, Numkeys, Viewsteps, loop, 1.0 - Tension);
00286 
00287         if (!Views) {
00288             G_warning(_("Check no. of frames requested and keyframes marked"));
00289         }
00290     }
00291 
00292     return;
00293 }
00294 
00300 void GK_set_numsteps(int newsteps)
00301 {
00302     Viewsteps = newsteps;
00303     GK_update_frames();
00304 
00305     return;
00306 }
00307 
00313 void GK_clear_keys(void)
00314 {
00315     gk_free_key(Keys);
00316     Keys = NULL;
00317     Numkeys = 0;
00318     free(Views);
00319     Views = NULL;
00320 
00321     Keystartpos = 0.0;
00322     Keyendpos = 1.0;
00323 
00324     return;
00325 }
00326 
00339 int GK_move_key(float oldpos, float precis, float newpos)
00340 {
00341     Keylist *k;
00342 
00343     for (k = Keys; k; k = k->next) {
00344         if (k->pos >= oldpos - precis && k->pos <= oldpos + precis) {
00345             _remove_key(k);
00346             k->pos = newpos;
00347             _add_key(k, 1, precis);
00348             GK_update_frames();
00349             return (1);
00350         }
00351     }
00352 
00353     return (0);
00354 }
00355 
00370 int GK_delete_key(float pos, float precis, int justone)
00371 {
00372     Keylist *k, *next;
00373     int cnt;
00374 
00375     for (cnt = 0, k = Keys; k;) {
00376         next = k->next;
00377 
00378         if (k->pos >= pos - precis && k->pos <= pos + precis) {
00379             cnt++;
00380             _remove_key(k);
00381             free(k);
00382             if (justone) {
00383                 break;
00384             }
00385         }
00386 
00387         k = next;
00388     }
00389 
00390     GK_update_frames();
00391     return (cnt);
00392 }
00393 
00432 int GK_add_key(float pos, unsigned long fmask, int force_replace,
00433                float precis)
00434 {
00435     Keylist *newk;
00436     float tmp[3];
00437 
00438     if (NULL == (newk = (Keylist *) malloc(sizeof(Keylist)))) {
00439         fprintf(stderr, "Out of memory\n");
00440         return (-1);
00441     }
00442 
00443     /* All fields set, don't use mask until making Views */
00444 
00445     GS_get_from(tmp);
00446     newk->fields[KF_FROMX] = tmp[X];
00447     newk->fields[KF_FROMY] = tmp[Y];
00448     newk->fields[KF_FROMZ] = tmp[Z];
00449 
00450     G_debug(3, "KEY FROM: %f %f %f", tmp[X], tmp[Y], tmp[Z]);
00451 
00452     /* Instead of View Dir try get_focus (view center) */
00453     /* View Dir is implied from eye and center position */
00454     /*    GS_get_viewdir(tmp); */
00455 
00456     /* ACS 1 line: was      GS_get_focus(tmp);
00457        with this kanimator works also for flythrough navigation
00458        also changed in gk.c
00459      */
00460     GS_get_viewdir(tmp);
00461     newk->fields[KF_DIRX] = tmp[X];
00462     newk->fields[KF_DIRY] = tmp[Y];
00463     newk->fields[KF_DIRZ] = tmp[Z];
00464 
00465     newk->fields[KF_FOV] = GS_get_fov();
00466     newk->fields[KF_TWIST] = GS_get_twist();
00467     newk->pos = pos;
00468     newk->fieldmask = fmask;
00469     newk->next = NULL;
00470     newk->prior = NULL;
00471 
00472     if (0 < _add_key(newk, force_replace, precis)) {
00473         GK_update_frames();
00474         return (1);
00475     }
00476 
00477     return (-1);
00478 }
00479 
00489 void GK_do_framestep(int step, int render)
00490 {
00491     if (Views) {
00492         if (step > 0 && step <= Viewsteps) {
00493             gk_follow_frames(Views, Viewsteps, Keys, step, 1, render, Fmode);
00494         }
00495     }
00496 
00497     return;
00498 }
00499 
00505 void GK_show_path(int flag)
00506 {
00507     if (flag) {
00508         Fmode |= FM_PATH;
00509 
00510         if (Views) {
00511             GS_set_draw(GSD_FRONT);
00512             GS_ready_draw();
00513 
00514             gk_draw_path(Views, Viewsteps, Keys);
00515 
00516             GS_done_draw();
00517 
00518         }
00519     }
00520     else {
00521         Fmode &= ~FM_PATH;
00522     }
00523 
00524     return;
00525 }
00526 
00532 void GK_show_vect(int flag)
00533 {
00534     if (flag) {
00535         Fmode |= FM_VECT;
00536         if (Views) {
00537 
00538             GS_set_draw(GSD_FRONT);
00539             GS_ready_draw();
00540 
00541             GV_alldraw_vect();
00542 
00543             GS_done_draw();
00544         }
00545     }
00546     else {
00547         Fmode &= ~FM_VECT;
00548     }
00549 
00550     return;
00551 }
00552 
00558 void GK_show_site(int flag)
00559 {
00560     if (flag) {
00561         Fmode |= FM_SITE;
00562 
00563         if (Views) {
00564 
00565             GS_set_draw(GSD_FRONT);
00566             GS_ready_draw();
00567 
00568             GP_alldraw_site();
00569 
00570             GS_done_draw();
00571 
00572         }
00573     }
00574     else {
00575         Fmode &= ~FM_SITE;
00576     }
00577 
00578     return;
00579 }
00580 
00586 void GK_show_vol(int flag)
00587 {
00588     if (flag) {
00589         Fmode |= FM_VOL;
00590 
00591         if (Views) {
00592 
00593             GS_set_draw(GSD_FRONT);
00594             GS_ready_draw();
00595 
00596             GVL_alldraw_vol();
00597 
00598             GS_done_draw();
00599 
00600         }
00601     }
00602     else {
00603         Fmode &= ~FM_VOL;
00604     }
00605 
00606     return;
00607 }
00608 
00614 void GK_show_list(int flag)
00615 {
00616     if (flag) {
00617         Fmode |= FM_LABEL;
00618 
00619         if (Views) {
00620             GS_draw_all_list();
00621         }
00622     }
00623     else {
00624         Fmode &= ~FM_LABEL;
00625     }
00626 
00627     return;
00628 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines