Mercurial > MadButterfly
annotate src/rotate.c @ 779:8e9481bf1cc0
Avoid float divide to improve performance
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 30 Aug 2010 13:43:01 +0800 |
parents | 530bb7728546 |
children | 586e50f82c1f |
rev | line source |
---|---|
117 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <math.h> | |
186
530bb7728546
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
Thinker K.F. Li <thinker@branda.to>
parents:
185
diff
changeset
|
5 #include "mb_animate.h" |
117 | 6 |
7 static float comp_mb_timeval_ratio(const mb_timeval_t *a, | |
8 const mb_timeval_t *b) { | |
9 float ratio; | |
10 | |
11 ratio = (float)MB_TIMEVAL_SEC(a) * 1000000.0 + (float)MB_TIMEVAL_USEC(a); | |
12 ratio /= (float)MB_TIMEVAL_SEC(b) * 1000000.0 + (float)MB_TIMEVAL_USEC(b); | |
13 return ratio; | |
14 } | |
15 | |
16 /*! \brief Animation action to rotate a coordinate. | |
17 */ | |
18 struct _mb_rotate { | |
19 mb_action_t action; | |
20 | |
21 co_aix angle1, angle2; | |
22 coord_t *coord; | |
23 | |
24 mb_timeval_t start_time; | |
25 const mb_timeval_t *playing_time; | |
26 }; | |
27 typedef struct _mb_rotate mb_rotate_t; | |
28 | |
29 static void mb_rotate_start(mb_action_t *act, | |
30 const mb_timeval_t *now, | |
31 const mb_timeval_t *playing_time, | |
32 redraw_man_t *rdman) { | |
33 mb_rotate_t *rotate = (mb_rotate_t *)act; | |
34 co_aix *matrix; | |
35 float _sin, _cos; | |
36 | |
37 _sin = sinf(rotate->angle1); | |
38 _cos = cosf(rotate->angle1); | |
39 | |
40 matrix = rotate->coord->matrix; | |
41 memset(matrix, 0, sizeof(co_aix) * 6); | |
42 matrix[0] = _cos; | |
43 matrix[1] = -_sin; | |
44 matrix[3] = _sin; | |
45 matrix[4] = _cos; | |
46 rdman_coord_changed(rdman, rotate->coord); | |
47 | |
48 MB_TIMEVAL_CP(&rotate->start_time, now); | |
49 rotate->playing_time = playing_time; | |
50 } | |
51 | |
52 static void mb_rotate_step(mb_action_t *act, const mb_timeval_t *now, | |
53 redraw_man_t *rdman) { | |
54 mb_rotate_t *rotate = (mb_rotate_t *)act; | |
55 mb_timeval_t diff; | |
56 co_aix *matrix; | |
57 float ratio; | |
58 float angle; | |
59 float _sin, _cos; | |
60 | |
61 MB_TIMEVAL_CP(&diff, now); | |
62 MB_TIMEVAL_DIFF(&diff, &rotate->start_time); | |
63 ratio = comp_mb_timeval_ratio(&diff, rotate->playing_time); | |
64 | |
65 angle = rotate->angle1 * (1 - ratio) + rotate->angle2 * ratio; | |
66 _sin = sinf(angle); | |
67 _cos = cosf(angle); | |
68 | |
69 matrix = rotate->coord->matrix; | |
70 matrix[0] = _cos; | |
71 matrix[1] = -_sin; | |
72 matrix[3] = _sin; | |
73 matrix[4] = _cos; | |
74 rdman_coord_changed(rdman, rotate->coord); | |
75 } | |
76 | |
77 static void mb_rotate_stop(mb_action_t *act, const mb_timeval_t *now, | |
78 redraw_man_t *rdman) { | |
79 mb_rotate_t *rotate = (mb_rotate_t *)act; | |
80 co_aix *matrix; | |
81 float _sin, _cos; | |
82 | |
83 _sin = sinf(rotate->angle2); | |
84 _cos = cosf(rotate->angle2); | |
85 | |
86 matrix = rotate->coord->matrix; | |
87 matrix[0] = _cos; | |
88 matrix[1] = -_sin; | |
89 matrix[3] = _sin; | |
90 matrix[4] = _cos; | |
91 rdman_coord_changed(rdman, rotate->coord); | |
92 } | |
93 | |
94 static void mb_rotate_free(mb_action_t *act) { | |
95 free(act); | |
96 } | |
97 | |
98 mb_action_t *mb_rotate_new(float angle1, float angle2, | |
99 coord_t *coord, | |
100 mb_word_t *word) { | |
101 mb_rotate_t *rotate; | |
102 | |
103 rotate = (mb_rotate_t *)malloc(sizeof(mb_rotate_t)); | |
104 if(rotate == NULL) | |
105 return NULL; | |
106 | |
107 rotate->angle1 = angle1; | |
108 rotate->angle2 = angle2; | |
109 rotate->coord = coord; | |
110 | |
111 rotate->action.start = mb_rotate_start; | |
112 rotate->action.step = mb_rotate_step; | |
113 rotate->action.stop = mb_rotate_stop; | |
114 rotate->action.free = mb_rotate_free; | |
115 | |
116 mb_word_add_action(word, (mb_action_t *)rotate); | |
117 | |
118 return (mb_action_t *)rotate; | |
119 } |