gk2.c 11 KB

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