GRASS Programmer's Manual
6.4.2(2012)
|
00001 00019 #include <stdlib.h> 00020 #include <math.h> 00021 00022 #include <grass/gis.h> 00023 #include <grass/glocale.h> 00024 #include <grass/gstypes.h> 00025 #include <grass/keyframe.h> 00026 #include <grass/kftypes.h> 00027 00028 static float spl3(float, double, double, double, double, double, double, 00029 double); 00030 00031 static float spl3(float tension, double data0, double data1, double x, 00032 double x2, double x3, double lderiv, double rderiv) 00033 { 00034 return ((float) 00035 (data0 * (2 * x3 - 3 * x2 + 1) + data1 * (-2 * x3 + 3 * x2) + 00036 (double)tension * lderiv * (x3 - 2 * x2 + x) + 00037 (double)tension * rderiv * (x3 - x2))); 00038 } 00039 00047 Keylist *gk_copy_key(Keylist * k) 00048 { 00049 Keylist *newk; 00050 int i; 00051 00052 newk = (Keylist *) G_malloc(sizeof(Keylist)); /* G_fatal_error */ 00053 if (!newk) { 00054 return (NULL); 00055 } 00056 00057 for (i = 0; i < KF_NUMFIELDS; i++) { 00058 newk->fields[i] = k->fields[i]; 00059 } 00060 00061 newk->pos = k->pos; 00062 newk->look_ahead = k->look_ahead; 00063 newk->fieldmask = k->fieldmask; 00064 newk->next = newk->prior = NULL; 00065 00066 return (newk); 00067 } 00068 00081 unsigned long gk_get_mask_sofar(float time, Keylist * keys) 00082 { 00083 Keylist *k; 00084 float startpos, endpos, curpos; 00085 unsigned long mask = 0xFFFFFFFF; 00086 00087 if (keys) { 00088 /* find end key */ 00089 for (k = keys; k->next; k = k->next) ; 00090 00091 startpos = keys->pos; 00092 endpos = k->pos; 00093 curpos = startpos + time * (endpos - startpos); 00094 00095 for (k = keys; k->next; k = k->next) { 00096 if (k->pos <= curpos) { 00097 mask &= k->fieldmask; /* (else break) */ 00098 } 00099 } 00100 } 00101 00102 return (mask); 00103 } 00104 00114 int gk_viable_keys_for_mask(unsigned long mask, Keylist * keys, 00115 Keylist ** keyret) 00116 { 00117 Keylist *k; 00118 int cnt = 0; 00119 00120 for (k = keys; k; k = k->next) { 00121 if ((mask & k->fieldmask) == mask) { 00122 keyret[cnt++] = k; 00123 } 00124 } 00125 00126 return (cnt); 00127 } 00128 00143 void gk_follow_frames(Viewnode * view, int numsteps, Keylist * keys, int step, 00144 int onestep, int render, unsigned long mode) 00145 { 00146 Viewnode *v; 00147 int frame; /* frame is index into viewnode array */ 00148 float tmp[3]; 00149 float x, y, z; 00150 int num, w; 00151 unsigned long mask; 00152 00153 for (frame = step - 1; frame < numsteps; frame++) { 00154 00155 v = &view[frame]; 00156 mask = gk_get_mask_sofar((float)frame / numsteps, keys); 00157 00158 /* TODO?: set view field to current settings if not set, 00159 thereby keeping view structure up to date for easier saving of 00160 animation? */ 00161 00162 GS_get_from(tmp); 00163 if ((mask & KF_FROMX_MASK)) { 00164 tmp[X] = v->fields[KF_FROMX]; 00165 } 00166 if ((mask & KF_FROMY_MASK)) { 00167 tmp[Y] = v->fields[KF_FROMY]; 00168 } 00169 if ((mask & KF_FROMZ_MASK)) { 00170 tmp[Z] = v->fields[KF_FROMZ]; 00171 } 00172 00173 GS_moveto(tmp); 00174 00175 GS_get_from(tmp); 00176 G_debug(3, "gk_follow_frames():"); 00177 G_debug(3, " MASK: %lx", mask); 00178 G_debug(3, " FROM: %f %f %f", tmp[X], tmp[Y], tmp[Z]); 00179 00180 /* ACS 1 line: was GS_get_focus(tmp); 00181 with this kanimator works also for flythrough navigation 00182 also changed in GK2.c 00183 */ 00184 GS_get_viewdir(tmp); 00185 if ((mask & KF_DIRX_MASK)) { 00186 tmp[X] = v->fields[KF_DIRX]; 00187 } 00188 if ((mask & KF_DIRY_MASK)) { 00189 tmp[Y] = v->fields[KF_DIRY]; 00190 } 00191 if ((mask & KF_DIRZ_MASK)) { 00192 tmp[Z] = v->fields[KF_DIRZ]; 00193 } 00194 /* ACS 1 line: was GS_set_focus(tmp); 00195 with this kanimator works also for flythrough navigation 00196 also changed in GK2.c 00197 */ 00198 GS_set_viewdir(tmp); 00199 00200 G_debug(3, "gk_follow_frames():"); 00201 GS_get_viewdir(tmp); 00202 G_debug(3, " DIR: %f %f %f\n", tmp[X], tmp[Y], tmp[Z]); 00203 00204 if ((mask & KF_TWIST_MASK)) { 00205 GS_set_twist((int)v->fields[KF_TWIST]); 00206 } 00207 00208 if ((mask & KF_FOV_MASK)) { 00209 GS_set_fov((int)v->fields[KF_FOV]); 00210 } 00211 00212 /* Initilaize lights before drawing */ 00213 num = 1; 00214 GS_getlight_position(num, &x, &y, &z, &w); 00215 GS_setlight_position(num, x, y, z, w); 00216 num = 2; /* Top light */ 00217 GS_setlight_position(num, 0., 0., 1., 0); 00218 00219 if (render) { 00220 GS_set_draw(GSD_FRONT); 00221 } 00222 else { 00223 GS_set_draw(GSD_BACK); 00224 } 00225 00226 GS_ready_draw(); 00227 GS_clear(GS_background_color()); 00228 00229 if (render) { 00230 GS_alldraw_surf(); 00231 } 00232 else { 00233 GS_alldraw_wire(); 00234 } 00235 00236 GS_alldraw_cplane_fences(); 00237 00238 if (mode & FM_PATH) { 00239 gk_draw_path(view, numsteps, keys); 00240 } 00241 00242 if (mode & FM_VECT) { 00243 GV_alldraw_vect(); 00244 } 00245 00246 if (mode & FM_SITE) { 00247 GP_alldraw_site(); 00248 } 00249 00250 if (mode & FM_VOL) { 00251 GVL_alldraw_vol(); 00252 } 00253 00254 GS_done_draw(); 00255 00256 if (mode & FM_LABEL) { 00257 GS_draw_all_list(); /* draw labels and legend */ 00258 } 00259 00260 if (onestep) { 00261 return; 00262 } 00263 } 00264 00265 return; 00266 } 00267 00273 void gk_free_key(Keylist * ok) 00274 { 00275 Keylist *k, *prev; 00276 00277 if (ok) { 00278 k = ok; 00279 while (k) { 00280 prev = k; 00281 k = k->next; 00282 G_free(prev); 00283 } 00284 } 00285 00286 return; 00287 } 00288 00303 Viewnode *gk_make_framesfromkeys(Keylist * keys, int keysteps, int newsteps, 00304 int loop, float t) 00305 { 00306 int i; 00307 Viewnode *v, *newview; 00308 Keylist *k, *kp1, *kp2, *km1, **tkeys; 00309 float startpos, endpos; 00310 double dt1, dt2, x, x2, x3, range, time, time_step, len, rderiv, lderiv; 00311 00312 /* allocate tmp keys to hold valid keys for fields */ 00313 tkeys = (Keylist **) G_malloc(keysteps * sizeof(Keylist *)); /* G_fatal_error */ 00314 if (!tkeys) { 00315 return (NULL); 00316 } 00317 00318 correct_twist(keys); 00319 00320 if (keys && keysteps) { 00321 if (keysteps < 3) { 00322 G_warning(_("Need at least 3 keyframes for spline")); 00323 G_free(tkeys); 00324 return (NULL); 00325 } 00326 00327 /* find end key */ 00328 for (k = keys; k->next; k = k->next) ; 00329 00330 startpos = keys->pos; 00331 endpos = k->pos; 00332 range = endpos - startpos; 00333 time_step = range / (newsteps - 1); 00334 00335 newview = (Viewnode *) G_malloc(newsteps * sizeof(Viewnode)); /* G_fatal_error */ 00336 if (!newview) { /* not used */ 00337 G_free(tkeys); 00338 return (NULL); 00339 } 00340 00341 for (i = 0; i < newsteps; i++) { 00342 int field = 0; 00343 00344 v = &newview[i]; 00345 00346 time = startpos + i * time_step; 00347 00348 if (i == newsteps - 1) { 00349 time = endpos; /*to ensure no roundoff errors */ 00350 } 00351 00352 for (field = 0; field < KF_NUMFIELDS; field++) { 00353 int nvk = 0; /* number of viable keyframes for this field */ 00354 00355 /* now need to do for each field to look at mask */ 00356 k = kp1 = kp2 = km1 = NULL; 00357 nvk = gk_viable_keys_for_mask((unsigned long)(1 << field), 00358 keys, tkeys); 00359 if (nvk) { 00360 len = get_key_neighbors(nvk, time, range, 00361 loop, tkeys, &k, &kp1, &kp2, &km1, 00362 &dt1, &dt2); 00363 } 00364 00365 /* ACS 1 line: was if (len == 0.0) { 00366 when disabling a channel no calculation must be made at all (otherwise core dump) 00367 */ 00368 if (len == 0.0 || nvk == 0) { 00369 if (!k) { 00370 /* none valid - use first. 00371 (when showing , will be ignored anyway) */ 00372 v->fields[field] = keys->fields[field]; 00373 } 00374 else if (!kp1) { 00375 /* none on right - use left */ 00376 v->fields[field] = k->fields[field]; 00377 } 00378 00379 continue; 00380 } 00381 else if (!km1 && !kp2) { 00382 /* only two valid - use linear */ 00383 v->fields[field] = lin_interp((time - k->pos) / len, 00384 k->fields[field], 00385 kp1->fields[field]); 00386 continue; 00387 } 00388 00389 x = (time - k->pos) / len; 00390 x2 = x * x; 00391 x3 = x2 * x; 00392 00393 if (!km1) { 00394 /* leftmost interval */ 00395 rderiv = (kp2->fields[field] - k->fields[field]) / dt2; 00396 lderiv = (3 * (kp1->fields[field] - 00397 k->fields[field]) / dt1 - rderiv) / 2.0; 00398 v->fields[field] = spl3(t, k->fields[field], 00399 kp1->fields[field], x, x2, x3, 00400 lderiv, rderiv); 00401 } 00402 else if (!kp2) { 00403 /* rightmost interval */ 00404 lderiv = (kp1->fields[field] - km1->fields[field]) / dt1; 00405 rderiv = (3 * (kp1->fields[field] - 00406 k->fields[field]) / dt2 - lderiv) / 2.0; 00407 v->fields[field] = spl3(t, k->fields[field], 00408 kp1->fields[field], x, x2, x3, 00409 lderiv, rderiv); 00410 } 00411 else { 00412 /* not on ends */ 00413 lderiv = (kp1->fields[field] - km1->fields[field]) / dt1; 00414 rderiv = (kp2->fields[field] - k->fields[field]) / dt2; 00415 v->fields[field] = spl3(t, k->fields[field], 00416 kp1->fields[field], x, x2, x3, 00417 lderiv, rderiv); 00418 } 00419 } 00420 } 00421 00422 G_free(tkeys); 00423 return (newview); 00424 } 00425 else { 00426 G_free(tkeys); 00427 return (NULL); 00428 } 00429 } 00430 00457 double get_key_neighbors(int nvk, double time, double range, int loop, 00458 Keylist * karray[], Keylist ** km1, Keylist ** kp1, 00459 Keylist ** kp2, Keylist ** km2, double *dt1, 00460 double *dt2) 00461 { 00462 int i; 00463 double len; 00464 00465 *km1 = *kp1 = *kp2 = *km2 = NULL; 00466 *dt1 = *dt2 = 0.0; 00467 00468 for (i = 0; i < nvk; i++) { 00469 if (time < karray[i]->pos) { 00470 break; 00471 } 00472 } 00473 00474 if (!i) { 00475 return (0.0); /* before first keyframe or nvk == 0 */ 00476 } 00477 00478 if (i == nvk) { 00479 /* past or == last keyframe! */ 00480 *km1 = karray[nvk - 1]; 00481 return (0.0); 00482 } 00483 00484 /* there's at least 2 */ 00485 *km1 = karray[i - 1]; 00486 *kp1 = karray[i]; 00487 len = karray[i]->pos - karray[i - 1]->pos; 00488 00489 if (i == 1) { 00490 /* first interval */ 00491 if (loop) { 00492 *km2 = karray[nvk - 2]; 00493 *kp2 = karray[(i + 1) % nvk]; 00494 } 00495 else { 00496 if (nvk > 2) { 00497 *kp2 = karray[i + 1]; 00498 } 00499 } 00500 } 00501 else if (i == nvk - 1) { 00502 /* last interval */ 00503 if (loop) { 00504 *km2 = nvk > 2 ? karray[i - 2] : karray[1]; 00505 *kp2 = karray[1]; 00506 } 00507 else { 00508 if (nvk > 2) { 00509 *km2 = karray[i - 2]; 00510 } 00511 } 00512 } 00513 else { 00514 *km2 = karray[i - 2]; 00515 *kp2 = karray[i + 1]; 00516 } 00517 00518 *dt1 = (*km2) ? (*kp1)->pos - (*km2)->pos : len; 00519 *dt2 = (*kp2) ? (*kp2)->pos - (*km1)->pos : len; 00520 00521 if (i == 1 && loop) { 00522 *dt1 += range; 00523 } 00524 00525 if (i == nvk - 1 && loop) { 00526 *dt2 += range; 00527 } 00528 00529 return (len); 00530 } 00531 00541 double lin_interp(float dt, float val1, float val2) 00542 { 00543 return ((double)(val1 + dt * (val2 - val1))); 00544 } 00545 00560 double get_2key_neighbors(int nvk, float time, float range, int loop, 00561 Keylist * karray[], Keylist ** km1, Keylist ** kp1) 00562 { 00563 int i; 00564 double len; 00565 00566 *km1 = *kp1 = NULL; 00567 00568 for (i = 0; i < nvk; i++) { 00569 if (time < karray[i]->pos) { 00570 break; 00571 } 00572 } 00573 00574 if (!i) { 00575 return (0.0); /* before first keyframe or nvk == 0 */ 00576 } 00577 00578 if (i == nvk) { 00579 /* past or == last keyframe! */ 00580 *km1 = karray[nvk - 1]; 00581 return (0.0); 00582 } 00583 00584 /* there's at least 2 */ 00585 *km1 = karray[i - 1]; 00586 *kp1 = karray[i]; 00587 len = karray[i]->pos - karray[i - 1]->pos; 00588 00589 return (len); 00590 } 00591 00606 Viewnode *gk_make_linear_framesfromkeys(Keylist * keys, int keysteps, 00607 int newsteps, int loop) 00608 { 00609 int i, nvk; 00610 Viewnode *v, *newview; 00611 Keylist *k, *k1, *k2, **tkeys; 00612 float startpos, endpos, dt, range, time, time_step, len; 00613 00614 /* allocate tmp keys to hold valid keys for fields */ 00615 tkeys = (Keylist **) G_malloc(keysteps * sizeof(Keylist *)); /* G_fatal_error */ 00616 if (!tkeys) { 00617 return (NULL); 00618 } 00619 00620 correct_twist(keys); 00621 00622 if (keys && keysteps) { 00623 if (keysteps < 2) { 00624 G_warning(_("Need at least 2 keyframes for interpolation")); 00625 G_free(tkeys); 00626 return (NULL); 00627 } 00628 00629 /* find end key */ 00630 for (k = keys; k->next; k = k->next) ; 00631 00632 startpos = keys->pos; 00633 endpos = k->pos; 00634 range = endpos - startpos; 00635 time_step = range / (newsteps - 1); 00636 00637 newview = (Viewnode *) G_malloc(newsteps * sizeof(Viewnode)); /* G_fatal_error */ 00638 if (!newview) { /* not used */ 00639 G_free(tkeys); 00640 return (NULL); 00641 } 00642 00643 for (i = 0; i < newsteps; i++) { 00644 int field = 0; 00645 00646 v = &newview[i]; 00647 00648 time = startpos + i * time_step; 00649 if (i == newsteps - 1) { 00650 time = endpos; /*to ensure no roundoff errors */ 00651 } 00652 00653 for (field = 0; field < KF_NUMFIELDS; field++) { 00654 00655 nvk = gk_viable_keys_for_mask((unsigned long)(1 << field), 00656 keys, tkeys); 00657 if (!nvk) { 00658 v->fields[field] = keys->fields[field]; /*default-not used */ 00659 } 00660 else { 00661 len = get_2key_neighbors(nvk, time, range, loop, 00662 tkeys, &k1, &k2); 00663 } 00664 00665 /* ACS 1 line: was if (len == 0.0) { 00666 when disabling a channel no calculation must be made at all (otherwise core dump) 00667 */ 00668 if (len == 0.0 || nvk == 0) { 00669 if (!k1) { 00670 /* none valid - use first. 00671 (when showing , will be ignored anyway) */ 00672 v->fields[field] = keys->fields[field]; 00673 } 00674 else if (!k2) { 00675 /* none on right - use left */ 00676 v->fields[field] = k1->fields[field]; 00677 } 00678 } 00679 else { 00680 dt = (time - k1->pos) / len; 00681 v->fields[field] = lin_interp(dt, 00682 k1->fields[field], 00683 k2->fields[field]); 00684 } 00685 } 00686 } 00687 00688 G_free(tkeys); 00689 return (newview); 00690 } 00691 else { 00692 G_free(tkeys); 00693 return (NULL); 00694 } 00695 } 00696 00702 void correct_twist(Keylist * k) 00703 { 00704 Keylist *c, *p, *t; 00705 int cnt, j; 00706 00707 p = NULL; 00708 cnt = 0; 00709 for (c = k; c; c = c->next) { 00710 if (p) { 00711 if ((c->fields[KF_TWIST] - p->fields[KF_TWIST]) > 1800.) { 00712 for (t = c; t; t = t->next) { 00713 t->fields[KF_TWIST] -= 3600.; 00714 } 00715 } 00716 else if ((p->fields[KF_TWIST] - c->fields[KF_TWIST]) > 1800.) { 00717 for (t = k, j = 0; j < cnt; j++, t = t->next) { 00718 t->fields[KF_TWIST] -= 3600.; 00719 } 00720 } 00721 } 00722 00723 p = c; 00724 ++cnt; 00725 } 00726 00727 return; 00728 } 00729 00740 int gk_draw_path(Viewnode * views, int steps, Keylist * keys) 00741 { 00742 Viewnode *v; 00743 Keylist *k; 00744 int frame; 00745 float siz, from[3]; 00746 00747 if (!views || !keys) { 00748 return (0); 00749 } 00750 00751 GS_get_longdim(&siz); 00752 siz /= 200.; 00753 00754 gsd_colormode(CM_COLOR); 00755 gsd_linewidth(2); 00756 gsd_color_func(GS_default_draw_color()); 00757 gsd_zwritemask(0); 00758 00759 gsd_bgnline(); 00760 00761 for (frame = 0; frame < steps; frame++) { 00762 v = &views[frame]; 00763 gsd_vert_func(&(v->fields[KF_FROMX])); 00764 } 00765 00766 gsd_endline(); 00767 00768 gsd_linewidth(1); 00769 00770 00771 for (k = keys; k; k = k->next) { 00772 gsd_x(NULL, &(k->fields[KF_FROMX]), 00773 ~(GS_background_color() | 0xFF0000), siz); 00774 } 00775 00776 /* draw viewer position for inset images */ 00777 GS_get_from(from); 00778 gsd_x(NULL, from, ~(GS_default_draw_color() | 0xFFFF00), 3.0 * siz); 00779 00780 gsd_zwritemask(0xffffffff); 00781 00782 return (1); 00783 }