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

Linux Cross Reference
Tina4/src/tools/terrain/trn_procs.c

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

  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <tina/sys.h>
  4 #include <tina/sysfuncs.h>
  5 #include <tina/math.h>
  6 #include <tina/mathfuncs.h>
  7 #include <tina/vision.h>
  8 #include <tina/visionfuncs.h>
  9 #include <tina/tv.h>
 10 #include <tina/tvfuncs.h>
 11 #include <tina/draw.h>
 12 #include <tina/drawfuncs.h>
 13 #include <tina/image.h>
 14  
 15 /* needed for triangle */
 16 #define REAL double
 17  
 18 #include <tina/triangle.h>
 19 
 20 #define IMAGE_FILL 0
 21 #define SHADE_FILL 1
 22 #define MEAN_FILL  2
 23 
 24 Tv     *terrain_tv(void);
 25 
 26 static Terrain_data *terrain = NULL;
 27 static Imrect *im = NULL;
 28 static Imrect *shade_im = NULL;
 29 static Imrect *mean_im = NULL;
 30 
 31 static float scalez = 0.25;
 32 static int samplex = 16, sampley = 16;
 33 
 34 static Bool show_top = true;
 35 static Bool show_bot = false;
 36 static Bool show_lines = true;
 37 static Bool show_fill = false;
 38 static Bool show_all = false;
 39 
 40 static int fill_type = IMAGE_FILL;
 41 /* static int line_col; */
 42 
 43 void    terr_fill_set(int new_fill_type)
 44 {
 45     fill_type = new_fill_type;
 46 }
 47 
 48 /*
 49 void    terr_line_col_set(int col)
 50 {
 51     line_col = col;
 52 }
 53 */
 54 
 55 void    terr_show_lines_set(Bool show)
 56 {
 57     show_lines = show;
 58 }
 59 
 60 void    terr_show_all_set(Bool show)
 61 {
 62     show_all = show;
 63 }
 64 
 65 void    terr_show_fill_set(Bool show)
 66 {
 67     show_fill = show;
 68 }
 69 
 70 void     terr_show(Bool top, Bool bot)
 71 {
 72     show_top = top;
 73     show_bot = bot;
 74 }
 75 
 76 void    terr_im_set(Imrect * new_im)
 77 {
 78     im = new_im;
 79 }
 80 
 81 Imrect *terr_im_get(void)
 82 {
 83     return (im);
 84 }
 85 
 86 void    terr_samplex_set(int sx)
 87 {
 88     samplex = sx;
 89 }
 90 
 91 int     terr_samplex_get(void)
 92 {
 93     return (samplex);
 94 }
 95 
 96 void    terr_sampley_set(int sy)
 97 {
 98     sampley = sy;
 99 }
