GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gk.c
Go to the documentation of this file.
1 
19 #include <stdlib.h>
20 #include <math.h>
21 
22 #include <grass/gis.h>
23 #include <grass/glocale.h>
24 #include <grass/gstypes.h>
25 #include <grass/keyframe.h>
26 #include <grass/kftypes.h>
27 
28 static float spl3(float, double, double, double, double, double, double,
29  double);
30 
31 static float spl3(float tension, double data0, double data1, double x,
32  double x2, double x3, double lderiv, double rderiv)
33 {
34  return ((float)
35  (data0 * (2 * x3 - 3 * x2 + 1) + data1 * (-2 * x3 + 3 * x2) +
36  (double)tension * lderiv * (x3 - 2 * x2 + x) +
37  (double)tension * rderiv * (x3 - x2)));
38 }
39 
47 Keylist *gk_copy_key(Keylist * k)
48 {
49  Keylist *newk;
50  int i;
51 
52  newk = (Keylist *) G_malloc(sizeof(Keylist)); /* G_fatal_error */
53  if (!newk) {
54  return (NULL);
55  }
56 
57  for (i = 0; i < KF_NUMFIELDS; i++) {
58  newk->fields[i] = k->fields[i];
59  }
60 
61  newk->pos = k->pos;
62  newk->look_ahead = k->look_ahead;
63  newk->fieldmask = k->fieldmask;
64  newk->next = newk->prior = NULL;
65 
66  return (newk);
67 }
68 
81 unsigned long gk_get_mask_sofar(float time, Keylist * keys)
82 {
83  Keylist *k;
84  float startpos, endpos, curpos;
85  unsigned long mask = 0xFFFFFFFF;
86 
87  if (keys) {
88  /* find end key */
89  for (k = keys; k->next; k = k->next) ;
90 
91  startpos = keys->pos;
92  endpos = k->pos;
93  curpos = startpos + time * (endpos - startpos);
94 
95  for (k = keys; k->next; k = k->next) {
96  if (k->pos <= curpos) {
97  mask &= k->fieldmask; /* (else break) */
98  }
99  }
100  }
101 
102  return (mask);
103 }
104 
114 int gk_viable_keys_for_mask(unsigned long mask, Keylist * keys,
115  Keylist ** keyret)
116 {
117  Keylist *k;
118  int cnt = 0;
119 
120  for (k = keys; k; k = k->next) {
121  if ((mask & k->fieldmask) == mask) {
122  keyret[cnt++] = k;
123  }
124  }
125 
126  return (cnt);
127 }
128 
143 void gk_follow_frames(Viewnode * view, int numsteps, Keylist * keys, int step,
144  int onestep, int render, unsigned long mode)
145 {
146  Viewnode *v;
147  int frame; /* frame is index into viewnode array */
148  float tmp[3];
149  float x, y, z;
150  int num, w;
151  unsigned long mask;
152 
153  for (frame = step - 1; frame < numsteps; frame++) {
154 
155  v = &view[frame];
156  mask = gk_get_mask_sofar((float)frame / numsteps, keys);
157 
158  /* TODO?: set view field to current settings if not set,
159  thereby keeping view structure up to date for easier saving of
160  animation? */
161 
162  GS_get_from(tmp);
163  if ((mask & KF_FROMX_MASK)) {
164  tmp[X] = v->fields[KF_FROMX];
165  }
166  if ((mask & KF_FROMY_MASK)) {
167  tmp[Y] = v->fields[KF_FROMY];
168  }
169  if ((mask & KF_FROMZ_MASK)) {
170  tmp[Z] = v->fields[KF_FROMZ];
171  }
172 
173  GS_moveto(tmp);
174 
175  GS_get_from(tmp);
176  G_debug(3, "gk_follow_frames():");
177  G_debug(3, " MASK: %lx", mask);
178  G_debug(3, " FROM: %f %f %f", tmp[X], tmp[Y], tmp[Z]);
179 
180  /* ACS 1 line: was GS_get_focus(tmp);
181  with this kanimator works also for flythrough navigation
182  also changed in GK2.c
183  */
184  GS_get_viewdir(tmp);
185  if ((mask & KF_DIRX_MASK)) {
186  tmp[X] = v->fields[KF_DIRX];
187  }
188  if ((mask & KF_DIRY_MASK)) {
189  tmp[Y] = v->fields[KF_DIRY];
190  }
191  if ((mask & KF_DIRZ_MASK)) {
192  tmp[Z] = v->fields[KF_DIRZ];
193  }
194  /* ACS 1 line: was GS_set_focus(tmp);
195  with this kanimator works also for flythrough navigation
196  also changed in GK2.c
197  */
198  GS_set_viewdir(tmp);
199 
200  G_debug(3, "gk_follow_frames():");
201  GS_get_viewdir(tmp);
202  G_debug(3, " DIR: %f %f %f\n", tmp[X], tmp[Y], tmp[Z]);
203 
204  if ((mask & KF_TWIST_MASK)) {
205  GS_set_twist((int)v->fields[KF_TWIST]);
206  }
207 
208  if ((mask & KF_FOV_MASK)) {
209  GS_set_fov((int)v->fields[KF_FOV]);
210  }
211 
212  /* Initilaize lights before drawing */
213  num = 1;
214  GS_getlight_position(num, &x, &y, &z, &w);
215  GS_setlight_position(num, x, y, z, w);
216  num = 2; /* Top light */
217  GS_setlight_position(num, 0., 0., 1., 0);
218 
219  if (render) {
220  GS_set_draw(GSD_FRONT);
221  }
222  else {
223  GS_set_draw(GSD_BACK);
224  }
225 
226  GS_ready_draw();
228 
229  if (render) {
230  GS_alldraw_surf();
231  }
232  else {
233  GS_alldraw_wire();
234  }
235 
237 
238  if (mode & FM_PATH) {
239  gk_draw_path(view, numsteps, keys);
240  }
241 
242  if (mode & FM_VECT) {
243  GV_alldraw_vect();
244  }
245 
246  if (mode & FM_SITE) {
247  GP_alldraw_site();
248  }
249 
250  if (mode & FM_VOL) {
251  GVL_alldraw_vol();
252  }
253 
254  GS_done_draw();
255 
256  if (mode & FM_LABEL) {
257  GS_draw_all_list(); /* draw labels and legend */
258  }
259 
260  if (onestep) {
261  return;
262  }
263  }
264 
265  return;
266 }
267 
273 void gk_free_key(Keylist * ok)
274 {
275  Keylist *k, *prev;
276 
277  if (ok) {
278  k = ok;
279  while (k) {
280  prev = k;
281  k = k->next;
282  G_free(prev);
283  }
284  }
285 
286  return;
287 }
288 
303 Viewnode *gk_make_framesfromkeys(Keylist * keys, int keysteps, int newsteps,
304  int loop, float t)
305 {
306  int i;
307  Viewnode *v, *newview;
308  Keylist *k, *kp1, *kp2, *km1, **tkeys;
309  float startpos, endpos;
310  double dt1, dt2, x, x2, x3, range, time, time_step, len, rderiv, lderiv;
311 
312  /* allocate tmp keys to hold valid keys for fields */
313  tkeys = (Keylist **) G_malloc(keysteps * sizeof(Keylist *)); /* G_fatal_error */
314  if (!tkeys) {
315  return (NULL);
316  }
317 
318  correct_twist(keys);
319 
320  if (keys && keysteps) {
321  if (keysteps < 3) {
322  G_warning(_("Need at least 3 keyframes for spline"));
323  G_free(tkeys);
324  return (NULL);
325  }
326 
327  /* find end key */
328  for (k = keys; k->next; k = k->next) ;
329 
330  startpos = keys->pos;
331  endpos = k->pos;
332  range = endpos - startpos;
333  time_step = range / (newsteps - 1);
334 
335  newview = (Viewnode *) G_malloc(newsteps * sizeof(Viewnode)); /* G_fatal_error */
336  if (!newview) { /* not used */
337  G_free(tkeys);
338  return (NULL);
339  }
340 
341  for (i = 0; i < newsteps; i++) {
342  int field = 0;
343 
344  v = &newview[i];
345 
346  time = startpos + i * time_step;
347 
348  if (i == newsteps - 1) {
349  time = endpos; /*to ensure no roundoff errors */
350  }
351 
352  for (field = 0; field < KF_NUMFIELDS; field++) {
353  int nvk = 0; /* number of viable keyframes for this field */
354 
355  /* now need to do for each field to look at mask */
356  k = kp1 = kp2 = km1 = NULL;
357  nvk = gk_viable_keys_for_mask((unsigned long)(1 << field),
358  keys, tkeys);
359  if (nvk) {
360  len = get_key_neighbors(nvk, time, range,
361  loop, tkeys, &k, &kp1, &kp2, &km1,
362  &dt1, &dt2);
363  }
364 
365  /* ACS 1 line: was if (len == 0.0) {
366  when disabling a channel no calculation must be made at all (otherwise core dump)
367  */
368  if (len == 0.0 || nvk == 0) {
369  if (!k) {
370  /* none valid - use first.
371  (when showing , will be ignored anyway) */
372  v->fields[field] = keys->fields[field];
373  }
374  else if (!kp1) {
375  /* none on right - use left */
376  v->fields[field] = k->fields[field];
377  }
378 
379  continue;
380  }
381  else if (!km1 && !kp2) {
382  /* only two valid - use linear */
383  v->fields[field] = lin_interp((time - k->pos) / len,
384  k->fields[field],
385  kp1->fields[field]);
386  continue;
387  }
388 
389  x = (time - k->pos) / len;
390  x2 = x * x;
391  x3 = x2 * x;
392 
393  if (!km1) {
394  /* leftmost interval */
395  rderiv = (kp2->fields[field] - k->fields[field]) / dt2;
396  lderiv = (3 * (kp1->fields[field] -
397  k->fields[field]) / dt1 - rderiv) / 2.0;
398  v->fields[field] = spl3(t, k->fields[field],
399  kp1->fields[field], x, x2, x3,
400  lderiv, rderiv);
401  }
402  else if (!kp2) {
403  /* rightmost interval */
404  lderiv = (kp1->fields[field] - km1->fields[field]) / dt1;
405  rderiv = (3 * (kp1->fields[field] -
406  k->fields[field]) / dt2 - lderiv) / 2.0;
407  v->fields[field] = spl3(t, k->fields[field],
408  kp1->fields[field], x, x2, x3,
409  lderiv, rderiv);
410  }
411  else {
412  /* not on ends */
413  lderiv = (kp1->fields[field] - km1->fields[field]) / dt1;
414  rderiv = (kp2->fields[field] - k->fields[field]) / dt2;
415  v->fields[field] = spl3(t, k->fields[field],
416  kp1->fields[field], x, x2, x3,
417  lderiv, rderiv);
418  }
419  }
420  }
421 
422  G_free(tkeys);
423  return (newview);
424  }
425  else {
426  G_free(tkeys);
427  return (NULL);
428  }
429 }
430 
457 double get_key_neighbors(int nvk, double time, double range, int loop,
458  Keylist * karray[], Keylist ** km1, Keylist ** kp1,
459  Keylist ** kp2, Keylist ** km2, double *dt1,
460  double *dt2)
461 {
462  int i;
463  double len;
464 
465  *km1 = *kp1 = *kp2 = *km2 = NULL;
466  *dt1 = *dt2 = 0.0;
467 
468  for (i = 0; i < nvk; i++) {
469  if (time < karray[i]->pos) {
470  break;
471  }
472  }
473 
474  if (!i) {
475  return (0.0); /* before first keyframe or nvk == 0 */
476  }
477 
478  if (i == nvk) {
479  /* past or == last keyframe! */
480  *km1 = karray[nvk - 1];
481  return (0.0);
482  }
483 
484  /* there's at least 2 */
485  *km1 = karray[i - 1];
486  *kp1 = karray[i];
487  len = karray[i]->pos - karray[i - 1]->pos;
488 
489  if (i == 1) {
490  /* first interval */
491  if (loop) {
492  *km2 = karray[nvk - 2];
493  *kp2 = karray[(i + 1) % nvk];
494  }
495  else {
496  if (nvk > 2) {
497  *kp2 = karray[i + 1];
498  }
499  }
500  }
501  else if (i == nvk - 1) {
502  /* last interval */
503  if (loop) {
504  *km2 = nvk > 2 ? karray[i - 2] : karray[1];
505  *kp2 = karray[1];
506  }
507  else {
508  if (nvk > 2) {
509  *km2 = karray[i - 2];
510  }
511  }
512  }
513  else {
514  *km2 = karray[i - 2];
515  *kp2 = karray[i + 1];
516  }
517 
518  *dt1 = (*km2) ? (*kp1)->pos - (*km2)->pos : len;
519  *dt2 = (*kp2) ? (*kp2)->pos - (*km1)->pos : len;
520 
521  if (i == 1 && loop) {
522  *dt1 += range;
523  }
524 
525  if (i == nvk - 1 && loop) {
526  *dt2 += range;
527  }
528 
529  return (len);
530 }
531 
541 double lin_interp(float dt, float val1, float val2)
542 {
543  return ((double)(val1 + dt * (val2 - val1)));
544 }
545 
560 double get_2key_neighbors(int nvk, float time, float range, int loop,
561  Keylist * karray[], Keylist ** km1, Keylist ** kp1)
562 {
563  int i;
564  double len;
565 
566  *km1 = *kp1 = NULL;
567 
568  for (i = 0; i < nvk; i++) {
569  if (time < karray[i]->pos) {
570  break;
571  }
572  }
573 
574  if (!i) {
575  return (0.0); /* before first keyframe or nvk == 0 */
576  }
577 
578  if (i == nvk) {
579  /* past or == last keyframe! */
580  *km1 = karray[nvk - 1];
581  return (0.0);
582  }
583 
584  /* there's at least 2 */
585  *km1 = karray[i - 1];
586  *kp1 = karray[i];
587  len = karray[i]->pos - karray[i - 1]->pos;
588 
589  return (len);
590 }
591 
606 Viewnode *gk_make_linear_framesfromkeys(Keylist * keys, int keysteps,
607  int newsteps, int loop)
608 {
609  int i, nvk;
610  Viewnode *v, *newview;
611  Keylist *k, *k1, *k2, **tkeys;
612  float startpos, endpos, dt, range, time, time_step, len;
613 
614  /* allocate tmp keys to hold valid keys for fields */
615  tkeys = (Keylist **) G_malloc(keysteps * sizeof(Keylist *)); /* G_fatal_error */
616  if (!tkeys) {
617  return (NULL);
618  }
619 
620  correct_twist(keys);
621 
622  if (keys && keysteps) {
623  if (keysteps < 2) {
624  G_warning(_("Need at least 2 keyframes for interpolation"));
625  G_free(tkeys);
626  return (NULL);
627  }
628 
629  /* find end key */
630  for (k = keys; k->next; k = k->next) ;
631 
632  startpos = keys->pos;
633  endpos = k->pos;
634  range = endpos - startpos;
635  time_step = range / (newsteps - 1);
636 
637  newview = (Viewnode *) G_malloc(newsteps * sizeof(Viewnode)); /* G_fatal_error */
638  if (!newview) { /* not used */
639  G_free(tkeys);
640  return (NULL);
641  }
642 
643  for (i = 0; i < newsteps; i++) {
644  int field = 0;
645 
646  v = &newview[i];
647 
648  time = startpos + i * time_step;
649  if (i == newsteps - 1) {
650  time = endpos; /*to ensure no roundoff errors */
651  }
652 
653  for (field = 0; field < KF_NUMFIELDS; field++) {
654 
655  nvk = gk_viable_keys_for_mask((unsigned long)(1 << field),
656  keys, tkeys);
657  if (!nvk) {
658  v->fields[field] = keys->fields[field]; /*default-not used */
659  }
660  else {
661  len = get_2key_neighbors(nvk, time, range, loop,
662  tkeys, &k1, &k2);
663  }
664 
665  /* ACS 1 line: was if (len == 0.0) {
666  when disabling a channel no calculation must be made at all (otherwise core dump)
667  */
668  if (len == 0.0 || nvk == 0) {
669  if (!k1) {
670  /* none valid - use first.
671  (when showing , will be ignored anyway) */
672  v->fields[field] = keys->fields[field];
673  }
674  else if (!k2) {
675  /* none on right - use left */
676  v->fields[field] = k1->fields[field];
677  }
678  }
679  else {
680  dt = (time - k1->pos) / len;
681  v->fields[field] = lin_interp(dt,
682  k1->fields[field],
683  k2->fields[field]);
684  }
685  }
686  }
687 
688  G_free(tkeys);
689  return (newview);
690  }
691  else {
692  G_free(tkeys);
693  return (NULL);
694  }
695 }
696 
702 void correct_twist(Keylist * k)
703 {
704  Keylist *c, *p, *t;
705  int cnt, j;
706 
707  p = NULL;
708  cnt = 0;
709  for (c = k; c; c = c->next) {
710  if (p) {
711  if ((c->fields[KF_TWIST] - p->fields[KF_TWIST]) > 1800.) {
712  for (t = c; t; t = t->next) {
713  t->fields[KF_TWIST] -= 3600.;
714  }
715  }
716  else if ((p->fields[KF_TWIST] - c->fields[KF_TWIST]) > 1800.) {
717  for (t = k, j = 0; j < cnt; j++, t = t->next) {
718  t->fields[KF_TWIST] -= 3600.;
719  }
720  }
721  }
722 
723  p = c;
724  ++cnt;
725  }
726 
727  return;
728 }
729 
740 int gk_draw_path(Viewnode * views, int steps, Keylist * keys)
741 {
742  Viewnode *v;
743  Keylist *k;
744  int frame;
745  float siz, from[3];
746 
747  if (!views || !keys) {
748  return (0);
749  }
750 
751  GS_get_longdim(&siz);
752  siz /= 200.;
753 
754  gsd_colormode(CM_COLOR);
755  gsd_linewidth(2);
757  gsd_zwritemask(0);
758 
759  gsd_bgnline();
760 
761  for (frame = 0; frame < steps; frame++) {
762  v = &views[frame];
763  gsd_vert_func(&(v->fields[KF_FROMX]));
764  }
765 
766  gsd_endline();
767 
768  gsd_linewidth(1);
769 
770 
771  for (k = keys; k; k = k->next) {
772  gsd_x(NULL, &(k->fields[KF_FROMX]),
773  ~(GS_background_color() | 0xFF0000), siz);
774  }
775 
776  /* draw viewer position for inset images */
777  GS_get_from(from);
778  gsd_x(NULL, from, ~(GS_default_draw_color() | 0xFFFF00), 3.0 * siz);
779 
780  gsd_zwritemask(0xffffffff);
781 
782  return (1);
783 }
void gsd_zwritemask(unsigned long n)
Write out z-mask.
Definition: gsd_prim.c:231
void GS_set_fov(int fov)
Set field of view.
Definition: GS2.c:2841
void gk_free_key(Keylist *ok)
Free keyframe list.
Definition: gk.c:273
void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos, int *local)
Get light position.
Definition: GS2.c:335
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
unsigned long gk_get_mask_sofar(float time, Keylist *keys)
Get mask value.
Definition: gk.c:81
double lin_interp(float dt, float val1, float val2)
Linear interpolation.
Definition: gk.c:541
DCELL val1
Definition: g3dcats.c:91
void GS_done_draw(void)
Draw done, swap buffers.
Definition: GS2.c:2499
void GS_get_from(float *fr)
Get viewpoint &#39;from&#39; position.
Definition: GS2.c:2723
long num
Definition: g3dcats.c:93
Viewnode * gk_make_framesfromkeys(Keylist *keys, int keysteps, int newsteps, int loop, float t)
Generate viewnode from keyframes.
Definition: gk.c:303
#define Y(x)
Definition: display/draw.c:246
tuple pos
Definition: tools.py:1367
void gsd_colormode(int cm)
Set color mode.
Definition: gsd_prim.c:88
void correct_twist(Keylist *k)
Correct twist value.
Definition: gk.c:702
#define X(y)
Definition: display/draw.c:248
void gsd_color_func(unsigned int col)
Set current color.
Definition: gsd_prim.c:689
int y
Definition: plot.c:34
void GS_clear(int col)
Clear view.
Definition: GS2.c:3416
void GP_alldraw_site(void)
Draw all available point sets.
Definition: GP2.c:557
unsigned int GS_background_color(void)
Get background color.
Definition: GS2.c:2447
void GV_alldraw_vect(void)
Draw all vector sets.
Definition: GV2.c:444
void gsd_x(geosurf *gs, float *center, int colr, float siz)
ADD.
Definition: gsd_objs.c:279
int gk_draw_path(Viewnode *views, int steps, Keylist *keys)
Draw path.
Definition: gk.c:740
DCELL val2
Definition: g3dcats.c:91
Viewnode * gk_make_linear_framesfromkeys(Keylist *keys, int keysteps, int newsteps, int loop)
Generate viewnode from keyframe list (linear interpolation)
Definition: gk.c:606
void GS_draw_all_list(void)
Draw all glLists.
Definition: GS2.c:876
double get_key_neighbors(int nvk, double time, double range, int loop, Keylist *karray[], Keylist **km1, Keylist **kp1, Keylist **kp2, Keylist **km2, double *dt1, double *dt2)
Find interval containing time.
Definition: gk.c:457
void gsd_endline(void)
End line.
Definition: gsd_prim.c:397
int gk_viable_keys_for_mask(unsigned long mask, Keylist *keys, Keylist **keyret)
ADD.
Definition: gk.c:114
void GS_set_viewdir(float *dir)
Set viewdir.
Definition: GS2.c:2821
void GVL_alldraw_vol(void)
Draw all volume sets.
Definition: GVL2.c:398
void GS_alldraw_surf(void)
Draw all surfaces.
Definition: GS2.c:1933
void gk_follow_frames(Viewnode *view, int numsteps, Keylist *keys, int step, int onestep, int render, unsigned long mode)
Checks key masks.
Definition: gk.c:143
void GS_moveto(float *pt)
Move viewpoint.
Definition: GS2.c:2615
void GS_alldraw_wire(void)
Draw all wires.
Definition: GS2.c:1916
void gsd_vert_func(float *pt)
ADD.
Definition: gsd_prim.c:677
void GS_set_twist(int t)
Set viewpoint twist value.
Definition: GS2.c:2875
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void GS_get_viewdir(float *dir)
Get viewdir.
Definition: GS2.c:2807
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition: gsd_prim.c:257
int GS_get_longdim(float *dim)
Get largest dimension.
Definition: GS2.c:140
tuple range
Definition: tools.py:1406
void GS_ready_draw(void)
Definition: GS2.c:2486
double get_2key_neighbors(int nvk, float time, float range, int loop, Keylist *karray[], Keylist **km1, Keylist **kp1)
Finds interval containing time, putting left (or equal) key at km1, right at kp1. ...
Definition: gk.c:560
unsigned int GS_default_draw_color(void)
Get default draw color.
Definition: GS2.c:2434
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:387
Keylist * gk_copy_key(Keylist *k)
Copy keyframes.
Definition: gk.c:47
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition: GS2.c:2457
void GS_setlight_position(int num, float xpos, float ypos, float zpos, int local)
Set light position.
Definition: GS2.c:309
void GS_alldraw_cplane_fences(void)
Draw all cplace fences ?
Definition: GS2.c:3193
tuple mode
Definition: tools.py:1481