SyntheticScan.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:4k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. //############################################################
  2. //
  3. // SyntheticScan.cc
  4. //
  5. // Matt Ginzton
  6. // Mon Jul 27 15:42:20 PDT 1998
  7. //
  8. // "Scan" objects created analytically rather than acquired.
  9. //
  10. //############################################################
  11. #include "SyntheticScan.h"
  12. #include "MeshTransport.h"
  13. #include "TriMeshUtils.h"
  14. #define SYNTH_SPHERE 1
  15. //#define SYNTH_CUBE 1
  16. SyntheticScan::SyntheticScan (float size)
  17. {
  18.   Pnt3 p (size, size, size);
  19.   bbox = Bbox (-p, p);
  20.   set_name ("cube");
  21.   insert_resolution (12, get_name());
  22. }
  23. MeshTransport*
  24. SyntheticScan::mesh(bool perVertex, bool stripped,
  25.     ColorSource color, int colorSize)
  26. {
  27.   MeshTransport* mt = new MeshTransport;
  28.   vector<Pnt3>* vtx = new vector<Pnt3>;
  29.   vtx->reserve (8);
  30.   for (int i = 0; i < 8; i++) {
  31.     vtx->push_back (bbox.corner(i));
  32.   }
  33.   vector<short>* nrm = new vector<short>;
  34.   if (perVertex) {
  35.     nrm->reserve(24);
  36.     for (i = 0; i < 8; i++) {
  37.       pushNormalAsShorts (*nrm, bbox.corner(i).normalize());
  38.     }
  39.   } else {
  40.     nrm->reserve (36);
  41.   }
  42.   const int faceInd[12][3] = {
  43.     { 0, 1, 2 },
  44.     { 1, 3, 2 },
  45.     { 2, 3, 6 },
  46.     { 3, 7, 6 },
  47.     { 6, 7, 4 },
  48.     { 7, 5, 4 },
  49.     { 0, 4, 1 },
  50.     { 1, 4, 5 },
  51.     { 0, 6, 4 },
  52.     { 0, 2, 6 },
  53.     { 1, 5, 7 },
  54.     { 1, 7, 3 }
  55.   };
  56.   vector<int>* tri_inds = new vector<int>;
  57.   for (i = 0; i < 12; i++) {
  58.     int t1 = faceInd[i][0];
  59.     int t2 = faceInd[i][1];
  60.     int t3 = faceInd[i][2];
  61.     tri_inds->push_back (t1);
  62.     tri_inds->push_back (t2);
  63.     tri_inds->push_back (t3);
  64.     if (!perVertex) {
  65.       Pnt3 normal = cross (((*vtx)[t1] - (*vtx)[t2]),
  66.    ((*vtx)[t1] - (*vtx)[t3]));
  67.       normal.normalize();
  68.       pushNormalAsShorts (*nrm, normal);
  69.     }
  70.     if (stripped)              // end strip
  71.       tri_inds->push_back (-1);
  72.   }
  73.   mt->setVtx (vtx, MeshTransport::steal);
  74.   mt->setNrm (nrm, MeshTransport::steal);
  75.   mt->setTris (tri_inds, MeshTransport::steal);
  76.   return mt;
  77. }
  78. OccSt
  79. SyntheticScan::carve_cube  (const Pnt3 &ctr, float side)
  80. {
  81.   side /= 2;
  82.   Pnt3 ofs (side, side, side);
  83.   Bbox cube (ctr - ofs, ctr + ofs);
  84.   float radius = bbox.size() / 2.0;
  85.   Xform<float> xfInv = getXform();
  86.   xfInv.fast_invert();
  87.   bool bAllIn = true, bAllOut = true; // points of node relative to mesh
  88.   for (int i = 0; i < 8; i++) {
  89.     Pnt3 corner = cube.corner(i);
  90.     xfInv (corner);
  91. #if SYNTH_CUBE
  92.     if (bbox.outside (corner))
  93.       bAllIn = false;
  94.     else
  95.       bAllOut = false;
  96.     // check whether this node contains current corner of entire cube --
  97.     // if so, node can be neither entirely in front nor behind, so it's
  98.     // a boundary
  99.     corner = bbox.corner(i);
  100.     xformPnt (corner);
  101.     if (!cube.outside (corner))
  102.       return BOUNDARY;
  103. #else // SYNTH_SPHERE
  104.     if (corner.norm() > radius)
  105.       bAllIn = false;
  106.     else
  107.       bAllOut = false;
  108. #endif
  109.   }
  110. #if SYNTH_SPHERE
  111.   if (bAllOut) { // possible containment of sphere in voxel
  112.     Pnt3 lo = cube.min();
  113.     Pnt3 hi = cube.max();
  114.     if (lo[0] < -radius && lo[1] < -radius && lo[2] < -radius
  115. && hi[0] > radius && hi[1] > radius && hi[2] > radius)
  116.       return BOUNDARY;
  117.   }
  118. #endif
  119.   if (bAllIn)
  120.     return INSIDE;
  121.   else if (bAllOut)
  122.     return OUTSIDE;
  123.   else
  124.     return BOUNDARY;
  125. }
  126. float 
  127. SyntheticScan::closest_along_line_of_sight(const Pnt3 &p, Pnt3 &cp, 
  128.    OccSt &status_p)
  129. {
  130. #if SYNTH_CUBE
  131.   Pnt3 _p;
  132.   xf.apply_inv (p, _p);
  133.   Pnt3 c = bbox.center();
  134.   for (int i = 0; i < 3; i++)
  135.     cp[i] = (_p[i] > c[i] ? bbox.max()[i] : bbox.min()[i]);
  136.   if (bbox.outside (_p))
  137.     status_p = OUTSIDE;
  138.   else
  139.     status_p = INSIDE;
  140.   return 1.0;  // always confident
  141. #else // SYNTH_SPHERE
  142.   // ignore "line of sight" constraint
  143.   // just return closest point
  144.   float radius = bbox.size() / 2.0;
  145.   float dist_to_ctr = p.norm();
  146.   cp = p / dist_to_ctr * radius;
  147.   if (dist_to_ctr < radius) {
  148.     status_p = INSIDE;
  149.   } else {
  150.     status_p = OUTSIDE;
  151.   }
  152.   return 1.0; // always confident
  153. #endif
  154. }