Exemplo n.º 1
0
bool
Bface::view_intersect(
   CNDCpt& p,           // Screen point at which to do intersect
   Wpt&    nearpt,      // Point on face visually nearest to p
   double& dist,        // Distance from nearpt to ray from camera
   double& d2d,         // Distance in pixels nearpt to p
   Wvec& n              // "normal" at nearpt in world coordinates
   ) const
{
   // (Bsimplex virtual method):
   // Intersection w/ ray from given screen point -- returns the point
   // on the Bface that is nearest to the given screen space point.
   // Note: the returned "near point" and "normal" are both
   //       transformed to world space.

   // Get "eye point" for computing distance.
   // Not sure if this is the same as cam->from(),
   // but it seems to be the way it's done in other
   // intersection code.
   Wpt eye = XYpt(p);

   // Make object-space ray:
   Wline ray = mesh()->inv_xform()*Wline(p); // ray in object space
   Wpt hit;

   // Try for exact intersection:
   double d;
   if (ray_intersect(ray, hit, d)) {
      // Direct hit
      nearpt = mesh()->xform()*hit;
      dist   = nearpt.dist(eye);
      d2d    = PIXEL(nearpt).dist(PIXEL(p));
      n      = (mesh()->inv_xform().transpose()*norm()).normalized();
      return true;
   }

   Wpt    hit1, hit2, hit3;
   double d1 = DBL_MAX, d2 = DBL_MAX, d3 = DBL_MAX;
   Wvec   n1, n2, n3;
   _e1->view_intersect(p, hit1, d, d1, n1);
   _e2->view_intersect(p, hit2, d, d2, n2);
   _e3->view_intersect(p, hit3, d, d3, n3);

   // Rename so d1 represents closest hit
   if (d1 > d2) {
      swap(d1, d2);
      swap(hit1, hit2);
      swap(n1, n2);
   }
   if (d1 > d3) {
      swap(d1, d3);
      swap(hit1, hit3);
      swap(n1, n3);
   }
   nearpt = mesh()->xform()*hit1;
   dist   = nearpt.dist(eye);
   d2d    = PIXEL(nearpt).dist(PIXEL(p));
   n      = n1;
   return true;
}
Exemplo n.º 2
0
void 
SKY_BOX::update_position() //centers the sky box around the camera
{
   Wpt eye = VIEW::eye();
   if (eye.dist_sqrd(xform().origin()) > 0) { //only update when really needed
      set_xform(Wtransf(eye));
      err_adv(debug, "SKY_BOX::update_position: updated skybox");
   }
}
Exemplo n.º 3
0
Wpt 
QuadtreeNode::farthest_pt(Wpt& p)
{
   Wpt ret = _v1;
   double max_dist = ret.dist(p);
   if (_v2.dist(p) > max_dist) {
      ret = _v2;
      max_dist = ret.dist(p);
   }
   if (_v3.dist(p) > max_dist) {
      ret = _v3;
   }
   return ret;
}
Exemplo n.º 4
0
void TEXT2D::draw_debug(const char* str, Wpt &pos, CVIEWptr& view)
{
   if (view->rendering() == RCOLOR_ID || view->grabbing_screen())
      return;
   
   if (!_dl.valid(view)) initialize(view);

   // GL initialization
   glPushAttrib(GL_ENABLE_BIT); // (GL_ENABLE_BIT)

   // No lighting
   glDisable(GL_LIGHTING);
   // Color

   //glColor3dv(COLOR::white.data());
   
   glRasterPos3dv(pos.data());
   glPushAttrib (GL_LIST_BIT); // (GL_LIST_BIT)
   glListBase(_dl.dl(view));  
   glCallLists(strlen(str), GL_UNSIGNED_BYTE, (GLubyte *) str);
   glPopAttrib (); // (GL_LIST_BIT)   
   
   glEnable(GL_LIGHTING);
   glPopAttrib(); // (GL_ENABLE_BIT)
   glFlush();

}
Exemplo n.º 5
0
void
Bpoint::draw_axes()
{
   const double PIX_LEN = 30;
   const double len     = world_length(loc(), PIX_LEN);

   Wtransf xf = map()->xf();
   Wpt o = xf * Wpt::Origin();
   Wpt x = xf * Wpt(len,0,0);
   Wpt y = xf * Wpt(0,len,0);
   Wpt z = xf * Wpt(0,0,len);

   GLfloat w = GLfloat(1.0 * VIEW::peek()->line_scale());
   GL_VIEW::init_line_smooth(w, GL_CURRENT_BIT);
   glDisable(GL_LIGHTING);      // GL_ENABLE_BIT

   glBegin(GL_LINES);

   // draw x, y, z in red, yellow, blue

   GL_COL(Color::red, 1);       // GL_CURRENT_BIT
   glVertex3dv(o.data());
   glVertex3dv(x.data());

   GL_COL(Color::yellow, 1);    // GL_CURRENT_BIT
   glVertex3dv(o.data());
   glVertex3dv(y.data());

   GL_COL(Color::blue, 1);      // GL_CURRENT_BIT
   glVertex3dv(o.data());
   glVertex3dv(z.data());

   glEnd();

   GL_VIEW::end_line_smooth();
}
Exemplo n.º 6
0
bool
Bedge::view_intersect(
    CNDCpt& p,           // Screen point at which to do intersect
    Wpt&    nearpt,      // Point on edge visually nearest to p
    double& dist,        // Distance from nearpt to ray from camera
    double& d2d,         // Distance in pixels nearpt to p
    Wvec& n              // "normal" at nearpt in world space
) const
{
    // (Bsimplex virtual method):
    // Intersection w/ ray from given screen point -- returns the point
    // on the Bedge that is nearest to the given screen space point.
    // Note: the returned "near point" and "normal" are both
    //       transformed to world space.

    // Find nearest point on the edge in screen-space, and make a 3D
    // ray out of it (world space, not object space):
    Wline ray(NDCline(_v1->ndc(), _v2->ndc()).project_to_seg(p));

    // Working in world space (applying mesh xf to verts), find
    // nearest point on the edge to the ray:
    nearpt = Wline(_v1->wloc(), _v2->wloc()).project_to_seg(ray);

    // Compute world and screen distances
    dist = nearpt.dist(ray.point());
    d2d  = PIXEL(nearpt).dist(PIXEL(ray.point()));

    // Return a "normal" vector:
    Wvec n1;
    if (nfaces() == 2)
        n1 = norm();
    else if (nfaces() == 1)
        n1 = get_face()->norm();
    else
        n1 = (ray.point() - nearpt).normalized();

    // Transform the normal properly:
    n = (_mesh->inv_xform().transpose()*n1).normalized();

    return 1;
}
Exemplo n.º 7
0
//! Given an initial slash gesture (or delayed slash) near the
//! center of an existing straight Bcurve, set up the widget to
//! do a sweep cross-ways to the Bcurve:
bool
SWEEP_LINE::setup(CGESTUREptr& slash, double dur)
{

   static bool debug =
      Config::get_var_bool("DEBUG_SWEEP_SETUP",false) || debug_all;

   err_adv(debug, "SWEEP_LINE::setup");

   // check the gesture
   if (!(slash && slash->straightness() > 0.99)) {
      err_adv(debug, "SWEEP_LINE::setup: gesture is bad");
      return false;
   }

   // find the (straight) Bcurve near slash start
   _curve = Bcurve::hit_ctrl_curve(slash->start());
   if (!(_curve && _curve->is_straight())) {
      err_adv(debug, "SWEEP_LINE::setup: no straight curve at start");
      return false;
   }

   // find endpoints
   Bpoint *b1 = _curve->b1(), *b2 = _curve->b2();
   assert(b1 && b2);    // straight curve must have endpoints

   // curve cannot be connected to other curves
   if (b1->vert()->degree() != 1 || b2->vert()->degree() != 1) {
      err_adv(debug, "SWEEP_LINE::setup: curve is not isolated");
      return false;
   }

   // ensure the gesture starts near the center of the straight line Bcurve:
   {
      PIXEL a = b1->vert()->pix();
      PIXEL b = b2->vert()->pix();
      double t = (slash->start() - a).tlen(b-a);
      if (t < 0.35 || t > 0.65) {
         err_adv(debug, "SWEEP_LINE::setup: gesture not near center of line");
         return false;
      }
   }

   // find the plane to work in
   _plane = check_plane(shared_plane(b1, b2));
   if (!_plane.is_valid()) {
      err_adv(debug, "SWEEP_LINE::setup: no valid plane");
      return false;
   }

   // check that slash is perpendicular to line
   Wpt  a = b1->loc();  // endpoint at b1
   Wpt  b = b2->loc();  // endpoint at b2
   Wvec t = b - a;      // vector from endpt a to endpt b
   Wpt  o = a + t/2;    // center of straight line curve
   Wvec n = cross(_plane.normal(), t); // direction across line ab

   Wvec slash_vec = endpt_vec(slash, _plane);
   const double ALIGN_ANGLE_THRESH = 15;
   double angle = rad2deg(slash_vec.angle(n));
   if (angle > 90) {
      angle = 180 - angle;
      n = -n;
   }
   if (angle > ALIGN_ANGLE_THRESH) {
      err_adv(debug, "SWEEP_LINE::setup: slash is not perpendicular to line");
      err_adv(debug, "                   angle: %f", angle);
      return false;
   }

   // compute guideline endpoint:
   Wpt endpt = o + n.normalized()*a.dist(b);

   return SWEEP_BASE::setup(_curve->mesh(), o, endpt, dur);
}
Exemplo n.º 8
0
/**********************************************************************
 * ZcrossTexture:
 **********************************************************************/
