GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
gk.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gk.c
3 
4  \brief OGSF library - setting and manipulating keyframes animation (lower level functions)
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  (C) 1999-2008 by the GRASS Development Team
9 
10  This program is free software under the
11  GNU General Public License (>=v2).
12  Read the file COPYING that comes with GRASS
13  for details.
14 
15  \author Bill Brown USACERL, GMSL/University of Illinois
16  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17  */
18 
19 #include <stdlib.h>
20 #include <math.h>
21 
22 #include <grass/gis.h>
23 #include <grass/glocale.h>
24 #include <grass/ogsf.h>
25 
26 static float spl3(float, double, double, double, double, double, double,
27  double);
28 
29 static float spl3(float tension, double data0, double data1, double x,
30  double x2, double x3, double lderiv, double rderiv)
31 {
32  return ((float)
33  (data0 * (2 * x3 - 3 * x2 + 1) + data1 * (-2 * x3 + 3 * x2) +
34  (double)tension * lderiv * (x3 - 2 * x2 + x) +
35  (double)tension * rderiv * (x3 - x2)));
36 }
37 
38 /*!
39  \brief Copy keyframes
40 
41  \param k source keyframes
42 
43  \return pointer to Keylist struct (target)
44  */
46 {
47  Keylist *newk;
48  int i;
49 
50  newk = (Keylist *) G_malloc(sizeof(Keylist)); /* G_fatal_error */
51  if (!newk) {
52  return (NULL);
53  }
54 
55  for (i = 0; i < KF_NUMFIELDS; i++) {
56  newk->fields[i] = k->fields[i];
57  }
58 
59  newk->pos = k->pos;
60  newk->look_ahead = k->look_ahead;
61  newk->fieldmask = k->fieldmask;
62  newk->next = newk->prior = NULL;
63 
64  return (newk);
65 }
66 
67 /*!
68  \brief Get mask value
69 
70  Get begin & end pos, AND all masks in keys <= pos
71 
72  Time must be between 0.0 & 1.0
73 
74  \param time timestamp
75  \param keys list of keyframes
76 
77  \return mask value
78  */
79 unsigned long gk_get_mask_sofar(float time, Keylist * keys)
80 {
81  Keylist *k;
82  float startpos, endpos, curpos;
83  unsigned long mask = 0xFFFFFFFF;
84 
85  if (keys) {
86  /* find end key */
87  for (k = keys; k->next; k = k->next) ;
88 
89  startpos = keys->pos;
90  endpos = k->pos;
91  curpos = startpos + time * (endpos - startpos);
92 
93  for (k = keys; k->next; k = k->next) {
94  if (k->pos <= curpos) {
95  mask &= k->fieldmask; /* (else break) */
96  }
97  }
98  }
99 
100  return (mask);
101 }
102 
103 /*!
104  \brief ADD
105 
106  \param mask mask value
107  \param keys list of keyframes
108  \param[out] keyret output list of keyframes
109 
110  \return number of output keyframes
111  */
112 int gk_viable_keys_for_mask(unsigned long mask, Keylist * keys,
113  Keylist ** keyret)
114 {
115  Keylist *k;
116  int cnt = 0;
117 
118  for (k = keys; k; k = k->next) {
119  if ((mask & k->fieldmask) == mask) {
120  keyret[cnt++] = k;
121  }
122  }
123 
124  return (cnt);
125 }
126 
127 /*!
128  \brief Checks key masks
129 
130  Because if they're masked up until the current position,
131  pre-existing (or current) field should be used.
132 
133  \param view pointer to Viewmode struct
134  \param numsteps number of steps
135  \param keys list of keyframes
136  \param step step value
137  \param onestep
138  \param render
139  \param mode
140  */
141 void gk_follow_frames(Viewnode * view, int numsteps, Keylist * keys, int step,
142  int onestep, int render, unsigned long mode)
143 {
144  Viewnode *v;
145  int frame; /* frame is index into viewnode array */
146  float tmp[3];
147  float x, y, z;
148  int num, w;
149  unsigned long mask;
150 
151  for (frame = step - 1; frame < numsteps; frame++) {
152 
153  v = &view[frame];
154  mask = gk_get_mask_sofar((float)frame / numsteps, keys);
155 
156  /* TODO?: set view field to current settings if not set,
157  thereby keeping view structure up to date for easier saving of
158  animation? */
159 
160  GS_get_from(tmp);
161  if ((mask & KF_FROMX_MASK)) {
162  tmp[X] = v->fields[KF_FROMX];
163  }
164  if ((mask & KF_FROMY_MASK)) {
165  tmp[Y] = v->fields[KF_FROMY];
166  }
167  if ((mask & KF_FROMZ_MASK)) {
168  tmp[Z] = v->fields[KF_FROMZ];
169  }
170 
171  GS_moveto(tmp);
172 
173  GS_get_from(tmp);
174  G_debug(3, "gk_follow_frames():");
175  G_debug(3, " MASK: %lx", mask);
176  G_debug(3, " FROM: %f %f %f", tmp[X], tmp[Y], tmp[Z]);
177 
178  /* ACS 1 line: was GS_get_focus(tmp);
179  with this kanimator works also for flythrough navigation
180  also changed in GK2.c
181  */
182  GS_get_viewdir(tmp);
183  if ((mask & KF_DIRX_MASK)) {
184  tmp[X] = v->fields[KF_DIRX];
185  }
186  if ((mask & KF_DIRY_MASK)) {
187  tmp[Y] = v->fields[KF_DIRY];
188  }
189  if ((mask & KF_DIRZ_MASK)) {
190  tmp[Z] = v->fields[KF_DIRZ];
191  }
192  /* ACS 1 line: was GS_set_focus(tmp);
193  with this kanimator works also for flythrough navigation
194  also changed in GK2.c
195  */
196  GS_set_viewdir(tmp);
197 
198  G_debug(3, "gk_follow_frames():");
199  GS_get_viewdir(tmp);
200  G_debug(3, " DIR: %f %f %f\n", tmp[X], tmp[Y], tmp[Z]);
201 
202  if ((mask & KF_TWIST_MASK)) {
203  GS_set_twist((int)v->fields[KF_TWIST]);
204  }
205 
206  if ((mask & KF_FOV_MASK)) {
207  GS_set_fov((int)v->fields[KF_FOV]);
208  }
209 
210  /* Initilaize lights before drawing */
211  num = 1;
212  GS_getlight_position(num, &x, &y, &z, &w);
213  GS_setlight_position(num, x, y, z, w);
214  num = 2; /* Top light */
215  GS_setlight_position(num, 0., 0., 1., 0);
216 
217  if (render) {
219  }
220  else {
222  }
223 
224  GS_ready_draw();
226 
227  if (render) {
228  GS_alldraw_surf();
229  }
230  else {
231  GS_alldraw_wire();
232  }
233 
235 
236  if (mode & FM_PATH) {
237  gk_draw_path(view, numsteps, keys);
238  }
239 
240  if (mode & FM_VECT) {
241  GV_alldraw_vect();
242  }
243 
244  if (mode & FM_SITE) {
245  GP_alldraw_site();
246  }
247 
248  if (mode & FM_VOL) {
249  GVL_alldraw_vol();
250  }
251 
252  GS_done_draw();
253 
254  if (mode & FM_LABEL) {
255  GS_draw_all_list(); /* draw labels and legend */
256  }
257 
258  if (onestep) {
259  return;
260  }
261  }
262 
263  return;
264 }
265 
266 /*!
267  \brief Free keyframe list
268 
269  \param ok pointer to Keylist struct
270  */
272 {
273  Keylist *k, *prev;
274 
275  if (ok) {
276  k = ok;
277  while (k) {
278  prev = k;
279  k = k->next;
280  G_free(prev);
281  }
282  }
283 
284  return;
285 }
286 
287 /*!
288  \brief Generate viewnode from keyframes
289 
290  Here we use a cardinal cubic spline
291 
292  \param keys list of keyframes
293  \param keysteps keyframe step
294  \param newsteps new step value
295  \param loop loop indicator
296  \param t
297 
298  \return pointer to Viewnode
299  \return NULL on failure
300  */
301 Viewnode *gk_make_framesfromkeys(Keylist * keys, int keysteps, int newsteps,
302  int loop, float t)
303 {
304  int i;
305  Viewnode *v, *newview;
306  Keylist *k, *kp1, *kp2, *km1, **tkeys;
307  float startpos, endpos;
308  double dt1, dt2, x, x2, x3, range, time, time_step, len, rderiv, lderiv;
309 
310  /* allocate tmp keys to hold valid keys for fields */
311  tkeys = (Keylist **) G_malloc(keysteps * sizeof(Keylist *)); /* G_fatal_error */
312  if (!tkeys) {
313  return (NULL);
314  }
315 
316  correct_twist(keys);
317 
318  if (keys && keysteps) {
319  if (keysteps < 3) {
320  G_warning(_("Need at least 3 keyframes for spline"));
321  G_free(tkeys);
322  return (NULL);
323  }
324 
325  /* find end key */
326  for (k = keys; k->next; k = k->next) ;
327 
328  startpos = keys->pos;
329  endpos = k->pos;
330  range = endpos - startpos;
331  time_step = range / (newsteps - 1);
332 
333  newview = (Viewnode *) G_malloc(newsteps * sizeof(Viewnode)); /* G_fatal_error */
334  if (!newview) { /* not used */
335  G_free(tkeys);
336  return (NULL);
337  }
338 
339  for (i = 0; i < newsteps; i++) {
340  int field = 0;
341 
342  v = &newview[i];
343 
344  time = startpos + i * time_step;
345 
346  if (i == newsteps - 1) {
347  time = endpos; /*to ensure no roundoff errors */
348  }
349 
350  for (field = 0; field < KF_NUMFIELDS; field++) {
351  int nvk = 0; /* number of viable keyframes for this field */
352 
353  /* now need to do for each field to look at mask */
354  k = kp1 = kp2 = km1 = NULL;
355  nvk = gk_viable_keys_for_mask((unsigned long)(1 << field),
356  keys, tkeys);
357  if (nvk) {
358  len = get_key_neighbors(nvk, time, range,
359  loop, tkeys, &k, &kp1, &kp2, &km1,
360  &dt1, &dt2);
361  }
362 
363  /* ACS 1 line: was if (len == 0.0) {
364  when disabling a channel no calculation must be made at all (otherwise core dump)
365  */
366  if (len == 0.0 || nvk == 0) {
367  if (!k) {
368  /* none valid - use first.
369  (when showing , will be ignored anyway) */
370  v->fields[field] = keys->fields[field];
371  }
372  else if (!kp1) {
373  /* none on right - use left */
374  v->fields[field] = k->fields[field];
375  }
376 
377  continue;
378  }
379  else if (!km1 && !kp2) {
380  /* only two valid - use linear */
381  v->fields[field] = lin_interp((time - k->pos) / len,
382  k->fields[field],
383  kp1->fields[field]);
384  continue;
385  }
386 
387  x = (time - k->pos) / len;
388  x2 = x * x;
389  x3 = x2 * x;
390 
391  if (!km1) {
392  /* leftmost interval */
393  rderiv = (kp2->fields[field] - k->fields[field]) / dt2;
394  lderiv = (3 * (kp1->fields[field] -
395  k->fields[field]) / dt1 - rderiv) / 2.0;
396  v->fields[field] = spl3(t, k->fields[field],
397  kp1->fields[field], x, x2, x3,
398  lderiv, rderiv);
399  }
400  else if (!kp2) {
401  /* rightmost interval */
402  lderiv = (kp1->fields[field] - km1->fields[field]) / dt1;
403  rderiv = (3 * (kp1->fields[field] -
404  k->fields[field]) / dt2 - lderiv) / 2.0;
405  v->fields[field] = spl3(t, k->fields[field],
406  kp1->fields[field], x, x2, x3,
407  lderiv, rderiv);
408  }
409  else {
410  /* not on ends */
411  lderiv = (kp1->fields[field] - km1->fields[field]) / dt1;
412  rderiv = (kp2->fields[field] - k->fields[field]) / dt2;
413  v->fields[field] = spl3(t, k->fields[field],
414  kp1->fields[field], x, x2, x3,
415  lderiv, rderiv);
416  }
417  }
418  }
419 
420  G_free(tkeys);
421  return (newview);
422  }
423  else {
424  G_free(tkeys);
425  return (NULL);
426  }
427 }
428 
429 /*!
430  \brief Find interval containing time
431 
432  Changed June 94 to handle masks - now need to have called get_viable_keys
433  for appropriate mask first to build the ARRAY of viable keyframes.
434 
435  Putting left (or equal) key
436  at km1, right at kp1, 2nd to right at kp2, and second to left at km2.
437  dt1 is given the length of the current + left intervals
438  dt2 is given the length of the current + right intervals
439 
440  \param nvk
441  \param time
442  \param range
443  \param loop
444  \param karray
445  \param km1
446  \param kp1
447  \param kp2
448  \param km2
449  \param dt1
450  \param dt2
451 
452  \return the length of the current interval
453  \return 0 on error
454  */
455 double get_key_neighbors(int nvk, double time, double range, int loop,
456  Keylist * karray[], Keylist ** km1, Keylist ** kp1,
457  Keylist ** kp2, Keylist ** km2, double *dt1,
458  double *dt2)
459 {
460  int i;
461  double len;
462 
463  *km1 = *kp1 = *kp2 = *km2 = NULL;
464  *dt1 = *dt2 = 0.0;
465 
466  for (i = 0; i < nvk; i++) {
467  if (time < karray[i]->pos) {
468  break;
469  }
470  }
471 
472  if (!i) {
473  return (0.0); /* before first keyframe or nvk == 0 */
474  }
475 
476  if (i == nvk) {
477  /* past or == last keyframe! */
478  *km1 = karray[nvk - 1];
479  return (0.0);
480  }
481 
482  /* there's at least 2 */
483  *km1 = karray[i - 1];
484  *kp1 = karray[i];
485  len = karray[i]->pos - karray[i - 1]->pos;
486 
487  if (i == 1) {
488  /* first interval */
489  if (loop) {
490  *km2 = karray[nvk - 2];
491  *kp2 = karray[(i + 1) % nvk];
492  }
493  else {
494  if (nvk > 2) {
495  *kp2 = karray[i + 1];
496  }
497  }
498  }
499  else if (i == nvk - 1) {
500  /* last interval */
501  if (loop) {
502  *km2 = nvk > 2 ? karray[i - 2] : karray[1];
503  *kp2 = karray[1];
504  }
505  else {
506  if (nvk > 2) {
507  *km2 = karray[i - 2];
508  }
509  }
510  }
511  else {
512  *km2 = karray[i - 2];
513  *kp2 = karray[i + 1];
514  }
515 
516  *dt1 = (*km2) ? (*kp1)->pos - (*km2)->pos : len;
517  *dt2 = (*kp2) ? (*kp2)->pos - (*km1)->pos : len;
518 
519  if (i == 1 && loop) {
520  *dt1 += range;
521  }
522 
523  if (i == nvk - 1 && loop) {
524  *dt2 += range;
525  }
526 
527  return (len);
528 }
529 
530 /*!
531  \brief Linear interpolation
532 
533  \param dt coeficient
534  \param val2 value 2
535  \param val1 value 1
536 
537  \return val1 + dt * (val2 - val1)
538  */
539 double lin_interp(float dt, float val1, float val2)
540 {
541  return ((double)(val1 + dt * (val2 - val1)));
542 }
543 
544 /*!
545  \brief Finds interval containing time, putting left (or equal) key
546  at km1, right at kp1
547 
548  \param nvk
549  \param time
550  \param range
551  \param loop
552  \param karray
553  \param km1
554  \param km2
555 
556  \return interval value
557  */
558 double get_2key_neighbors(int nvk, float time, float range, int loop,
559  Keylist * karray[], Keylist ** km1, Keylist ** kp1)
560 {
561  int i;
562  double len;
563 
564  *km1 = *kp1 = NULL;
565 
566  for (i = 0; i < nvk; i++) {
567  if (time < karray[i]->pos) {
568  break;
569  }
570  }
571 
572  if (!i) {
573  return (0.0); /* before first keyframe or nvk == 0 */
574  }
575 
576  if (i == nvk) {
577  /* past or == last keyframe! */
578  *km1 = karray[nvk - 1];
579  return (0.0);
580  }
581 
582  /* there's at least 2 */
583  *km1 = karray[i - 1];
584  *kp1 = karray[i];
585  len = karray[i]->pos - karray[i - 1]->pos;
586 
587  return (len);
588 }
589 
590 /*!
591  \brief Generate viewnode from keyframe list (linear interpolation)
592 
593  Here we use linear interpolation. Loop variable isn't used, but left
594  in for use in possible "linear interp with smoothing" version.
595 
596  \param kesy keyframe list
597  \param keysteps step value
598  \param newsteps new step value
599  \param loop loop indicator
600 
601  \param pointer to viewnode struct
602  \param NULL on failure
603  */
605  int newsteps, int loop)
606 {
607  int i, nvk;
608  Viewnode *v, *newview;
609  Keylist *k, *k1, *k2, **tkeys;
610  float startpos, endpos, dt, range, time, time_step, len;
611 
612  /* allocate tmp keys to hold valid keys for fields */
613  tkeys = (Keylist **) G_malloc(keysteps * sizeof(Keylist *)); /* G_fatal_error */
614  if (!tkeys) {
615  return (NULL);
616  }
617 
618  correct_twist(keys);
619 
620  if (keys && keysteps) {
621  if (keysteps < 2) {
622  G_warning(_("Need at least 2 keyframes for interpolation"));
623  G_free(tkeys);
624  return (NULL);
625  }
626 
627  /* find end key */
628  for (k = keys; k->next; k = k->next) ;
629 
630  startpos = keys->pos;
631  endpos = k->pos;
632  range = endpos - startpos;
633  time_step = range / (newsteps - 1);
634 
635  newview = (Viewnode *) G_malloc(newsteps * sizeof(Viewnode)); /* G_fatal_error */
636  if (!newview) { /* not used */
637  G_free(tkeys);
638  return (NULL);
639  }
640 
641  for (i = 0; i < newsteps; i++) {
642  int field = 0;
643 
644  v = &newview[i];
645 
646  time = startpos + i * time_step;
647  if (i == newsteps - 1) {
648  time = endpos; /*to ensure no roundoff errors */
649  }
650 
651  for (field = 0; field < KF_NUMFIELDS; field++) {
652 
653  nvk = gk_viable_keys_for_mask((unsigned long)(1 << field),
654  keys, tkeys);
655  if (!nvk) {
656  v->fields[field] = keys->fields[field]; /*default-not used */
657  }
658  else {
659  len = get_2key_neighbors(nvk, time, range, loop,
660  tkeys, &k1, &k2);
661  }
662 
663  /* ACS 1 line: was if (len == 0.0) {
664  when disabling a channel no calculation must be made at all (otherwise core dump)
665  */
666  if (len == 0.0 || nvk == 0) {
667  if (!k1) {
668  /* none valid - use first.
669  (when showing , will be ignored anyway) */
670  v->fields[field] = keys->fields[field];
671  }
672  else if (!k2) {
673  /* none on right - use left */
674  v->fields[field] = k1->fields[field];
675  }
676  }
677  else {
678  dt = (time - k1->pos) / len;
679  v->fields[field] = lin_interp(dt,
680  k1->fields[field],
681  k2->fields[field]);
682  }
683  }
684  }
685 
686  G_free(tkeys);
687  return (newview);
688  }
689  else {
690  G_free(tkeys);
691  return (NULL);
692  }
693 }
694 
695 /*!
696  \brief Correct twist value
697 
698  \param k keyframe list
699  */
701 {
702  Keylist *c, *p, *t;
703  int cnt, j;
704 
705  p = NULL;
706  cnt = 0;
707  for (c = k; c; c = c->next) {
708  if (p) {
709  if ((c->fields[KF_TWIST] - p->fields[KF_TWIST]) > 1800.) {
710  for (t = c; t; t = t->next) {
711  t->fields[KF_TWIST] -= 3600.;
712  }
713  }
714  else if ((p->fields[KF_TWIST] - c->fields[KF_TWIST]) > 1800.) {
715  for (t = k, j = 0; j < cnt; j++, t = t->next) {
716  t->fields[KF_TWIST] -= 3600.;
717  }
718  }
719  }
720 
721  p = c;
722  ++cnt;
723  }
724 
725  return;
726 }
727 
728 /*!
729  \brief Draw path
730 
731  \param views Viewnode struct
732  \param steps step value
733  \param keys keyframe list
734 
735  \return 0 on failure
736  \return 1 on success
737  */
738 int gk_draw_path(Viewnode * views, int steps, Keylist * keys)
739 {
740  Viewnode *v;
741  Keylist *k;
742  int frame;
743  float siz, from[3];
744 
745  if (!views || !keys) {
746  return (0);
747  }
748 
749  GS_get_longdim(&siz);
750  siz /= 200.;
751 
753  gsd_linewidth(2);
755  gsd_zwritemask(0);
756 
757  gsd_bgnline();
758 
759  for (frame = 0; frame < steps; frame++) {
760  v = &views[frame];
761  gsd_vert_func(&(v->fields[KF_FROMX]));
762  }
763 
764  gsd_endline();
765 
766  gsd_linewidth(1);
767 
768 
769  for (k = keys; k; k = k->next) {
770  gsd_x(NULL, &(k->fields[KF_FROMX]),
771  ~(GS_background_color() | 0xFF0000), siz);
772  }
773 
774  /* draw viewer position for inset images */
775  GS_get_from(from);
776  gsd_x(NULL, from, ~(GS_default_draw_color() | 0xFFFF00), 3.0 * siz);
777 
778  gsd_zwritemask(0xffffffff);
779 
780  return (1);
781 }
#define KF_TWIST
Definition: ogsf.h:532
#define G_malloc(n)
Definition: defs/gis.h:112
void gk_free_key(Keylist *ok)
Free keyframe list.
Definition: gk.c:271
void GS_set_viewdir(float *)
Set viewdir.
Definition: gs2.c:2823
unsigned long gk_get_mask_sofar(float time, Keylist *keys)
Get mask value.
Definition: gk.c:79
double lin_interp(float dt, float val1, float val2)
Linear interpolation.
Definition: gk.c:539
#define KF_FROMX_MASK
Definition: ogsf.h:504
#define KF_NUMFIELDS
Definition: ogsf.h:519
#define KF_FOV
Definition: ogsf.h:531
void GS_ready_draw(void)
Definition: gs2.c:2488
#define KF_DIRY_MASK
Definition: ogsf.h:510
void GS_draw_all_list(void)
Draw all glLists.
Definition: gs2.c:879
void GVL_alldraw_vol(void)
Draw all volume sets.
Definition: gvl2.c:441
#define KF_FROMX
Definition: ogsf.h:525
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
Viewnode * gk_make_framesfromkeys(Keylist *keys, int keysteps, int newsteps, int loop, float t)
Generate viewnode from keyframes.
Definition: gk.c:301
#define KF_TWIST_MASK
Definition: ogsf.h:515
#define KF_FROMY
Definition: ogsf.h:526
#define FM_VOL
Definition: ogsf.h:537
void GS_alldraw_cplane_fences(void)
Draw all cplace fences ?
Definition: gs2.c:3195
void correct_twist(Keylist *k)
Correct twist value.
Definition: gk.c:700
#define NULL
Definition: ccmath.h:32
unsigned int GS_background_color(void)
Get background color.
Definition: gs2.c:2452
#define x
void GS_get_from(float *)
Get viewpoint &#39;from&#39; position.
Definition: gs2.c:2725
void GS_clear(int)
Clear view.
Definition: gs2.c:3418
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1919
int gk_draw_path(Viewnode *views, int steps, Keylist *keys)
Draw path.
Definition: gk.c:738
Viewnode * gk_make_linear_framesfromkeys(Keylist *keys, int keysteps, int newsteps, int loop)
Generate viewnode from keyframe list (linear interpolation)
Definition: gk.c:604
double t
Definition: r_raster.c:39
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:97
unsigned long fieldmask
Definition: ogsf.h:549
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:455
struct key_node * prior
Definition: ogsf.h:550
int gk_viable_keys_for_mask(unsigned long mask, Keylist *keys, Keylist **keyret)
ADD.
Definition: gk.c:112
#define KF_FROMZ_MASK
Definition: ogsf.h:506
#define CM_COLOR
Definition: ogsf.h:145
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:701
#define FM_VECT
Definition: ogsf.h:534
void GS_set_twist(int)
Set viewpoint twist value.
Definition: gs2.c:2877
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
#define KF_DIRX
Definition: ogsf.h:528
void GS_alldraw_surf(void)
Draw all surfaces.
Definition: gs2.c:1936
void gsd_x(geosurf *, float *, int, float)
Draw X symbol.
Definition: gsd_objs.c:278
#define FM_SITE
Definition: ogsf.h:535
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:141
void GP_alldraw_site(void)
Draw all available point sets.
Definition: gp2.c:607
float fields[KF_NUMFIELDS]
Definition: ogsf.h:547
#define KF_DIRZ_MASK
Definition: ogsf.h:511
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
#define KF_DIRY
Definition: ogsf.h:529
#define Z
Definition: ogsf.h:139
#define KF_DIRZ
Definition: ogsf.h:530
void GS_setlight_position(int, float, float, float, int)
Set light position.
Definition: gs2.c:309
Definition: ogsf.h:545
void gsd_zwritemask(unsigned long)
Write out z-mask.
Definition: gsd_prim.c:240
#define GSD_BACK
Definition: ogsf.h:102
#define Y
Definition: ogsf.h:138
#define KF_FROMZ
Definition: ogsf.h:527
#define FM_PATH
Definition: ogsf.h:536
struct key_node * next
Definition: ogsf.h:550
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:266
float pos
Definition: ogsf.h:547
void GS_get_viewdir(float *)
Get viewdir.
Definition: gs2.c:2809
#define KF_DIRX_MASK
Definition: ogsf.h:509
void G_warning(const char *,...) __attribute__((format(printf
#define GSD_FRONT
Definition: ogsf.h:101
void GS_moveto(float *)
Move viewpoint.
Definition: gs2.c:2617
#define _(str)
Definition: glocale.h:10
#define X
Definition: ogsf.h:137
int GS_get_longdim(float *)
Get largest dimension.
Definition: gs2.c:140
unsigned int GS_default_draw_color(void)
Get default draw color.
Definition: gs2.c:2439
void GS_getlight_position(int, float *, float *, float *, int *)
Get light position.
Definition: gs2.c:335
#define KF_FROMY_MASK
Definition: ogsf.h:505
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:558
#define FM_LABEL
Definition: ogsf.h:538
int look_ahead
Definition: ogsf.h:548
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2462
int G_debug(int, const char *,...) __attribute__((format(printf
Keylist * gk_copy_key(Keylist *k)
Copy keyframes.
Definition: gk.c:45
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
#define KF_FOV_MASK
Definition: ogsf.h:514
float fields[KF_NUMFIELDS]
Definition: ogsf.h:542
void GV_alldraw_vect(void)
Draw all loaded vector sets.
Definition: gv2.c:506
void GS_set_fov(int)
Set field of view.
Definition: gs2.c:2843
void gsd_vert_func(float *)
ADD.
Definition: gsd_prim.c:689