Code

add simplified feed_path_to_cairo functions
[inkscape.git] / src / display / nr-3dutils.cpp
1 /*
2  * 3D utils.
3  *
4  * Authors:
5  *   Jean-Rene Reinhard <jr@komite.net>
6  *
7  * Copyright (C) 2007 authors
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #include <glib/gmessages.h>
14 #include "libnr/nr-pixblock.h"
15 #include "libnr/nr-matrix.h"
16 #include "display/nr-3dutils.h"
17 #include <cmath>
19 namespace NR {
21 #define BEGIN 0 // TOP or LEFT
22 #define MIDDLE 1
23 #define END 2 // BOTTOM or RIGHT
25 #define START(v) ((v)==BEGIN? 1 : 0)
26 #define FINISH(v) ((v)==END? 1 : 2)
28 signed char K_X[3][3][3][3] = {
29     //K_X[TOP]
30     {
31         //K_X[TOP][LEFT]
32         {
33             { 0,  0,  0},
34             { 0, -2,  2},
35             { 0, -1,  1}
36         },
37         {
38             { 0,  0,  0},
39             {-2,  0,  2},
40             {-1,  0,  1}
41         },
42         {
43             { 0,  0,  0},
44             {-2,  2,  0},
45             {-1,  1,  0}
46         }
47     },
48     //K_X[MIDDLE]
49     {
50         //K_X[MIDDLE][LEFT]
51         {
52             { 0, -1,  1},
53             { 0, -2,  2},
54             { 0, -1,  1}
55         },
56         {
57             {-1,  0,  1},
58             {-2,  0,  2},
59             {-1,  0,  1}
60         },
61         {
62             {-1,  1,  0},
63             {-2,  2,  0},
64             {-1,  1,  0}
65         }
66     },
67     //K_X[BOTTOM]
68     {
69         //K_X[BOTTOM][LEFT]
70         {
71             { 0, -1,  1},
72             { 0, -2,  2},
73             { 0,  0,  0}
74         },
75         {
76             {-1,  0,  1},
77             {-2,  0,  2},
78             { 0,  0,  0}
79         },
80         {
81             {-1,  1,  0},
82             {-2,  2,  0},
83             { 0,  0,  0}
84         }
85     }
86 };
88 //K_Y is obtained by transposing K_X globally and each of its components
90 gdouble FACTOR_X[3][3] = {
91     {2./3, 1./3, 2./3},
92     {1./2, 1./4, 1./2},
93     {2./3, 1./3, 2./3}
94 };
96 //FACTOR_Y is obtained by transposing FACTOR_X
98 inline
99 int get_carac(int i, int len, int delta) {
100     if (i < delta)
101         return BEGIN;
102     else if (i > len - 1 - delta)
103         return END;
104     else
105         return MIDDLE;
108 //assumes in is RGBA
109 //should be made more resistant
110 void compute_surface_normal(Fvector &N, gdouble ss, NRPixBlock *in, int i, int j, int dx, int dy) {
111     int w = in->area.x1 - in->area.x0;
112     int h = in->area.y1 - in->area.y0;
113     int k, l, alpha_idx, alpha_idx_y;
114     int x_carac, y_carac;
115     gdouble alpha;
116     gdouble accu_x;
117     gdouble accu_y;
118     unsigned char *data = NR_PIXBLOCK_PX (in);
119     g_assert(NR_PIXBLOCK_BPP(in) == 4);
120     x_carac = get_carac(j, w, dx); //LEFT, MIDDLE or RIGHT
121     y_carac = get_carac(i, h, dy); //TOP, MIDDLE or BOTTOM
122     alpha_idx = 4*(i*w + j);
123     accu_x = 0;
124     accu_y = 0;
125     for (k = START(y_carac); k <= FINISH(y_carac); k++) {
126         alpha_idx_y = alpha_idx + 4*(k-1)*dy*w;
127         for (l = START(x_carac); l <= FINISH(x_carac); l++) {
128             alpha = (data + alpha_idx_y + 4*dx*(l-1))[3];
129             accu_x += K_X[y_carac][x_carac][k][l] * alpha / 255;
130             accu_y += K_X[x_carac][y_carac][l][k] * alpha / 255;
131         }
132     }
133     N[X_3D] = -1 * ss * FACTOR_X[y_carac][x_carac] * accu_x / dx;
134     N[Y_3D] = -1 * ss * FACTOR_X[x_carac][y_carac] * accu_y / dy;
135     N[Z_3D] = 1;
136     normalize_vector(N);
137     //std::cout << "(" << N[X_3D] << ", " << N[Y_3D] << ", " << N[Z_3D] << ")" << std::endl;
140 void convert_coord(gdouble &x, gdouble &y, gdouble &z, Matrix const &trans) {
141     Point p = Point(x, y);
142     p *= trans;
143     x = p[X];
144     y = p[Y];
145     z *= trans[0];
148 gdouble norm(const Fvector &v) {
149     return sqrt(v[X_3D]*v[X_3D] + v[Y_3D]*v[Y_3D] + v[Z_3D]*v[Z_3D]);
152 void normalize_vector(Fvector &v) {
153     gdouble nv = norm(v);
154     //TODO test nv == 0
155     for (int j = 0; j < 3; j++) {
156         v[j] /= nv;
157     }
160 gdouble scalar_product(const Fvector &a, const Fvector &b) {
161     return  a[X_3D] * b[X_3D] +
162             a[Y_3D] * b[Y_3D] +
163             a[Z_3D] * b[Z_3D];
166 void normalized_sum(Fvector &r, const Fvector &a, const Fvector &b) {
167     r[X_3D] = a[X_3D] + b[X_3D];
168     r[Y_3D] = a[Y_3D] + b[Y_3D];
169     r[Z_3D] = a[Z_3D] + b[Z_3D];
170     normalize_vector(r);
173 }/* namespace NR */
175 /*
176   Local Variables:
177   mode:c++
178   c-file-style:"stroustrup"
179   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
180   indent-tabs-mode:nil
181   fill-column:99
182   End:
183 */
184 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :