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

Linux Cross Reference
Tina4/src/tv/tv_proj3.c

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

  1 /**@(#)
  2 **/
  3 #include <values.h>
  4 #include <tina/sys.h>
  5 #include <tina/math.h>
  6 #include <tina/mathfuncs.h>
  7 #include <tina/tv.h>
  8 
  9 /**orthographic projection**/
 10 
 11 static Ipos proj3_orth(Tv * tv, Vec3 v)
 12 {
 13     Ipos    pos = {Ipos_id};
 14     double  x, y;
 15 
 16     v = vec3_diff(v, tv->centre3);
 17     x = tv->cx + tv->scalex * vec3_dot(v, tv->ex3);
 18     y = tv->cy + tv->scaley * vec3_dot(v, tv->ey3);
 19     pos.x = ROUND(x);
 20     pos.y = ROUND(y);
 21     return (pos);
 22 }
 23 
 24 static void ray3_orth(Tv * tv, Ipos pos, Vec3 * p, Vec3 * v)
 25 {
 26     double  x = (pos.x - tv->cx) / tv->scalex;
 27     double  y = (pos.y - tv->cy) / tv->scaley;
 28 
 29     *p = vec3_sum3(tv->centre3, vec3_times(x, tv->ex3), vec3_times(y, tv->ey3));
 30     *v = tv->ez3;
 31 }
 32 
 33 static Vec3 backproj3_orth(Tv * tv, Ipos pos)
 34 {
 35     Vec3    p = {Vec3_id};
 36     double  x = (pos.x - tv->cx) / tv->scalex;
 37     double  y = (pos.y - tv->cy) / tv->scaley;
 38 
 39     p = vec3_sum3(tv->centre3, vec3_times(x, tv->ex3), vec3_times(y, tv->ey3));
 40     return (p);
 41 }
 42 
 43 void    tv_set_proj3_orth(Tv * tv)
 44 {
 45     tv->proj3type = ORTH;
 46     tv->proj3 = proj3_orth;
 47     tv->ray3 = ray3_orth;
 48     tv->backproj3 = backproj3_orth;
 49 }
 50 
 51 /**perspective projection**/
 52 
 53 static Ipos proj3_persp(Tv * tv, Vec3 v)
 54 {
 55     Ipos    pos = {Ipos_id};
 56     double  x, y;
 57 
 58     v = vec3_unit(vec3_diff(v, tv->pcentre));
 59     v = vec3_inter_line_plane(tv->pcentre, v, tv->centre3, tv->ez3);
 60     v = vec3_diff(v, tv->centre3);
 61     x = tv->cx + tv->scalex * vec3_dot(v, tv->ex3);
 62     y = tv->cy + tv->scaley * vec3_dot(v, tv->ey3);
 63     pos.x = ROUND(x);
 64     pos.y = ROUND(y);
 65     return (pos);
 66 }
 67 
 68 static void ray3_persp(Tv * tv, Ipos pos, Vec3 * p, Vec3 * v)
 69 {
 70     double  x = (pos.x - tv->cx) / tv->scalex;
 71     double  y = (pos.y - tv->cy) / tv->scaley;
 72     Vec3    q = {Vec3_id};
 73 
 74     q = vec3_sum3(tv->centre3, vec3_times(x, tv->ex3), vec3_times(y, tv->ey3));
 75     *p = tv->pcentre;
 76     *v = vec3_unit(vec3_diff(q, tv->pcentre));
 77 }
 78 
 79 static Vec3 backproj3_persp(Tv * tv, Ipos pos)
 80 {
 81     Vec3    p = {Vec3_id};
 82     double  x = (pos.x - tv->cx) / tv->scalex;
 83     double  y = (pos.y - tv->cy) / tv->scaley;
 84 
 85     p = vec3_sum3(tv->centre3, vec3_times(x, tv->ex3), vec3_times(y, tv->ey3));
 86     return (p);
 87 }
 88 
 89 void    tv_set_proj3_persp(Tv * tv)
 90 {
 91     tv->proj3type = PERSP;
 92     tv->proj3 = proj3_persp;
 93     tv->ray3 = ray3_persp;
 94     tv->backproj3 = backproj3_persp;
 95 }
 96 
 97 /**generic 3D projection**/
 98 
 99 Ipos    tv_proj3(Tv * tv, Vec3 p)
