~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Tina4/src/draw/paint/draw_tri.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /**@(#)
  2 **/
  3 #include <math.h>
  4 #include <values.h>
  5 #include <tina/sys.h>
  6 #include <tina/sysfuncs.h>
  7 #include <tina/math.h>
  8 #include <tina/mathfuncs.h>
  9 #include <tina/vision.h>
 10 #include <tina/tv.h>
 11 #include <tina/tvfuncs.h>
 12 #include <tina/draw.h>
 13 #include <tina/drawfuncs.h>
 14 
 15 void    draw_triangle3(Tv * tv, Vec3 * tri)
 16 
 17 /* a 3 vector of VEC3 */
 18 {
 19     if (tv == NULL)
 20         return;
 21 
 22     tv_line3(tv, tri[0], tri[1]);
 23     tv_line3(tv, tri[1], tri[2]);
 24     tv_line3(tv, tri[2], tri[0]);
 25 }
 26 
 27 void    draw_triangle3_fill(Tv * tv, Vec3 * tri, int col)
 28 
 29 /* a 3 vector of VEC3 */
 30 
 31 {
 32     Ipos    p[3] = {{Ipos_id}, {Ipos_id}, {Ipos_id}};
 33     Ipos    dif[3] = {{Ipos_id}, {Ipos_id}, {Ipos_id}};
 34     int     lx, ux, ly, uy;
 35     int     width, height;
 36     int     i, j;
 37 
 38     if (tv == NULL)
 39         return;
 40 
 41     width = tv_get_width(tv);
 42     height = tv_get_height(tv);
 43     tv_set_color(tv, col);
 44     draw_triangle3(tv, tri);
 45     for (i = 0; i < 3; ++i)
 46         p[i] = tv_proj3(tv, tri[i]);
 47 
 48     for (i = 0; i < 3; ++i)
 49     {
 50         j = (i + 1) % 3;
 51         dif[i] = ipos_diff(p[j], p[i]);
 52     }
 53 
 54     ly = MIN3(ipos_y(p[0]), ipos_y(p[1]), ipos_y(p[2]));
 55     if (ly < 0)
 56         ly = 0;
 57     uy = MAX3(ipos_y(p[0]), ipos_y(p[1]), ipos_y(p[2]));
 58     if (uy >= height)
 59         uy = height - 1;
 60 
 61     for (i = ly; i < uy; ++i)
 62     {
 63         lx = width;
 64         ux = 0;
 65         for (j = 0; j < 3; ++j)
 66         {
 67             if (i == ipos_y(p[j]) || i == ipos_y(p[(j + 1) % 3]) ||
 68                 BETWEEN(i, ipos_y(p[j]), ipos_y(p[(j + 1) % 3])))
 69             {
 70                 int     x;
 71 
 72                 if (ipos_y(dif[j]) == 0)
 73                 {               /* horizontal line */
 74                     x = MIN(ipos_x(p[j]), ipos_x(p[(j + 1) % 3]));
 75                     if (x < lx)
 76                         lx = x;
 77                     x = MAX(ipos_x(p[j]), ipos_x(p[(j + 1) % 3]));
 78                     if (x > ux)
 79                         ux = x;
 80                     continue;
 81                 }
 82                 x = i - ipos_y(p[j]);   /* bottom of the pixel */
 83                 x = ipos_x(p[j]) + x * ipos_x(dif[j]) / ipos_y(dif[j]);
 84                 if (x < lx)
 85                     lx = x;
 86                 if (x > ux)
 87                     ux = x;
 88             } else
 89                 continue;
 90 
 91             if (i + 1 == ipos_y(p[j]) || i + 1 == ipos_y(p[(j + 1) % 3]) ||
 92                 BETWEEN(i + 1, ipos_y(p[j]), ipos_y(p[(j + 1) % 3])))
 93             {
 94                 int     x;
 95 
 96                 x = i + 1 - ipos_y(p[j]);       /* top of the pixel */
 97                 x = ipos_x(p[j]) + x * ipos_x(dif[j]) / ipos_y(dif[j]);
 98                 if (x < lx)
 99                     lx = x;
100                 if (x > ux)
101                     ux = x;
102             }
103         }
104         if (lx < ux)
105             tv_linexy(tv, lx - 1, i, ux + 1, i);
106     }
107 }
108 
109 void    shade_triangle3(Tv * tv, Vec3 * tri)
110 
111 /* a 3 vector of VEC3 */
112 {
113     Vec3    n = {Vec3_id};
114     Vec3    dif[3] = {{Vec3_id}, {Vec3_id}, {Vec3_id}};
115     int     gl, i, j;
116     double  min_dp = MAXFLOAT;
117 
118     if (tv == NULL)
119         return;
120 
121     for (i = 0; i < 3; ++i)
122     {
123         j = (i + 1) % 3;
124         dif[i] = vec3_diff(tri[j], tri[i]);
125     }
126 
127     for (i = 0; i < 3; ++i)
128         for (j = i + 1; j < 3; ++j)
129         {
130             double  dp = fabs(vec3_dot(dif[i], dif[j]));
131 
132             if ((i == 0 && j == 1) || dp < min_dp)
133             {
134                 min_dp = dp;
135                 n = vec3_cross(dif[i], dif[j]);
136             }
137         }
138 
139     n = vec3_unit(n);
140     gl = (int)(64.0 + 191.0 * fabs(vec3_dot(n, tv->ez3)));
141     if (gl > 255)
142         gl = 255;
143     if (gl < 0)
144         gl = 0;
145     draw_triangle3_fill(tv, tri, (int) tv->cmap_data_visible->std_lut[gl]);
146 }
147 
148 /* ARGSUSED quieten lint */
149 static double tri_closest_along_tv_ez3(Vec3 * tri, int type, Tv * tv)
150 {
151     int     i;
152     double  max = MINFLOAT;
153 
154     for (i = 0; i < 3; ++i)
155     {
156         double  dp = -vec3_dot(vec3_diff(tri[i], tv->centre3), tv->ez3);
157 
158         if (i == 0 || dp > max)
159             max = dp;
160     }
161     return (max);
162 }
163 
164 void    draw_ordered_tris3_list(Tv * tv, List * tris)
165 {
166     if (tv == NULL)
167         return;
168 
169     tris = list_copy(tris, (void *(*) ()) NULL, NULL);
170     tris = sort_list(tris, tri_closest_along_tv_ez3, (void *) tv);
171     reclist_list_draw(tv, tris, TRIANGLE3, shade_triangle3, NULL);
172 }
173 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.