canvas.cc

Go to the documentation of this file.
00001 
00005 
00006 //
00007 // Copyright (c) 1999-2004 California Institute of Technology
00008 // Copyright (c) 2004-2007 University of Southern California
00009 // Rob Peters <rjpeters at usc dot edu>
00010 //
00011 // created: Mon Nov 15 18:00:38 1999
00012 // commit: $Id: canvas.cc 10065 2007-04-12 05:54:56Z rjpeters $
00013 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/gfx/canvas.cc $
00014 //
00015 // --------------------------------------------------------------------
00016 //
00017 // This file is part of GroovX.
00018 //   [http://ilab.usc.edu/rjpeters/groovx/]
00019 //
00020 // GroovX is free software; you can redistribute it and/or modify it
00021 // under the terms of the GNU General Public License as published by
00022 // the Free Software Foundation; either version 2 of the License, or
00023 // (at your option) any later version.
00024 //
00025 // GroovX is distributed in the hope that it will be useful, but
00026 // WITHOUT ANY WARRANTY; without even the implied warranty of
00027 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00028 // General Public License for more details.
00029 //
00030 // You should have received a copy of the GNU General Public License
00031 // along with GroovX; if not, write to the Free Software Foundation,
00032 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00033 //
00035 
00036 #ifndef GROOVX_GFX_CANVAS_CC_UTC20050626084025_DEFINED
00037 #define GROOVX_GFX_CANVAS_CC_UTC20050626084025_DEFINED
00038 
00039 #include "canvas.h"
00040 
00041 #include "gfx/rgbacolor.h"
00042 
00043 #include "geom/bezier4.h"
00044 #include "geom/box.h"
00045 #include "geom/vec3.h"
00046 
00047 #include "rutz/arrays.h"
00048 #include "rutz/error.h"
00049 
00050 #include "rutz/debug.h"
00051 GVX_DBG_REGISTER
00052 #include "rutz/trace.h"
00053 
00054 using geom::recti;
00055 using geom::rectd;
00056 using geom::vec2i;
00057 using geom::vec2d;
00058 using geom::vec3i;
00059 using geom::vec3d;
00060 
00061 namespace
00062 {
00063   struct BezData
00064   {
00065     vec3d pt0;
00066     vec3d pt1;
00067     vec3d pt2;
00068     vec3d pt3;
00069   };
00070 }
00071 
00072 Gfx::Canvas::~Canvas() throw() {}
00073 
00074 vec2d Gfx::Canvas::screenFromWorld2(const vec2d& world_pos) const
00075 {
00076 GVX_TRACE("Gfx::Canvas::screenFromWorld2");
00077 
00078   return screenFromWorld3(vec3d(world_pos.x(),
00079                                 world_pos.y(),
00080                                 0.0)).as_vec2();
00081 }
00082 
00083 recti Gfx::Canvas::screenBoundsFromWorldRect(const rectd& world_pos) const
00084 {
00085 GVX_TRACE("Gfx::Canvas::screenBoundsFromWorldRect");
00086 
00087   // In order to get an accurate bounding box in screen coords, we need
00088   // to consider all four corners in world coordinates.
00089   const vec2i p1(screenFromWorld2(world_pos.bottom_left()));
00090   const vec2i p2(screenFromWorld2(world_pos.top_right()));
00091   const vec2i p3(screenFromWorld2(world_pos.bottom_right()));
00092   const vec2i p4(screenFromWorld2(world_pos.top_left()));
00093 
00094   const recti screen_rect1(p1, p2);
00095   const recti screen_rect2(p3, p4);
00096 
00097   return screen_rect1.union_with(screen_rect2);
00098 }
00099 
00100 void Gfx::Canvas::drawRect(const rectd& rect, bool filled)
00101 {
00102   Gfx::AttribSaver saver(*this);
00103 
00104   this->setPolygonFill(filled);
00105 
00106   drawRect(rect);
00107 }
00108 
00109 void Gfx::Canvas::drawBox(const geom::box<double>& box)
00110 {
00111   AttribSaver saver(*this);
00112 
00113   {
00114     setColor(RgbaColor(1.0, 0.0, 0.0, 1.0));
00115     LineStripBlock block(*this);
00116     vertex3(box.point000());
00117     vertex3(box.point100());
00118     vertex3(box.point110());
00119     vertex3(box.point111());
00120   }
00121 
00122   {
00123     setColor(RgbaColor(0.0, 1.0, 0.0, 1.0));
00124     LineStripBlock block(*this);
00125     vertex3(box.point001());
00126     vertex3(box.point000());
00127     vertex3(box.point010());
00128     vertex3(box.point110());
00129   }
00130 
00131   {
00132     setColor(RgbaColor(0.0, 0.0, 1.0, 1.0));
00133     LineStripBlock block(*this);
00134     vertex3(box.point101());
00135     vertex3(box.point001());
00136     vertex3(box.point011());
00137     vertex3(box.point010());
00138   }
00139 
00140   {
00141     setColor(RgbaColor(0.0, 0.0, 0.0, 1.0));
00142     LineStripBlock block(*this);
00143     vertex3(box.point011());
00144     vertex3(box.point111());
00145     vertex3(box.point101());
00146     vertex3(box.point100());
00147   }
00148 }
00149 
00150 void Gfx::Canvas::drawBezier4(const vec3d& p1,
00151                               const vec3d& p2,
00152                               const vec3d& p3,
00153                               const vec3d& p4,
00154                               unsigned int subdivisions)
00155 {
00156 GVX_TRACE("Gfx::Canvas::drawBezier4");
00157 
00158   geom::bezier4 xb(p1.x(), p2.x(), p3.x(), p4.x());
00159   geom::bezier4 yb(p1.y(), p2.y(), p3.y(), p4.y());
00160   geom::bezier4 zb(p1.z(), p2.z(), p3.z(), p4.z());
00161 
00162   beginLineStrip();
00163   for (unsigned int i = 0; i < subdivisions; ++i)
00164     {
00165       double u = double(i) / double(subdivisions - 1);
00166       vertex3(vec3d(xb.eval(u), yb.eval(u), zb.eval(u)));
00167     }
00168   end();
00169 }
00170 
00171 void Gfx::Canvas::drawBezierFill4(const vec3d& center,
00172                                   const vec3d& p1,
00173                                   const vec3d& p2,
00174                                   const vec3d& p3,
00175                                   const vec3d& p4,
00176                                   unsigned int subdivisions)
00177 {
00178 GVX_TRACE("Gfx::Canvas::drawBezierFill4");
00179 
00180   geom::bezier4 xb(p1.x(), p2.x(), p3.x(), p4.x());
00181   geom::bezier4 yb(p1.y(), p2.y(), p3.y(), p4.y());
00182   geom::bezier4 zb(p1.z(), p2.z(), p3.z(), p4.z());
00183 
00184   beginTriangleFan();
00185   vertex3(center);
00186   for (unsigned int i = 0; i < subdivisions; ++i)
00187     {
00188       double u = double(i) / double(subdivisions - 1);
00189       vertex3(vec3d(xb.eval(u), yb.eval(u), zb.eval(u)));
00190     }
00191   end();
00192 }
00193 
00194 void Gfx::Canvas::drawNurbsCurve
00195   (const rutz::dynamic_block<float>& knots,
00196    const rutz::dynamic_block<geom::vec3<float> >& pts)
00197 {
00198 GVX_TRACE("Gfx::Canvas::drawNurbsCurve");
00199 
00200   const float* t = &knots[2];
00201   // t points to { 0, 0, 0.17, 0.33, 0.5, 0.67, 0.83, 1, 1 }
00202 
00203   unsigned int nctrl = pts.size();
00204 
00205   GVX_ASSERT(nctrl > 4);
00206 
00207   unsigned int nbz = nctrl - 3;
00208 
00209   rutz::dynamic_block<BezData> bz(nbz);
00210 
00211   for (unsigned int k = 0; k < nbz; ++k)
00212     {
00213       float d1 = t[k+3] - t[k+2]; // == 0 when k == nbz-1 (last iteration)
00214       float d2 = t[k+2] - t[k+1];
00215       float d3 = t[k+1] - t[k];  // == 0 when k == 0 (first iteration)
00216       float d = t[k+3] - t[k];
00217 
00218       bz[k].pt1 = vec3d((pts[k+2] *  d3     + pts[k+1] * (d1+d2)) / d);
00219       bz[k].pt2 = vec3d((pts[k+2] * (d2+d3) + pts[k+1] *  d1    ) / d);
00220 
00221       if (k == 0)
00222         {
00223           bz[k].pt0 = vec3d(pts[k]);
00224         }
00225       else
00226         {
00227           bz[k-1].pt3 = (bz[k-1].pt2 * d2 + bz[k].pt1 * d3) / (d2+d3);
00228           bz[k].pt0 = bz[k-1].pt3;
00229         }
00230 
00231       if (k == (nbz-1))
00232         {
00233           bz[k].pt3 = vec3d(pts[k+3]);
00234         }
00235 
00236     }
00237 
00238   for (unsigned int i = 0; i < bz.size(); ++i)
00239     {
00240       drawBezier4(bz[i].pt0, bz[i].pt1, bz[i].pt2, bz[i].pt3, 20);
00241     }
00242 }
00243 
00244 void Gfx::Canvas::begin(Gfx::Canvas::VertexStyle s, const char* comment)
00245 {
00246   switch (s)
00247     {
00248     case POINTS:         beginPoints(comment); break;
00249     case LINES:          beginLines(comment); break;
00250     case LINE_STRIP:     beginLineStrip(comment); break;
00251     case LINE_LOOP:      beginLineLoop(comment); break;
00252     case TRIANGLES:      beginTriangles(comment); break;
00253     case TRIANGLE_STRIP: beginTriangleStrip(comment); break;
00254     case TRIANGLE_FAN:   beginTriangleFan(comment); break;
00255     case QUADS:          beginQuads(comment); break;
00256     case QUAD_STRIP:     beginQuadStrip(comment); break;
00257     case POLYGON:        beginPolygon(comment); break;
00258     }
00259 }
00260 
00261 void Gfx::Canvas::finishDrawing()
00262 {
00263 GVX_TRACE("Gfx::Canvas::finishDrawing");
00264 }
00265 
00266 const char __attribute__((used)) vcid_canvas_cc[] = "$Id: canvas.cc 10065 2007-04-12 05:54:56Z rjpeters $ $URL: file:
00267 #endif // !GROOVX_GFX_CANVAS_CC_UTC20050626084025_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:38 2008 by Doxygen version 1.5.5.