home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / hull.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  3KB  |  119 lines

  1. /*
  2.  * Hull.C - methods for hull manipulations.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  */
  17.  
  18. #include <values.h>
  19. #include "Hull.h"
  20.  
  21. //___________________________________________________________ Hull
  22.  
  23. implementTable(HullSymtab, rcString, HullPtr);
  24.  
  25. Hull::Hull()
  26. : primitives(new GeoObjectList(10))
  27. {}
  28.  
  29. Hull::~Hull()
  30. {
  31. #ifndef OLD_STYLE_CPP
  32.   // AT&T 2.x has problems: too compilcated pointer expression
  33.   for (register long i=0; i<primitives->count(); i++)
  34.     delete primitives->item(i);
  35. #endif
  36.  
  37.   delete primitives;
  38. }
  39.  
  40. void Hull::addPrimitive(GeoObject* obj)
  41. {
  42.   primitives->append(obj);
  43. }
  44.  
  45. long Hull::numPrimitives() const
  46. {
  47.   return primitives->count();
  48. }
  49.  
  50. /*
  51.  * Intersect ray with hull primitives and calculate closest object
  52.  * and distance to this object.
  53.  * intersect return TRUE if hit occured, FALSE otherwise.
  54.  */
  55.  
  56. int Hull::intersect(const Ray& ray, real& dist, GeoObject*& obj) const
  57. {
  58.   int hit = FALSE;
  59.   TransMatrix* itrans;
  60.  
  61.   dist = MAXFLOAT;
  62.   obj = NULL;
  63.  
  64.   for (register long i=0; i<primitives->count(); i++) {
  65.  
  66.     /*
  67.      * primitive has transformation matrix attached 
  68.      *  -> transform the ray
  69.      */
  70.     if ((itrans = primitives->item(i)->getInvTrans()) != NULL) {
  71.       Ray newRay(ray);
  72.       real distfact = newRay.transform(*itrans);
  73.  
  74.       /*
  75.        * Transformimg the ray can change the distance between the
  76.        * ray origin and the Point of intersection. We save the amount
  77.        * the is "stretched" and later devide the computed distance
  78.        * by this amount.
  79.        */
  80.       dist *= distfact;
  81.       if (primitives->item(i)->intersect(newRay, EPSILON*distfact, dist)) {
  82.     obj = primitives->item(i);
  83.     hit = TRUE;
  84.       }
  85.       dist /= distfact;
  86.     }
  87.     else {
  88.       if (primitives->item(i)->intersect(ray, EPSILON, dist)) {
  89.     obj = primitives->item(i);
  90.     hit = TRUE;
  91.       }
  92.     }
  93.   }
  94.   return hit;
  95. }
  96.  
  97. /*
  98.  * convertToPolygonList tesselates all the primitives in the hull 
  99.  * and returns the result as a list of polygons.
  100.  * If there is no polygon in the hull, a empty polygon list is
  101.  * returned.
  102.  */
  103.  
  104. PolygonList* Hull::convertToPolygonList(const BoundingBox& bbox) const
  105. {
  106.   PolygonList* polys = new PolygonList;
  107.   PolygonList* polytmp;
  108.   
  109.   for (register long i=0; i<primitives->count(); i++) {
  110.     if ((polytmp = primitives->item(i)->tesselate(bbox)) != NULL) {
  111.       for (register long j=0; j<polytmp->count(); j++)
  112.     polys->append(polytmp->item(j));
  113.       delete polytmp;
  114.     }
  115.   }
  116.  
  117.   return polys;
  118. }
  119.