int
ZcrossTexture::draw(CVIEWptr& v)
{
   if (_ctrl)
      return _ctrl->draw(v);

   // Ensure zcross strips are current, and get them
   _patch->mesh()->build_zcross_strips();

   // Get a reference for low-overhead:
   //const ZcrossPath& zx_sils = _patch->zx_sils();

   //needs to have a current sils (simon)
   const ZcrossPath& zx_sils = _patch->cur_zx_sils();
   // Stop now, before making partial GL calls, if nothing is going on
   if (zx_sils.empty())
      return 1;

   // Set line width, (optionally) enable antialiasing, and save GL state
   GLfloat w = float(v->line_scale()*_width);
   static bool antialias = Config::get_var_bool("ANTIALIAS_SILS",true,true);
   static bool drawback = Config::get_var_bool("DRAW_BACKFACING",false,true);
   if (antialias) {
      // push attributes, enable line smoothing, and set line width
      GL_VIEW::init_line_smooth(w, GL_CURRENT_BIT);
   } else {
      // push state, set line width
      glPushAttrib(GL_LINE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT);
      glLineWidth(w); // GL_LINE_BIT
   }

   glDisable(GL_BLEND);
   glDisable(GL_LIGHTING);      // GL_ENABLE_BIT
   GL_COL(_color, alpha());     // GL_CURRENT_BIT


   // right now we're only doing OpenGL, ignoring CB
   int n = zx_sils.num();
   bool started = false;
   bool lvis = false;
   bool vis = false;

   static bool nodots = Config::get_var_bool("ZX_NO_DOTS",false,true);
   static bool nocolor = Config::get_var_bool("ZX_NO_COLOR",false,true);
   //XXX - Hack. Not good when a loop isn't closed.
   // But I'm in a hurry to close proper loops...
   static bool closed = Config::get_var_bool("ZX_CLOSED",false,true);

   srand48(0);
   if (!nocolor)
      glColor3d ( drand48(), drand48(), drand48() );
   else
      glColor3d ( 0.0, 0.0, 0.0 );

   Wpt wp;

   if (!nodots) {
      glPointSize(5.0);
      glBegin ( GL_POINTS ) ;
      for ( int k =0 ; k < n; k++ ) {
         glColor3d ( 0.0 , 0.0 , 1.0 );
         if ( zx_sils.face(k) == NULL )
            glColor3d ( 1.0, 0, 0 );
         glVertex3dv ( zx_sils.point(k).data() );
      }
      glEnd();
   }
   if ( !drawback ) {
      for (int i=0; i < n; i++) {

         vis = zx_sils.grad(i);

         // start new line strip if needed:
         if ( vis ) {
            //we are in a visible section of the curve
            if (!started ) {
               if ( zx_sils.face(i) ) {
                  glBegin(GL_LINE_STRIP);
                  zx_sils.face(i)->bc2pos ( zx_sils.bc(i) , wp );
                  glVertex3dv( wp.data());
                  started = true;
               }
            } else {
               if ( zx_sils.face(i) && i < n-1 ) {
                  zx_sils.face(i)->bc2pos ( zx_sils.bc(i) , wp );
                  glVertex3dv( wp.data());
               } else {
                  zx_sils.face(i-1)->bc2pos ( zx_sils.bc(i) , wp );
                  glVertex3dv( wp.data());
                  glEnd();
                  started = false;
               }
            }
         } else if ( lvis && started ) {
            //this point is not visible, but the last one was.
            zx_sils.face(i-1)->bc2pos ( zx_sils.bc(i-1) , wp );
            glVertex3dv( wp.data());
            glEnd();
            started=false;
         }
         lvis = vis;
         //if the face was null, we started a new loop
         if ( !zx_sils.face(i) ) {
            if (!nocolor)
               glColor3d ( drand48(), drand48(), drand48() );
            else
               glColor3d ( 0.0, 0.0, 0.0);
         }
      }
   } else {  //draw using barycentric values
      Wpt first;
      for (int i=0; i < n; i++) {
         vis = true;
         if ( vis ) {
            //we are in a visible section of the curve
            if (!started ) {
               if ( zx_sils.face(i) ) {
                  glBegin(GL_LINE_STRIP);
                  zx_sils.face(i)->bc2pos ( zx_sils.bc(i) , wp );
                  if (!nocolor) {
                     if ( !zx_sils.grad(i) )
                        glColor3d( 1.0, 0.0 ,0.0 );
                     else
                        glColor3d( 0.0 , 0.0, 1.0 );
                  } else {
                     glColor3d( 0.0 , 0.0, 0.0 );
                  }
                  first = wp;
                  glVertex3dv( wp.data());
                  started = true;
               }
            } else {
               if (!nocolor) {
                  if ( !zx_sils.grad(i) )
                     glColor3d( 1.0, 0.0 ,0.0 );
                  else
                     glColor3d( 0.0 , 0.0, 1.0 );
               } else
                  glColor3d( 0.0 , 0.0, 0.0 );

               if ( zx_sils.face(i) && i < n-1 ) {
                  zx_sils.face(i)->bc2pos ( zx_sils.bc(i) , wp );
                  glVertex3dv( zx_sils.point(i).data());
               } else {
                  zx_sils.face(i-1)->bc2pos ( zx_sils.bc(i) , wp );
                  glVertex3dv( zx_sils.point(i-1).data());
                  if (closed)
                     glVertex3dv( first.data());
                  glEnd();
                  started = false;
               }
            }
         } else if ( lvis && started ) {
            //this point is not visible, but the last one was.
            zx_sils.face(i-1)->bc2pos ( zx_sils.bc(i-1) , wp );
            glVertex3dv( zx_sils.point(i-1).data());
            glEnd();
            started=false;
         }
         lvis = vis;
      }
   }

   // Restore GL state:
   if (antialias)
      GL_VIEW::end_line_smooth();
   else
      glPopAttrib();

   return 1;
}