00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00088
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
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];
00214 float d2 = t[k+2] - t[k+1];
00215 float d3 = t[k+1] - t[k];
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