PageRenderTime 25ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/brlcad/branches/bullet/src/anim/anim_orient.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 307 lines | 223 code | 26 blank | 58 comment | 24 complexity | 3f3b4ddbbd456ca22472d99832abfb66 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /* A N I M _ O R I E N T . C
  2. * BRL-CAD
  3. *
  4. * Copyright (c) 1993-2012 United States Government as represented by
  5. * the U.S. Army Research Laboratory.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public License
  9. * version 2.1 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this file; see the file named COPYING for more
  18. * information.
  19. *
  20. */
  21. /** @file anim_orient.c
  22. *
  23. * Convert between different orientation formats. The formats are:
  24. * quaternion, yaw-pitch-roll, azimuth-elevation-twist, xyz angles,
  25. * pre-multiplication rotation matrices, and transposed matrices
  26. * (inverses).
  27. *
  28. * By default, the information is assumed to represent a
  29. * transformation which should be an object which initially faces the
  30. * x-axis, with the z-axis going up. Alternatively, the information
  31. * can be interpreted as transformations which should be applied to an
  32. * object initially facing the negative z-axis, with the y-axis going
  33. * up.
  34. *
  35. * The conversion is done by converting each input form to a matrix,
  36. * and then converting that matrix to the desired output form.
  37. *
  38. * Angles may be specified in radians or degrees.
  39. *
  40. */
  41. #include "common.h"
  42. #include <stdlib.h>
  43. #include <math.h>
  44. #include "bio.h"
  45. #include "bu.h"
  46. #include "bn.h"
  47. #include "anim.h"
  48. #include "vmath.h"
  49. #define YPR 0
  50. #define XYZ 1
  51. #define AET 2
  52. #define QUAT 3
  53. #define MAT 4
  54. #define DEGREES 0
  55. #define RADIANS 1
  56. #define ANIM_NORMAL 0
  57. #define ANIM_ERROR1 1
  58. #define ANIM_ERROR2 2
  59. int upright;
  60. int input_mode, output_mode, length, input_units, output_units;
  61. int input_perm, output_perm, input_inv, output_inv;
  62. int
  63. parse_args(int argc, char **argv)
  64. {
  65. int c;
  66. char *cp;
  67. /* defaults */
  68. upright = 0;
  69. input_mode = QUAT;
  70. output_mode = QUAT;
  71. input_units = DEGREES;
  72. output_units = DEGREES;
  73. input_perm = 0;
  74. output_perm = 0;
  75. input_inv = 0;
  76. output_inv = 0;
  77. length = 4;
  78. if (argc > 2) {
  79. /*read output mode */
  80. cp = argv[2];
  81. while ((c=*cp++)) {
  82. switch (c) {
  83. case 'q':
  84. output_mode = QUAT;
  85. break;
  86. case 'y':
  87. output_mode = YPR;
  88. break;
  89. case 'a':
  90. output_mode = AET;
  91. break;
  92. case 'z':
  93. output_mode = XYZ;
  94. break;
  95. case 'm':
  96. output_mode = MAT;
  97. break;
  98. case 'i':
  99. output_inv = 1;
  100. break;
  101. case 'r':
  102. output_units = RADIANS;
  103. break;
  104. case 'v':
  105. output_perm = 1;
  106. break;
  107. case 'u':
  108. upright = 1;
  109. break;
  110. default:
  111. fprintf(stderr, "anim_orient: unknown output option: %c\n", c);
  112. return 0;
  113. }
  114. }
  115. }
  116. if (argc > 1) {
  117. /*read input mode */
  118. cp = argv[1];
  119. while ((c=*cp++)) {
  120. switch (c) {
  121. case 'q':
  122. input_mode = QUAT;
  123. length = 4;
  124. break;
  125. case 'y':
  126. input_mode = YPR;
  127. length = 3;
  128. break;
  129. case 'a':
  130. input_mode = AET;
  131. length = 3;
  132. break;
  133. case 'z':
  134. input_mode = XYZ;
  135. length = 3;
  136. break;
  137. case 'm':
  138. input_mode = MAT;
  139. length = 16;
  140. break;
  141. case 'i':
  142. input_inv = 1;
  143. break;
  144. case 'r':
  145. input_units = RADIANS;
  146. break;
  147. case 'v':
  148. input_perm = 1;
  149. break;
  150. default:
  151. fprintf(stderr, "anim_orient: unknown input option: %c\n", c);
  152. return 0;
  153. }
  154. }
  155. }
  156. return 1;
  157. }
  158. int
  159. main(int argc, char *argv[])
  160. {
  161. int num_read;
  162. fastf_t temp[3], temp2[3], angle[3], quat[4], matrix[16];
  163. if (!parse_args(argc, argv)) {
  164. fprintf(stderr, "Get_args error.\n");
  165. bu_exit(0, NULL);
  166. }
  167. /* read data */
  168. num_read = length;
  169. while (1) {
  170. double scan[4];
  171. switch (input_mode) {
  172. case YPR:
  173. case XYZ:
  174. case AET:
  175. num_read = scanf("%lf %lf %lf", &scan[0], &scan[1], &scan[2]);
  176. /* convert to radians if in degrees */
  177. if (input_units==DEGREES) {
  178. VSCALE(angle, scan, DEG2RAD); /* double to fastf_t */
  179. } else {
  180. VMOVE(angle, scan); /* double to fastf_t */
  181. }
  182. break;
  183. case QUAT:
  184. num_read = scanf("%lf %lf %lf %lf", &scan[0], &scan[1], &scan[2], &scan[3]);
  185. HMOVE(quat, scan); /* double to fastf_t */
  186. break;
  187. case MAT:
  188. num_read = 0;
  189. num_read += scanf("%lf %lf %lf %lf", &scan[0], &scan[1], &scan[2], &scan[3]);
  190. HMOVE(matrix, scan); /* double to fastf_t */
  191. num_read += scanf("%lf %lf %lf %lf", &scan[0], &scan[1], &scan[2], &scan[3]);
  192. HMOVE(matrix+4, scan); /* double to fastf_t */
  193. num_read += scanf("%lf %lf %lf %lf", &scan[0], &scan[1], &scan[2], &scan[3]);
  194. HMOVE(matrix+8, scan); /* double to fastf_t */
  195. num_read += scanf("%lf %lf %lf %lf", &scan[0], &scan[1], &scan[2], &scan[3]);
  196. HMOVE(matrix+12, scan); /* double to fastf_t */
  197. break;
  198. }
  199. if (num_read < length)
  200. break;
  201. /* convert to (object) matrix form */
  202. switch (input_mode) {
  203. case YPR:
  204. anim_ypr2mat(matrix, angle);
  205. break;
  206. case AET:
  207. anim_y_p_r2mat(matrix, angle[0]+M_PI, -angle[1], -angle[2]);
  208. break;
  209. case XYZ:
  210. anim_zyx2mat(matrix, angle);
  211. break;
  212. case QUAT:
  213. anim_quat2mat(matrix, quat);
  214. break;
  215. }
  216. if (input_inv) {
  217. anim_tran(matrix);
  218. }
  219. if (input_perm) {
  220. anim_v_unpermute(matrix);
  221. }
  222. /* end of input conversion, begin output conversion*/
  223. if (upright) {
  224. /* force right-side up */
  225. VSET(temp, matrix[0], matrix[4], matrix[8]);
  226. VSET(temp2, matrix[1], matrix[5], matrix[9]);
  227. anim_dirn2mat(matrix, temp, temp2);
  228. }
  229. if (output_perm) {
  230. anim_v_permute(matrix);
  231. }
  232. if (output_inv) {
  233. anim_tran(matrix);
  234. }
  235. /* convert from matrix form and print result*/
  236. switch (output_mode) {
  237. case YPR:
  238. anim_mat2ypr(matrix, angle);
  239. if (output_units==DEGREES)
  240. VSCALE(angle, angle, RAD2DEG);
  241. printf("%.12g\t%.12g\t%.12g\n", angle[0], angle[1], angle[2]);
  242. break;
  243. case AET:
  244. anim_mat2ypr(matrix, angle);
  245. if (angle[0] > 0.0) {
  246. angle[0] -= M_PI;
  247. } else {
  248. angle[0] += M_PI;
  249. }
  250. angle[1] = -angle[1];
  251. angle[2] = -angle[2];
  252. if (output_units==DEGREES)
  253. VSCALE(angle, angle, RAD2DEG);
  254. printf("%.12g\t%.12g\t%.12g\n", angle[0], angle[1], angle[2]);
  255. break;
  256. case XYZ:
  257. anim_mat2zyx(matrix, angle);
  258. if (output_units==DEGREES)
  259. VSCALE(angle, angle, RAD2DEG);
  260. printf("%.12g\t%.12g\t%.12g\n", angle[0], angle[1], angle[2]);
  261. break;
  262. case QUAT:
  263. anim_mat2quat(quat, matrix);
  264. printf("%.12g\t%.12g\t%.12g\t%.12g\n", quat[0], quat[1], quat[2], quat[3]);
  265. break;
  266. case MAT:
  267. anim_mat_print(stdout, matrix, 0);
  268. printf("\n");
  269. }
  270. }
  271. return 0;
  272. }
  273. /*
  274. * Local Variables:
  275. * mode: C
  276. * tab-width: 8
  277. * indent-tabs-mode: t
  278. * c-file-style: "stroustrup"
  279. * End:
  280. * ex: shiftwidth=4 tabstop=8
  281. */