GK2.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*!
  2. \file GK2.c
  3. \brief OGSF library - setting and manipulating keyframes animation
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL, GMSL/University of Illinois
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <stdlib.h>
  14. #include <grass/gis.h>
  15. #include <grass/glocale.h>
  16. #include <grass/gstypes.h>
  17. #include <grass/keyframe.h>
  18. #include <grass/kftypes.h>
  19. static int _add_key(Keylist *, int, float);
  20. static void _remove_key(Keylist *);
  21. static Keylist *Keys = NULL;
  22. static Keylist *Keytail = NULL;
  23. static Viewnode *Views = NULL;
  24. static float Keystartpos = 0.0;
  25. static float Keyendpos = 1.0;
  26. static float Tension = 0.8;
  27. static int Viewsteps = 0;
  28. static int Numkeys = 0;
  29. static int Interpmode = KF_SPLINE;
  30. static int Fmode = 0;
  31. /* next & prior already initialized to NULL */
  32. static int _add_key(Keylist * newk, int force_replace, float precis)
  33. {
  34. Keylist *k, *tempk, *prev;
  35. int found;
  36. found = 0;
  37. prev = NULL;
  38. /* if(Viewsteps) precis = 0.5/Viewsteps; */
  39. for (k = Keys; k; k = k->next) {
  40. if (k->pos >= newk->pos - precis && k->pos <= newk->pos + precis) {
  41. if (force_replace) {
  42. if (k->prior) {
  43. k->prior->next = newk;
  44. newk->prior = prev;
  45. }
  46. else {
  47. Keys = newk;
  48. }
  49. newk->next = k->next;
  50. newk->prior = k->prior;
  51. tempk = k;
  52. k = newk;
  53. free(tempk);
  54. }
  55. else {
  56. free(newk);
  57. }
  58. return (-1);
  59. }
  60. }
  61. if (Keys) {
  62. if (newk->pos < Keys->pos) {
  63. /* new will be first */
  64. newk->next = Keys;
  65. Keys->prior = newk;
  66. Keys = newk;
  67. }
  68. else {
  69. prev = k = Keys;
  70. while (k && !found) {
  71. if (k->pos > newk->pos) {
  72. prev->next = newk;
  73. newk->next = k;
  74. newk->prior = prev;
  75. k->prior = newk;
  76. found = 1;
  77. }
  78. prev = k;
  79. k = k->next;
  80. }
  81. if (!found) {
  82. Keytail = prev->next = newk;
  83. newk->prior = prev;
  84. }
  85. }
  86. }
  87. else {
  88. Keys = Keytail = newk;
  89. }
  90. ++Numkeys;
  91. return (1);
  92. }
  93. static void _remove_key(Keylist * k)
  94. {
  95. if (k->prior) {
  96. k->prior->next = k->next;
  97. if (k->next) {
  98. k->next->prior = k->prior;
  99. }
  100. else {
  101. Keytail = k->prior;
  102. }
  103. }
  104. else {
  105. Keys = k->next;
  106. if (k->next) {
  107. k->next->prior = NULL;
  108. }
  109. }
  110. k->next = k->prior = NULL;
  111. return;
  112. }
  113. /*!
  114. \brief Set interpolation mode
  115. \param mode interpolation mode (KF_LINEAR or KF_SPLINE)
  116. \return 1 on success
  117. \return -1 on error (invalid interpolation mode)
  118. */
  119. int GK_set_interpmode(int mode)
  120. {
  121. if (KF_LEGAL_MODE(mode)) {
  122. Interpmode = mode;
  123. return (1);
  124. }
  125. return (-1);
  126. }
  127. /*!
  128. \brief Set value for tension when interpmode is KF_SPLINE.
  129. \param tens value tens should be between 0.0; 1.0.
  130. */
  131. void GK_set_tension(float tens)
  132. {
  133. Tension = tens > 1.0 ? 1.0 : (tens < 0.0 ? 0.0 : tens);
  134. /* for now */
  135. if (Views) {
  136. GK_update_frames();
  137. GS_set_draw(GSD_BACK);
  138. GS_ready_draw();
  139. GS_clear(GS_background_color());
  140. GS_alldraw_wire();
  141. gk_draw_path(Views, Viewsteps, Keys);
  142. GS_done_draw();
  143. }
  144. return;
  145. }
  146. void GK_showtension_start(void)
  147. {
  148. return;
  149. }
  150. /*!
  151. \brief Show tension stop ?
  152. Use GK_showtension_start/GK_update_tension/GK_showtension_stop to
  153. initialize and stop multi-view display of path when changing
  154. tension.
  155. */
  156. void GK_showtension_stop(void)
  157. {
  158. return;
  159. }
  160. /*!
  161. \brief Update tension
  162. */
  163. void GK_update_tension(void)
  164. {
  165. if (Views) {
  166. GK_update_frames();
  167. }
  168. return;
  169. }
  170. /*!
  171. \brief Print keyframe info
  172. \param name filename
  173. */
  174. void GK_print_keys(const char *name)
  175. {
  176. Keylist *k;
  177. FILE *fp;
  178. int cnt = 1;
  179. if (NULL == (fp = fopen(name, "w"))) {
  180. G_fatal_error(_("Unable to open file <%s> for writing"), name);
  181. }
  182. /* write a default frame rate of 30 at top of file */
  183. fprintf(fp, "30 \n");
  184. for (k = Keys; k; k = k->next) {
  185. fprintf(fp,
  186. "{%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} ",
  187. k->pos, k->fields[KF_FROMX], k->fields[KF_FROMY],
  188. k->fields[KF_FROMZ], k->fields[KF_DIRX], k->fields[KF_DIRY],
  189. k->fields[KF_DIRZ], k->fields[KF_FOV] / 10.,
  190. k->fields[KF_TWIST], cnt);
  191. cnt++;
  192. }
  193. fclose(fp);
  194. return;
  195. }
  196. /*!
  197. \brief Recalculate path using the current number of frames requested.
  198. Call after changing number of frames or when
  199. Keyframes change.
  200. */
  201. void GK_update_frames(void)
  202. {
  203. Keylist *k;
  204. int loop = 0;
  205. if (Keys) {
  206. if (Numkeys > 1) {
  207. k = Keytail;
  208. Keyendpos = k->pos;
  209. if (k->fields[KF_FROMX] == Keys->fields[KF_FROMX] &&
  210. k->fields[KF_FROMY] == Keys->fields[KF_FROMY] &&
  211. k->fields[KF_FROMZ] == Keys->fields[KF_FROMZ]) {
  212. loop = 1;
  213. }
  214. }
  215. Keystartpos = Keys->pos;
  216. }
  217. if (Interpmode == KF_LINEAR && Numkeys > 1) {
  218. if (Views) {
  219. free(Views);
  220. Views = NULL;
  221. }
  222. Views = gk_make_linear_framesfromkeys(Keys, Numkeys, Viewsteps, loop);
  223. if (!Views) {
  224. G_warning(_("Check no. of frames requested and keyframes marked"));
  225. }
  226. }
  227. else if (Numkeys > 2) {
  228. if (Views) {
  229. free(Views);
  230. Views = NULL;
  231. }
  232. Views = gk_make_framesfromkeys
  233. (Keys, Numkeys, Viewsteps, loop, 1.0 - Tension);
  234. if (!Views) {
  235. G_warning(_("Check no. of frames requested and keyframes marked"));
  236. }
  237. }
  238. return;
  239. }
  240. /*!
  241. \brief Set the number of frames to be interpolated from keyframes
  242. \param newsteps number of frames
  243. */
  244. void GK_set_numsteps(int newsteps)
  245. {
  246. Viewsteps = newsteps;
  247. GK_update_frames();
  248. return;
  249. }
  250. /*!
  251. \brief Deletes all keyframes, resets field masks.
  252. Doesn't change number of frames requested.
  253. */
  254. void GK_clear_keys(void)
  255. {
  256. gk_free_key(Keys);
  257. Keys = NULL;
  258. Numkeys = 0;
  259. free(Views);
  260. Views = NULL;
  261. Keystartpos = 0.0;
  262. Keyendpos = 1.0;
  263. return;
  264. }
  265. /*!
  266. \brief Move keyframe
  267. Precis works as in other functions - to identify keyframe to move.
  268. Only the first keyframe in the precis range will be moved.
  269. \param oldpos old position
  270. \param precis precision value
  271. \param newpos new position
  272. \return number of keys moved (1 or 0)
  273. */
  274. int GK_move_key(float oldpos, float precis, float newpos)
  275. {
  276. Keylist *k;
  277. for (k = Keys; k; k = k->next) {
  278. if (k->pos >= oldpos - precis && k->pos <= oldpos + precis) {
  279. _remove_key(k);
  280. k->pos = newpos;
  281. _add_key(k, 1, precis);
  282. GK_update_frames();
  283. return (1);
  284. }
  285. }
  286. return (0);
  287. }
  288. /*!
  289. Delete keyframe
  290. The values pos and precis are used to determine which keyframes to
  291. delete. Any keyframes with their position within precis of pos will
  292. be deleted if justone is zero. If justone is non-zero, only the first
  293. (lowest pos) keyframe in the range will be deleted.
  294. \param pos position
  295. \param precis precision
  296. \param justone delete only one keyframe
  297. \return number of keys deleted.
  298. */
  299. int GK_delete_key(float pos, float precis, int justone)
  300. {
  301. Keylist *k, *next;
  302. int cnt;
  303. for (cnt = 0, k = Keys; k;) {
  304. next = k->next;
  305. if (k->pos >= pos - precis && k->pos <= pos + precis) {
  306. cnt++;
  307. _remove_key(k);
  308. free(k);
  309. if (justone) {
  310. break;
  311. }
  312. }
  313. k = next;
  314. }
  315. GK_update_frames();
  316. return (cnt);
  317. }
  318. /*!
  319. \brief Add keyframe
  320. The pos value is the relative position in the animation for this
  321. particular keyframe - used to compare relative distance to neighboring
  322. keyframes, it can be any floating point value.
  323. The fmask value can be any of the following or'd together:
  324. - KF_FROMX_MASK
  325. - KF_FROMY_MASK
  326. - KF_FROMZ_MASK
  327. - KF_FROM_MASK (KF_FROMX_MASK | KF_FROMY_MASK | KF_FROMZ_MASK)
  328. - KF_DIRX_MASK
  329. - KF_DIRY_MASK
  330. - KF_DIRZ_MASK
  331. - KF_DIR_MASK (KF_DIRX_MASK | KF_DIRY_MASK | KF_DIRZ_MASK)
  332. - KF_FOV_MASK
  333. - KF_TWIST_MASK
  334. - KF_ALL_MASK (KF_FROM_MASK | KF_DIR_MASK | KF_FOV_MASK | KF_TWIST_MASK)
  335. Other fields will be added later.
  336. The value precis and the boolean force_replace are used to determine
  337. if a keyframe should be considered to be at the same position as a
  338. pre-existing keyframe. e.g., if anykey.pos - newkey.pos &lt;= precis,
  339. GK_add_key() will fail unless force_replace is TRUE.
  340. \param pos postion
  341. \param fmaks
  342. \param force_replace
  343. \param precis precision value
  344. \return 1 if key is added
  345. \return -1 key not added
  346. */
  347. int GK_add_key(float pos, unsigned long fmask, int force_replace,
  348. float precis)
  349. {
  350. Keylist *newk;
  351. float tmp[3];
  352. if (NULL == (newk = (Keylist *) malloc(sizeof(Keylist)))) {
  353. fprintf(stderr, "Out of memory\n");
  354. return (-1);
  355. }
  356. /* All fields set, don't use mask until making Views */
  357. GS_get_from(tmp);
  358. newk->fields[KF_FROMX] = tmp[X];
  359. newk->fields[KF_FROMY] = tmp[Y];
  360. newk->fields[KF_FROMZ] = tmp[Z];
  361. G_debug(3, "KEY FROM: %f %f %f", tmp[X], tmp[Y], tmp[Z]);
  362. /* Instead of View Dir try get_focus (view center) */
  363. /* View Dir is implied from eye and center position */
  364. /* GS_get_viewdir(tmp); */
  365. /* ACS 1 line: was GS_get_focus(tmp);
  366. with this kanimator works also for flythrough navigation
  367. also changed in gk.c
  368. */
  369. GS_get_viewdir(tmp);
  370. newk->fields[KF_DIRX] = tmp[X];
  371. newk->fields[KF_DIRY] = tmp[Y];
  372. newk->fields[KF_DIRZ] = tmp[Z];
  373. newk->fields[KF_FOV] = GS_get_fov();
  374. newk->fields[KF_TWIST] = GS_get_twist();
  375. newk->pos = pos;
  376. newk->fieldmask = fmask;
  377. newk->next = NULL;
  378. newk->prior = NULL;
  379. if (0 < _add_key(newk, force_replace, precis)) {
  380. GK_update_frames();
  381. return (1);
  382. }
  383. return (-1);
  384. }
  385. /*!
  386. \brief Moves the animation to frame number "step".
  387. Step should be a value between 1 and the number of frames. If
  388. render is non-zero, calls draw_all.
  389. \param step step value
  390. \param render
  391. */
  392. void GK_do_framestep(int step, int render)
  393. {
  394. if (Views) {
  395. if (step > 0 && step <= Viewsteps) {
  396. gk_follow_frames(Views, Viewsteps, Keys, step, 1, render, Fmode);
  397. }
  398. }
  399. return;
  400. }
  401. /*!
  402. \brief Draw the current path
  403. \param flag
  404. */
  405. void GK_show_path(int flag)
  406. {
  407. if (flag) {
  408. Fmode |= FM_PATH;
  409. if (Views) {
  410. GS_set_draw(GSD_FRONT);
  411. GS_ready_draw();
  412. gk_draw_path(Views, Viewsteps, Keys);
  413. GS_done_draw();
  414. }
  415. }
  416. else {
  417. Fmode &= ~FM_PATH;
  418. }
  419. return;
  420. }
  421. /*!
  422. \brief Show vector sets
  423. \param flag
  424. */
  425. void GK_show_vect(int flag)
  426. {
  427. if (flag) {
  428. Fmode |= FM_VECT;
  429. if (Views) {
  430. GS_set_draw(GSD_FRONT);
  431. GS_ready_draw();
  432. GV_alldraw_vect();
  433. GS_done_draw();
  434. }
  435. }
  436. else {
  437. Fmode &= ~FM_VECT;
  438. }
  439. return;
  440. }
  441. /*!
  442. \brief Show point sets
  443. \param flag
  444. */
  445. void GK_show_site(int flag)
  446. {
  447. if (flag) {
  448. Fmode |= FM_SITE;
  449. if (Views) {
  450. GS_set_draw(GSD_FRONT);
  451. GS_ready_draw();
  452. GP_alldraw_site();
  453. GS_done_draw();
  454. }
  455. }
  456. else {
  457. Fmode &= ~FM_SITE;
  458. }
  459. return;
  460. }
  461. /*!
  462. \brief Show volumes
  463. \param flag
  464. */
  465. void GK_show_vol(int flag)
  466. {
  467. if (flag) {
  468. Fmode |= FM_VOL;
  469. if (Views) {
  470. GS_set_draw(GSD_FRONT);
  471. GS_ready_draw();
  472. GVL_alldraw_vol();
  473. GS_done_draw();
  474. }
  475. }
  476. else {
  477. Fmode &= ~FM_VOL;
  478. }
  479. return;
  480. }
  481. /*!
  482. \brief Show list
  483. \param flag
  484. */
  485. void GK_show_list(int flag)
  486. {
  487. if (flag) {
  488. Fmode |= FM_LABEL;
  489. if (Views) {
  490. GS_draw_all_list();
  491. }
  492. }
  493. else {
  494. Fmode &= ~FM_LABEL;
  495. }
  496. return;
  497. }