100 {
101     return (tv->proj3(tv, p));
102 }
103 
104 void    tv_ray3(Tv * tv, Ipos pos, Vec3 * p, Vec3 * v)
105 {
106     tv->ray3(tv, pos, p, v);
107 }
108 
109 Vec3    tv_backproj3(Tv * tv, Ipos pos)
110 {
111     return (tv->backproj3(tv, pos));
112 }
113 
114 double  tv_dist3(Tv * tv, Vec3 p)
115 {
116     if (tv == NULL)
117         return (MAXFLOAT);
118     switch (tv->proj3type)
119     {
120     case ORTH:
121         return (vec3_dot(vec3_diff(p, tv->centre3), tv->ez3));
122     case PERSP:
123         return (vec3_dist(p, tv->pcentre));
124     }
125     return (MAXFLOAT);
126 }
127 
128 Ipos    tv_zbuff_proj3(Tv * tv, Vec3 p, int *iz)
129 {
130     double  z;
131 
132     z = (tv_dist3(tv, p) - tv->zbuff->zmin) / (tv->zbuff->zmax - tv->zbuff->zmin);
133     if (z < 0.0 || z > 1.0)
134         *iz = MAXINT;
135     else
136         *iz = ROUND(MAXINT * z);
137     return (tv_proj3(tv, p));
138 }
139 
140 /**setting down and changing the 3D camera**/
141 
142 void    tv_camera3(Tv * tv, Vec3 centre, double radius, double pscale, Vec3 aim, Vec3 down)
143 {
144     tv->scalex = tv->scaley = (float)(0.5 * MIN(tv->width, tv->height) / radius);
145     tv->cx = (float)(tv->width / 2.0);
146     tv->cy = (float)(tv->height / 2.0);
147     tv->centre3 = centre;
148     tv->radius3 = (float)radius;
149     vec3_basis(aim, down, &tv->ex3, &tv->ey3, &tv->ez3);
150     tv->pscale = (float)pscale;
151     tv->pcentre = vec3_diff(centre, vec3_times(pscale * radius, tv->ez3));
152 }
153 
154 void    tv_aim3(Tv * tv, Vec3 aim)
155 {
156     vec3_basis(aim, vec3_ey(), &tv->ex3, &tv->ey3, &tv->ez3);
157 }
158 
159 void    tv_orient3(Tv * tv, Vec3 aim, Vec3 down)
160 {
161     vec3_basis(aim, down, &tv->ex3, &tv->ey3, &tv->ez3);
162     tv->pcentre = vec3_diff(tv->centre3,
163                        vec3_times(tv->pscale * tv->radius3, tv->ez3));
164 }
165 
166 void    tv_set_axis(Tv * tv, Vec3 axis)
167 {
168     tv->axis = vec3_unit(axis);
169     tv->axis_set = true;
170 }
171 
172 void    tv_unset_axis(Tv * tv)
173 {
174     tv->axis_set = false;
175 }
176 
177 double  tv_pscale(Tv * tv, double pscale)
178 {
179     double  oldpscale = tv->pscale;
180 
181     tv->pscale = (float)pscale;
182     return (oldpscale);
183 }
184 
185 void    tv_set_proj3(Tv * tv, int type)
186 {
187     if (tv == NULL)
188         return;
189 
190     switch (type)
191     {
192     case ORTH:
193         tv_set_proj3_orth(tv);
194         break;
195     case PERSP:
196         tv_set_proj3_persp(tv);
197         break;
198     }
199 }
200 

~ [ 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.