100 
101 int     terr_sampley_get(void)
102 {
103     return (sampley);
104 }
105 
106 void    terr_scalez_set(double sz)
107 {
108     scalez = sz;
109 }
110 
111 double  terr_scalez_get(void)
112 {
113     return (scalez);
114 }
115 
116 void    terrain_skeldraw(Tv * tv)
117 {
118     if (terrain == NULL)
119         return;
120 
121     tv_terrain_skel(tv, terrain->data, terrain->mask, terrain->m, terrain->n);
122 }
123 
124 static int patch_shade(int i, int j, Tv * tv)
125 {
126     Vec3    p00 = {Vec3_id};
127     Vec3    p01 = {Vec3_id};
128     Vec3    p10 = {Vec3_id};
129     Vec3    n = {Vec3_id};
130 
131     if (tv == NULL)
132         return (0);
133     p00 = terrain->data[i][j];
134     p01 = terrain->data[i][j + 1];
135     p10 = terrain->data[i + 1][j];
136     /* BUGFIX Vec3 p11; p11 = terrain->data[i + 1][j + 1]; */
137 
138     n = vec3_unit(vec3_cross(vec3_diff(p10, p00), vec3_diff(p01, p00)));
139     return ((int) (64.0 + 191.0 * fabs(vec3_dot(n, tv->ez3))));
140 }
141 
142 static int patch_mean(int i, int j)
143 {
144     double  sum = 0;
145 
146     sum += vec3_z(terrain->data[i][j]);
147     sum += vec3_z(terrain->data[i][j + 1]);
148     sum += vec3_z(terrain->data[i + 1][j]);
149     sum += vec3_z(terrain->data[i + 1][j + 1]);
150     sum /= 4.0 * scalez;
151     return ((sum > 255) ? 255 : sum);
152 }
153 
154 static Imrect *get_image_for_surf(int (*intensity_func) ( /* ??? */ ), void *data)
155 {
156     Imregion *region;
157     Imrect *im;
158     int     n, m;
159     int     i, j;
160     int     x, y;
161     int     lx, ux, ly, uy;
162     double  dx, dy;
163     int     g, *row;
164 
165     if (terrain == NULL)
166         return (NULL);
167 
168     m = terrain->m;
169     n = terrain->n;
170 
171     lx = vec3_x(terrain->data[0][0]);
172     ly = vec3_y(terrain->data[0][0]);
173     ux = vec3_x(terrain->data[m - 1][n - 1]) + 1;
174     uy = vec3_y(terrain->data[m - 1][n - 1]) + 1;
175     dx = (double) (ux - lx) / (n - 1);
176     dy = (double) (uy - ly) / (m - 1);
177 
178     region = roi_alloc(lx, ly, ux, uy);
179     im = im_alloc(uy, ux, region, uchar_v);
180     rfree((void *) region);
181 
182     row = ivector_alloc(lx, ux);
183     for (i = 0; i < m - 1; i++)
184     {
185         for (j = 0; j < n - 1; j++)
186         {
187             g = intensity_func(i, j, data);
188             for (x = j * dx; x < (j + 1) * dx && x + lx < ux; x++)
189                 row[lx + x] = g;
190         }
191         for (y = i * dy; y < (i + 1) * dy && y + ly < uy; y++)
192             im_put_row(row, im, y + ly, lx, ux);
193     }
194     ivector_free((void *) row, lx);
195     return (im);
196 }
197 
198 void    terrain_fulldraw(Tv * tv)
199 {
200     int     n, m;
201 
202     if (terrain == NULL)
203         return;
204 
205     n = terrain->n;
206     m = terrain->m;
207 
208     /* tv_set_color(tv, line_col); */
209     (void) tv_set_op(tv, (show_lines == true) ? rop_copy : rop_null);
210     tv_terrain_hidden_init(tv, show_bot, show_top);
211     if (show_fill == true)
212     {
213         switch (fill_type)
214         {
215         case IMAGE_FILL:
216             tv_terrain_fill3(tv, terrain->data, m, n, im);
217             break;
218         case SHADE_FILL:
219             tv_terrain_fill3(tv, terrain->data, m, n, shade_im);
220             break;
221         case MEAN_FILL:
222             tv_terrain_fill3(tv, terrain->data, m, n, mean_im);
223             break;
224         }
225     } else if (show_all)
226         tv_terrain3(tv, terrain->data, m, n);
227     else
228         tv_terrain_hidden3(tv, terrain->data, m, n);
229     (void) tv_set_op(tv, rop_copy);
230 }
231 
232 void    terrain_backdraw(Tv * tv)
233 {
234 }
235 
236 void    terr_terrain_set(Terrain_data * new_terrain)
237 {
238     terrain_data_free(terrain);
239     terrain = new_terrain;
240     im_free(shade_im);
241     shade_im = get_image_for_surf(patch_shade, (void *) terrain_tv());
242     im_free(mean_im);
243     mean_im = get_image_for_surf(patch_mean, NULL);
244 }
245 
246 void    terrain_from_image(void)
247 {
248     if (im == NULL)
249         return;
250 
251     terrain_data_free(terrain);
252     terrain = im_surface(im, (Imrect *) NULL, samplex, sampley, scalez);
253     im_free(shade_im);
254     shade_im = get_image_for_surf(patch_shade, (void *) terrain_tv());
255     im_free(mean_im);
256     mean_im = get_image_for_surf(patch_mean, NULL);
257 }
258 
259 void    terrain_init(Tv * tv)
260 {
261     Vec3    centre = {Vec3_id};
262     Vec3    aim = {Vec3_id};
263     Vec3    down = {Vec3_id};
264     float   radius, pscale;
265     int     m, n;
266 
267     if (tv == NULL || terrain == NULL)
268         return;
269 
270     m = terrain->m;
271     n = terrain->n;
272     centre = terrain->data[m / 2][n / 2];
273     radius = 0.5 * vec3_mod(vec3_diff(terrain->data[0][0], terrain->data[m - 1][n - 1]));
274     pscale = 3;
275     /**
276     aim = vec3_unit(vec3(1.0, 1.0, -1.0));
277     down = vec3_minus(vec3_ey());
278     tv_set_axis(tv, vec3_minus(vec3_ez()));
279     **/
280     aim = vec3_unit(vec3(0.0, -0.5, 1.0));
281     down = vec3_ey();
282     tv_camera3(tv, centre, radius, pscale, aim, down);
283     tv_set_axis(tv, vec3_ez());
284 }
285 
286 Tv     *terrain_tv(void)
287 {
288     static Tv *tv = NULL;
289 
290     if (tv != NULL)
291         return (tv);
292 
293     tv = tv_create("Terrain");
294     (void) tv_set_backdraw(tv, terrain_backdraw);
295     (void) tv_set_fulldraw(tv, terrain_fulldraw);
296     (void) tv_set_skeldraw(tv, terrain_skeldraw);
297     tv_set_init(tv, terrain_init);
298     (void) tv_set_zoomlevel(tv, ZOOMGR);
299     return (tv);
300 }
301 
302 static void triangle_init(struct triangulateio *in, struct triangulateio *out)
303 {
304   /* initialise the input triangle structure */
305 
306   in->pointlist = NULL;
307   in->pointattributelist = NULL;
308   in->pointmarkerlist = NULL;
309   in->numberofpoints = 0;
310   in->numberofpointattributes = 0;
311 
312   in->trianglelist = NULL;
313   in->triangleattributelist = NULL;
314   in->trianglearealist = NULL;
315   in->neighborlist = NULL;
316   in->numberoftriangles = 0;
317   in->numberofcorners = 0;
318   in->numberoftriangleattributes = 0;
319 
320   in->segmentlist = NULL;
321   in->segmentmarkerlist = NULL;
322   in->numberofsegments = 0;
323 
324   in->holelist = NULL;
325   in->numberofholes = 0;
326 
327   in->regionlist = NULL;
328   in->numberofregions = 0;
329 
330   in->edgelist = NULL;
331   in->edgemarkerlist = NULL;
332   in->normlist = NULL;
333   in->numberofedges = 0;
334 
335   /* initialise the output triangle structure */
336 
337   out->pointlist = NULL;
338   out->pointattributelist = NULL;
339   out->pointmarkerlist = NULL;
340   out->numberofpoints = 0;
341   out->numberofpointattributes = 0;
342 
343   out->trianglelist = NULL;
344   out->triangleattributelist = NULL;
345   out->trianglearealist = NULL;
346   out->neighborlist = NULL;
347   out->numberoftriangles = 0;
348   out->numberofcorners = 0;
349   out->numberoftriangleattributes = 0;
350 
351   out->segmentlist = NULL;
352   out->segmentmarkerlist = NULL;
353   out->numberofsegments = 0;
354 
355   out->holelist = NULL;
356   out->numberofholes = 0;
357 
358   out->regionlist = NULL;
359   out->numberofregions = 0;
360 
361   out->edgelist = NULL;
362   out->edgemarkerlist = NULL;
363   out->normlist = NULL;
364   out->numberofedges = 0;
365 }
366 
367 /* same_side: returns true if pixel in question is on the
368    same side of the line (defined by p1, p2) as p3 */
369 
370 static Bool same_side(Vec2 p1, Vec2 p2, Vec2 p3, Vec2 pix)
371 {
372   float m, p3test, pixtest;
373   
374   /* vertical line case */
375   if (vec2_x(p1) == vec2_x(p2))
376     {
377       /* both p3 and pix to right of line */
378       if ((vec2_x(p3) > vec2_x(p1)) && (vec2_x(pix) >= vec2_x(p1)))
379         return(true);
380       /* both p3 and pix to left of line */
381       if ((vec2_x(p3) < vec2_x(p1)) && (vec2_x(pix) <= vec2_x(p1)))
382         return(true);
383     }
384 
385   /* horizontal line case */
386   else if (vec2_y(p1) == vec2_y(p2))
387     {
388       /* both p3 and pix above line */
389       if ((vec2_y(p3) > vec2_y(p1)) && (vec2_y(pix) >= vec2_y(p1)))
390         return(true);
391       /* both p3 and pix below line */
392       if ((vec2_y(p3) < vec2_y(p1)) && (vec2_y(pix) <= vec2_y(p1)))
393         return(true);
394     }
395 
396   /* sloping line case */
397   else
398     {
399       /* find the line gradient */
400       m = (vec2_y(p2) - vec2_y(p1)) / (vec2_x(p2) - vec2_x(p1));
401       
402       if (abs(m) <= 1)
403         {
404           /* use x knowns, look at y vals */
405           p3test = m * (vec2_x(p3) - vec2_x(p1)) + vec2_y(p1);
406           pixtest = m * (vec2_x(pix) - vec2_x(p1)) + vec2_y(p1);
407 
408           /* both points below line */
409           if ((p3test > vec2_y(p3)) && (pixtest >= vec2_y(pix)))
410             return(true);
411           /* both points above line */
412           if ((p3test < vec2_y(p3)) && (pixtest <= vec2_y(pix)))
413             return(true);
414         }
415       else
416         {
417           /* use y knowns, look at x vals */
418           p3test = vec2_x(p1) + (vec2_y(p3) - vec2_y(p1)) / m;
419           pixtest = vec2_x(p1) + (vec2_y(pix) - vec2_y(p1)) / m;
420 
421           /* both points to the left of line */
422           if ((p3test > vec2_x(p3)) && (pixtest >= vec2_x(pix)))
423             return(true);
424           /* both points to the right of line */
425           if ((p3test < vec2_x(p3)) && (pixtest <= vec2_x(pix)))
426             return(true);
427         }
428     }
429   
430   return(false);
431 }
432 
433 /* interp_val: given a triangle in 3d space (p1, p2, p3)
434    what is the z value of a point on that plane with x y
435    coordinates given by pix */
436 
437 static float interp_val(Vec3 p1, Vec3 p2, Vec3 p3, Vec2 pix)
438 {
439   Vec3 normal, interp;
440 
441   normal = vec3_cross(vec3_diff(p1, p3), vec3_diff(p2, p3));
442   interp = vec3_inter_line_plane(vec3(vec2_x(pix), vec2_y(pix), 0.0),
443                                  vec3(0.0, 0.0, 1.0),
444                                  p1, normal);
445   return(vec3_z(interp));
446 }
447 
448 /* triangulate_IM: uses delaunay triangulation routine to
449    divide up a set of points into triangles and then interpolates
450    those triangles to fill in the unknown points in the triangles */
451 /*
452 void triangulate_IM(Imrect *im)
453 {
454   struct triangulateio in, out;
455   Vec2 *lut = NULL, p1, p2, p3;
456   Vec3 t1, t2, t3;
457   int num, x, y, xmin, xmax, ymin, ymax;
458 
459   if (im == NULL || im->vtype!=float_v)
460     {
461       error("No IM or IM not of type float", non_fatal);
462       return;
463     }
464 
465   triangle_init(&in, &out);
466 
467   FOR_IM(im->region, y, x)
468     if (IM_FLOAT(im, y, x))
469       in.numberofpoints++;
470 
471   lut = (Vec2 *)calloc(in.numberofpoints, sizeof(Vec2));
472 
473 
474   in.pointlist = (REAL *)malloc(in.numberofpoints * 2 * sizeof(REAL));
475 
476   num = 0;
477 
478   FOR_IM(im->region, y, x)
479     {
480       if (IM_FLOAT(im, y, x) == 0.0)
481         continue;
482       
483       vec2_x(lut[num]) = x;
484       vec2_y(lut[num]) = y;
485       
486       in.pointlist[2*num] = x;
487       in.pointlist[2*num+1] = y;
488       num++;
489     }
490   
491   triangulate("zPNQ", &in, &out, NULL);
492 
493   for (num=0; num<out.numberoftriangles; num++)
494     {
495       p1 = lut[out.trianglelist[3*num]];
496       p2 = lut[out.trianglelist[3*num+1]];
497       p3 = lut[out.trianglelist[3*num+2]];
498 
499       xmin = tina_int(MIN(MIN(vec2_x(p1), vec2_x(p2)), vec2_x(p3)));
500       ymin = tina_int(MIN(MIN(vec2_y(p1), vec2_y(p2)), vec2_y(p3)));
501       xmax = tina_int(MAX(MAX(vec2_x(p1), vec2_x(p2)), vec2_x(p3)));
502       ymax = tina_int(MAX(MAX(vec2_y(p1), vec2_y(p2)), vec2_y(p3)));
503 
504       for (y=ymin; y<=ymax; y++)
505         for (x=xmin; x<=xmax; x++)
506           if ((IM_FLOAT(im, y, x) == 0.0) &&
507               same_side(p1, p2, p3, vec2(x, y)) &&
508               same_side(p1, p3, p2, vec2(x, y)) &&
509               same_side(p2, p3, p1, vec2(x, y)))
510             {
511               
512               t1 = vec3(vec2_x(p1), vec2_y(p1), 
513                         IM_FLOAT(im, tina_int(vec2_y(p1)), tina_int(vec2_x(p1))));
514               t2 = vec3(vec2_x(p2), vec2_y(p2), 
515                         IM_FLOAT(im, tina_int(vec2_y(p2)), tina_int(vec2_x(p2))));
516               t3 = vec3(vec2_x(p3), vec2_y(p3), 
517                         IM_FLOAT(im, tina_int(vec2_y(p3)), tina_int(vec2_x(p3))));
518               
519               IM_FLOAT(im, y, x) = interp_val(t1, t2, t3, vec2(x, y));
520             }
521     }
522   
523   cfree(lut);
524   free(in.pointlist);
525   free(out.trianglelist);
526 }
527 */
528 
529 /* triangulate_geom: uses delaunay triangulation routine to triangulate
530    a set of 3D points. the main triangulation routine is driven by
531    the x,y coordinates of the points. the results can then be displayed
532    in the threed tv for example */
533 
534 /* note: this proc adds the triangulation lines to the existing
535    geomlist, it does NOT free the given geomlist and return a
536    new one */
537 /*
538 List *triangulate_geom(List *geomlist)
539 {
540   struct triangulateio in, out;
541   List *ptr;
542   Point3 *point, **lut = NULL;
543   Vec3 p1, p2;
544   int num;
545 
546   if (geomlist == NULL)
547     return(geomlist);
548   
549   triangle_init(&in, &out);
550 
551   for (ptr=geomlist; ptr!=NULL; ptr=ptr->next)
552     if (ptr->type == POINT3)
553       in.numberofpoints++;
554 
555   lut = (Point3 **)calloc(in.numberofpoints, sizeof(Point3 *));
556 
557   in.pointlist = (REAL *)malloc(in.numberofpoints * 2 * sizeof(REAL));
558 
559   for (num=0, ptr=geomlist; ptr!=NULL; ptr=ptr->next)
560     {
561       if (ptr->type != POINT3)
562         continue;
563       
564       point = (Point3 *)ptr->to;
565 
566       lut[num] = point;
567       
568       in.pointlist[2*num] = vec3_x(point->p);
569       in.pointlist[2*num+1] = vec3_y(point->p);
570       num++;
571     }
572   
573   triangulate("zPNQ", &in, &out, NULL);
574 
575 
576   for (num=0; num<out.numberoftriangles; num++)
577     {
578       p1 = lut[out.trianglelist[3*num]]->p;
579       p2 = lut[out.trianglelist[3*num+1]]->p;
580       geomlist = list_addtostart(geomlist,
581                                  link_alloc((void *)line3_make(p1, p2, LINE3),
582                                             LINE3));
583 
584       p1 = lut[out.trianglelist[3*num+1]]->p;
585       p2 = lut[out.trianglelist[3*num+2]]->p;
586       geomlist = list_addtostart(geomlist,
587                                  link_alloc((void *)line3_make(p1, p2, LINE3),
588                                             LINE3));
589 
590       p1 = lut[out.trianglelist[3*num+2]]->p;
591       p2 = lut[out.trianglelist[3*num]]->p;
592       geomlist = list_addtostart(geomlist,
593                                  link_alloc((void *)line3_make(p1, p2, LINE3),
594                                             LINE3));
595     }
596   
597   cfree(lut);
598   free(in.pointlist);
599   free(out.trianglelist);
600 
601   return(geomlist);
602 }
603 */
604 

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