00001
00003
00004
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
00033
00034 #ifndef GROOVX_GFX_BBOX_CC_UTC20050626084024_DEFINED
00035 #define GROOVX_GFX_BBOX_CC_UTC20050626084024_DEFINED
00036
00037 #include "bbox.h"
00038
00039 #include "geom/box.h"
00040 #include "geom/txform.h"
00041
00042 #include "gfx/canvas.h"
00043
00044 #include <vector>
00045
00046 #include "rutz/trace.h"
00047 #include "rutz/debug.h"
00048 GVX_DBG_REGISTER
00049
00050 using geom::recti;
00051 using geom::rectd;
00052 using geom::txform;
00053 using geom::vec2i;
00054 using geom::vec2d;
00055 using geom::vec3i;
00056 using geom::vec3d;
00057
00058 struct Gfx::Bbox::Impl
00059 {
00060 Impl(Canvas& c) : canvas(c), cube(), txforms(), first(true)
00061 {
00062 txforms.push_back(txform::identity());
00063 }
00064
00065 Canvas& canvas;
00066 geom::box<double> cube;
00067 std::vector<txform> txforms;
00068 bool first;
00069
00070 vec3d screenFromWorld3(const vec3d& world_pos) const
00071 {
00072
00073 return canvas.screenFromWorld3(world_pos);
00074 }
00075
00076 vec3d worldFromScreen3(const vec3d& screen_pos) const
00077 {
00078
00079 return canvas.worldFromScreen3(screen_pos);
00080 }
00081
00082 void merge(const vec3d& v)
00083 {
00084 dbg_eval_nl(3, first);
00085
00086 if (first)
00087 {
00088 vec3d tx = txforms.back().apply_to(v);
00089 cube.set_corners(tx, tx);
00090 first = false;
00091 }
00092 else
00093 cube.merge(txforms.back().apply_to(v));
00094 }
00095
00096 void mergeRaw(const vec3d& v)
00097 {
00098 dbg_eval_nl(3, first);
00099
00100 if (first)
00101 {
00102 cube.set_corners(v, v);
00103 first = false;
00104 }
00105 else
00106 cube.merge(v);
00107 }
00108
00109 void merge(const vec2d& v)
00110 {
00111 merge(vec3d(v.x(), v.y(), 0.0));
00112 }
00113 };
00114
00115 Gfx::Bbox::Bbox(Canvas& c) :
00116 rep(new Impl(c))
00117 {
00118 GVX_TRACE("Gfx::Bbox::Bbox");
00119 }
00120
00121 Gfx::Bbox::Bbox(const Bbox& that) :
00122 rep(new Impl(*(that.rep)))
00123 {
00124 GVX_TRACE("Gfx::Bbox::Bbox(copy)");
00125 }
00126
00127 Gfx::Bbox::~Bbox()
00128 {
00129 GVX_TRACE("Gfx::Bbox::~Bbox");
00130 delete rep;
00131 }
00132
00133 Gfx::Bbox Gfx::Bbox::peer() const
00134 {
00135 GVX_TRACE("Gfx::Bbox::peer");
00136 return Gfx::Bbox(rep->canvas);
00137 }
00138
00139 void Gfx::Bbox::push()
00140 {
00141 GVX_TRACE("Gfx::Bbox::push");
00142 GVX_ASSERT(rep->txforms.size() >= 1);
00143 rep->txforms.push_back(rep->txforms.back());
00144 }
00145
00146 void Gfx::Bbox::pop()
00147 {
00148 GVX_TRACE("Gfx::Bbox::pop");
00149 GVX_ASSERT(rep->txforms.size() > 1);
00150 rep->txforms.pop_back();
00151 }
00152
00153 void Gfx::Bbox::translate(const vec3d& v)
00154 {
00155 GVX_TRACE("Gfx::Bbox::translate");
00156 rep->txforms.back().translate(v);
00157 }
00158
00159 void Gfx::Bbox::scale(const vec3d& v)
00160 {
00161 GVX_TRACE("Gfx::Bbox::scale");
00162 rep->txforms.back().scale(v);
00163 }
00164
00165 void Gfx::Bbox::transform(const txform& m)
00166 {
00167 GVX_TRACE("Gfx::Bbox::transform");
00168 rep->txforms.back().transform(m);
00169
00170 dbg_dump(2, rep->txforms.back());
00171 }
00172
00173 void Gfx::Bbox::vertex2(const vec2d& v)
00174 {
00175 GVX_TRACE("Gfx::Bbox::vertex2");
00176 rep->merge(v);
00177 }
00178
00179 void Gfx::Bbox::vertex3(const vec3d& v)
00180 {
00181 GVX_TRACE("Gfx::Bbox::vertex3");
00182 rep->merge(v);
00183 }
00184
00185 void Gfx::Bbox::drawRect(const rectd& rect)
00186 {
00187 GVX_TRACE("Gfx::Bbox::drawRect");
00188 rep->merge(rect.bottom_left());
00189 rep->merge(rect.bottom_right());
00190 rep->merge(rect.top_left());
00191 rep->merge(rect.top_right());
00192 }
00193
00194 void Gfx::Bbox::drawBox(const geom::box<double>& box)
00195 {
00196 GVX_TRACE("Gfx::Bbox::drawBox");
00197 rep->merge(box.point000());
00198 rep->merge(box.point001());
00199 rep->merge(box.point010());
00200 rep->merge(box.point011());
00201 rep->merge(box.point100());
00202 rep->merge(box.point101());
00203 rep->merge(box.point110());
00204 rep->merge(box.point111());
00205 }
00206
00207 void Gfx::Bbox::drawScreenRect(const vec3d& lower_left,
00208 const vec2i& size,
00209 const vec2d& zoom)
00210 {
00211 const recti screen_rect = recti::lbwh(vec2i::zeros(), size * zoom);
00212
00213 drawScreenRect(lower_left, screen_rect);
00214 }
00215
00216 void Gfx::Bbox::drawScreenRect(const vec3d& lower_left,
00217 const recti& screen_rect)
00218 {
00219 GVX_TRACE("Gfx::Bbox::drawScreenRect");
00220 const vec3d o = rep->screenFromWorld3(vec3d(lower_left));
00221
00222 rep->mergeRaw(rep->worldFromScreen3(o+vec2d(screen_rect.bottom_left())));
00223 rep->mergeRaw(rep->worldFromScreen3(o+vec2d(screen_rect.bottom_right())));
00224 rep->mergeRaw(rep->worldFromScreen3(o+vec2d(screen_rect.top_left())));
00225 rep->mergeRaw(rep->worldFromScreen3(o+vec2d(screen_rect.top_right())));
00226 }
00227
00228 geom::box<double> Gfx::Bbox::cube() const
00229 {
00230 GVX_TRACE("Gfx::Bbox::cube");
00231 return rep->cube;
00232 }
00233
00234 rectd Gfx::Bbox::rect() const
00235 {
00236 GVX_TRACE("Gfx::Bbox::rect");
00237 return rep->cube.rect();
00238 }
00239
00240 static const char __attribute__((used)) vcid_groovx_gfx_bbox_cc_utc20050626084024[] = "$Id: bbox.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00241 #endif // !GROOVX_GFX_BBOX_CC_UTC20050626084024_DEFINED