comparison src/coord.c @ 1067:7b4e80ab671a openvg

merge from default branch
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 01 Dec 2010 12:25:56 +0800
parents 586e50f82c1f
children
comparison
equal deleted inserted replaced
630:bd18951b51d5 1067:7b4e80ab671a
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*-
2 // vim: sw=4:ts=8:sts=4
1 /*! \brief Implement coordination tranform mechanism. 3 /*! \brief Implement coordination tranform mechanism.
2 * \file 4 * \file
3 * This file implements coordination transforming for containers. 5 * This file implements coordination transforming for containers.
4 */ 6 */
5 #include <stdio.h> 7 #include <stdio.h>
26 } 28 }
27 29
28 void matrix_mul(co_aix *m1, co_aix *m2, co_aix *dst) { 30 void matrix_mul(co_aix *m1, co_aix *m2, co_aix *dst) {
29 co_aix *_dst = dst; 31 co_aix *_dst = dst;
30 co_aix fake_dst[6]; 32 co_aix fake_dst[6];
31 33
32 if(m1 == dst || m2 == dst) 34 if(m1 == dst || m2 == dst)
33 _dst = fake_dst; 35 _dst = fake_dst;
34 36
35 mul_matrix(m1, m2, _dst); 37 mul_matrix(m1, m2, _dst);
36 38
37 if(m1 == dst || m2 == dst) { 39 if(m1 == dst || m2 == dst) {
38 dst[0] = fake_dst[0]; 40 dst[0] = fake_dst[0];
39 dst[1] = fake_dst[1]; 41 dst[1] = fake_dst[1];
58 } 60 }
59 61
60 /*! \brief Compute aggregated transform matrix. 62 /*! \brief Compute aggregated transform matrix.
61 * 63 *
62 * Base on parent's aggregated matrix if it is existed, or use transform 64 * Base on parent's aggregated matrix if it is existed, or use transform
63 * matrix as aggregated matrix. 65 * matrix as aggregated matrix.
64 */ 66 */
65 static void compute_transform_function(coord_t *visit) { 67 static void compute_transform_function(coord_t *visit) {
66 if(!coord_is_root(visit)) 68 if(!coord_is_root(visit))
67 mul_matrix(visit->parent->aggr_matrix, 69 mul_matrix(visit->parent->aggr_matrix,
68 visit->matrix, visit->aggr_matrix); 70 visit->matrix, visit->aggr_matrix);
80 */ 82 */
81 static void compute_transform_function_cached(coord_t *visit) { 83 static void compute_transform_function_cached(coord_t *visit) {
82 co_aix *p_matrix; 84 co_aix *p_matrix;
83 co_aix cache_p_matrix[6]; 85 co_aix cache_p_matrix[6];
84 co_aix cache_scale_x, cache_scale_y; 86 co_aix cache_scale_x, cache_scale_y;
85 87
86 if(!coord_is_root(visit)) { 88 if(!coord_is_root(visit)) {
87 p_matrix = coord_get_aggr_matrix(visit->parent); 89 p_matrix = coord_get_aggr_matrix(visit->parent);
88 cache_scale_x = 90 cache_scale_x =
89 sqrtf(p_matrix[0] * p_matrix[0] + p_matrix[3] * p_matrix[3]); 91 sqrtf(p_matrix[0] * p_matrix[0] + p_matrix[3] * p_matrix[3]);
90 cache_scale_y = 92 cache_scale_y =
114 } 116 }
115 117
116 void compute_reverse(co_aix *orig, co_aix *reverse) { 118 void compute_reverse(co_aix *orig, co_aix *reverse) {
117 co_aix working[6]; 119 co_aix working[6];
118 co_aix factor; 120 co_aix factor;
119 121
120 #define VEC_MAC(src, factor, dst) \ 122 #define VEC_MAC(src, factor, dst) \
121 do { \ 123 do { \
122 (dst)[0] += (src)[0] * (factor); \ 124 (dst)[0] += (src)[0] * (factor); \
123 (dst)[1] += (src)[1] * (factor); \ 125 (dst)[1] += (src)[1] * (factor); \
124 (dst)[2] += (src)[2] * (factor); \ 126 (dst)[2] += (src)[2] * (factor); \
128 reverse[1] = 0; 130 reverse[1] = 0;
129 reverse[2] = 0; 131 reverse[2] = 0;
130 reverse[3] = 0; 132 reverse[3] = 0;
131 reverse[4] = 1; 133 reverse[4] = 1;
132 reverse[5] = 0; 134 reverse[5] = 0;
133 135
134 memcpy(working, orig, sizeof(co_aix) * 6); 136 memcpy(working, orig, sizeof(co_aix) * 6);
135 137
136 factor = -working[3] / working[0]; 138 factor = -working[3] / working[0];
137 VEC_MAC(working, factor, working + 3); 139 VEC_MAC(working, factor, working + 3);
138 VEC_MAC(reverse, factor, reverse + 3); 140 VEC_MAC(reverse, factor, reverse + 3);
142 VEC_MAC(reverse + 3, factor, reverse); 144 VEC_MAC(reverse + 3, factor, reverse);
143 145
144 reverse[2] = -working[2]; 146 reverse[2] = -working[2];
145 reverse[5] = -working[5]; 147 reverse[5] = -working[5];
146 148
147 reverse[0] /= working[0]; 149 factor = 1 / working[0];
148 reverse[1] /= working[0]; 150 reverse[0] *= factor;
149 reverse[2] /= working[0]; 151 reverse[1] *= factor;
150 reverse[3] /= working[4]; 152 reverse[2] *= factor;
151 reverse[4] /= working[4]; 153 factor = 1 / working[4];
152 reverse[5] /= working[4]; 154 reverse[3] *= factor;
155 reverse[4] *= factor;
156 reverse[5] *= factor;
153 } 157 }
154 158
155 /*! \brief Update aggregate matrices of elements under a sub-tree. 159 /*! \brief Update aggregate matrices of elements under a sub-tree.
156 * 160 *
157 * A subtree is specified by the root of it. All elements in the subtree 161 * A subtree is specified by the root of it. All elements in the subtree
241 */ 245 */
242 coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) { 246 coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) {
243 coord_t *next = NULL; 247 coord_t *next = NULL;
244 248
245 ASSERT(last != NULL); 249 ASSERT(last != NULL);
246 250
247 if((!(last->flags & COF_SKIP_TRIVAL)) && 251 if((!(last->flags & COF_SKIP_TRIVAL)) &&
248 STAILQ_HEAD(last->children)) { 252 STAILQ_HEAD(last->children)) {
249 next = STAILQ_HEAD(last->children); 253 next = STAILQ_HEAD(last->children);
250 if(!(next->flags & COF_SKIP_TRIVAL)) 254 if(!(next->flags & COF_SKIP_TRIVAL))
251 return next; 255 return next;
268 coord_t *postorder_coord_subtree(coord_t *root, coord_t *last) { 272 coord_t *postorder_coord_subtree(coord_t *root, coord_t *last) {
269 coord_t *next; 273 coord_t *next;
270 274
271 if(root == last) 275 if(root == last)
272 return NULL; 276 return NULL;
273 277
274 if(last == NULL) { 278 if(last == NULL) {
275 /* Go most left leaf. */ 279 /* Go most left leaf. */
276 next = root; 280 next = root;
277 while(STAILQ_HEAD(next->children)) 281 while(STAILQ_HEAD(next->children))
278 next = STAILQ_HEAD(next->children); 282 next = STAILQ_HEAD(next->children);
321 elms[1].matrix[3] = 5; 325 elms[1].matrix[3] = 5;
322 326
323 update_aggr_matrix(elms); 327 update_aggr_matrix(elms);
324 328
325 /* | -3 5 0 | 329 /* | -3 5 0 |
326 * | 5 1 0 | 330 * | 5 1 0 |
327 * | 0 0 1 | 331 * | 0 0 1 |
328 */ 332 */
329 CU_ASSERT(elms[3].aggr_matrix[0] == -3); 333 CU_ASSERT(elms[3].aggr_matrix[0] == -3);
330 CU_ASSERT(elms[3].aggr_matrix[1] == 5); 334 CU_ASSERT(elms[3].aggr_matrix[1] == 5);
331 CU_ASSERT(elms[3].aggr_matrix[2] == 0); 335 CU_ASSERT(elms[3].aggr_matrix[2] == 0);