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_GXCAMERA_CC_UTC20050626084024_DEFINED
00035 #define GROOVX_GFX_GXCAMERA_CC_UTC20050626084024_DEFINED
00036
00037 #include "gxcamera.h"
00038
00039 #include "gfx/canvas.h"
00040
00041 #include "io/reader.h"
00042 #include "io/writer.h"
00043
00044 #include "rutz/error.h"
00045
00046 #include <cmath>
00047
00048 #include "rutz/debug.h"
00049 GVX_DBG_REGISTER
00050 #include "rutz/trace.h"
00051
00052 namespace
00053 {
00054 const int GXPC_SVID = 0;
00055 const int GXFSC_SVID = 0;
00056 const int GXPPC_SVID = 0;
00057 }
00058
00059 GxCamera::~GxCamera() throw() {}
00060
00061 void GxCamera::reshape(Gfx::Canvas& canvas, int w, int h)
00062 {
00063 GVX_TRACE("GxCamera::reshape");
00064
00065 dbg_eval(3, itsWidth); dbg_eval_nl(3, itsHeight);
00066
00067 itsWidth = w; itsHeight = h;
00068
00069 dbg_eval(3, itsWidth); dbg_eval_nl(3, itsHeight);
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 draw(canvas);
00080 }
00081
00082 GxPerspectiveCamera::GxPerspectiveCamera() :
00083 GxCamera(),
00084 FieldContainer(&sigNodeChanged),
00085 itsFovY(30),
00086 itsNearZ(1),
00087 itsFarZ(30)
00088 {}
00089
00090 GxPerspectiveCamera::~GxPerspectiveCamera() throw() {}
00091
00092 const FieldMap& GxPerspectiveCamera::classFields()
00093 {
00094 GVX_TRACE("GxPerspectiveCamera::classFields");
00095 static const Field FIELD_ARRAY[] =
00096 {
00097 Field("fovY", &GxPerspectiveCamera::itsFovY, 30.0, 1.0, 180.0, 1.0,
00098 Field::NEW_GROUP),
00099 Field("nearZ", &GxPerspectiveCamera::itsNearZ, 1.0, 1.0, 50.0, 0.1),
00100 Field("farZ", &GxPerspectiveCamera::itsFarZ, 30.0, 1.0, 50.0, 0.1),
00101 Field("translation", Field::ValueType(), &GxPerspectiveCamera::translation,
00102 "0. 0. 0.", "-50. -50. -10.", "50. 50. 50.", "0.1 0.1 0.1",
00103 Field::MULTI)
00104 };
00105
00106 static FieldMap FIELD_MAP(FIELD_ARRAY);
00107
00108 return FIELD_MAP;
00109 }
00110
00111 io::version_id GxPerspectiveCamera::class_version_id() const
00112 {
00113 GVX_TRACE("GxPerspectiveCamera::class_version_id");
00114 return GXPC_SVID;
00115 }
00116
00117 void GxPerspectiveCamera::read_from(io::reader& reader)
00118 {
00119 GVX_TRACE("GxPerspectiveCamera::read_from");
00120 readFieldsFrom(reader, classFields());
00121 }
00122
00123 void GxPerspectiveCamera::write_to(io::writer& writer) const
00124 {
00125 GVX_TRACE("GxPerspectiveCamera::write_to");
00126 writeFieldsTo(writer, classFields(), GXPC_SVID);
00127 }
00128
00129 void GxPerspectiveCamera::draw(Gfx::Canvas& canvas) const
00130 {
00131 GVX_TRACE("GxPerspectiveCamera::draw");
00132
00133 dbg_eval(2, width()); dbg_eval_nl(2, height());
00134
00135 canvas.viewport(0, 0, width(), height());
00136
00137 canvas.perspective(itsFovY,
00138 double(width()) / double(height()),
00139 itsNearZ, itsFarZ);
00140
00141 canvas.translate(translation.vec());
00142 }
00143
00144
00145 GxFixedRectCamera::~GxFixedRectCamera() throw() {}
00146
00147 void GxFixedRectCamera::draw(Gfx::Canvas& canvas) const
00148 {
00149 GVX_TRACE("GxFixedRectCamera::draw");
00150
00151 canvas.viewport(0, 0, width(), height());
00152 canvas.orthographic(itsRect, -10.0, 10.0);
00153 }
00154
00155 GxMinRectCamera::~GxMinRectCamera() throw() {}
00156
00157 void GxMinRectCamera::draw(Gfx::Canvas& canvas) const
00158 {
00159 GVX_TRACE("GxMinRectCamera::draw");
00160
00161 canvas.viewport(0, 0, width(), height());
00162
00163
00164 geom::rect<double> port(itsRect);
00165
00166
00167
00168
00169
00170
00171 const double window_aspect = double(width()) / double(height());
00172
00173 const double ratio_of_aspects = itsRect.aspect() / window_aspect;
00174
00175 if ( ratio_of_aspects < 1 )
00176 {
00177 port.scale_x(1/ratio_of_aspects);
00178 }
00179 else
00180 {
00181 port.scale_y(ratio_of_aspects);
00182 }
00183
00184 canvas.orthographic(port, -10.0, 10.0);
00185 }
00186
00187 namespace
00188 {
00189 void orthoFixed(Gfx::Canvas& canvas, int w, int h, double ppu)
00190 {
00191 const double l = -1 * (w / 2.0) / ppu;
00192 const double r = (w / 2.0) / ppu;
00193 const double b = -1 * (h / 2.0) / ppu;
00194 const double t = (h / 2.0) / ppu;
00195
00196 canvas.orthographic(geom::rect<double>::ltrb(l,t,r,b), -10.0, 10.0);
00197 }
00198 }
00199
00200 GxFixedScaleCamera::GxFixedScaleCamera() :
00201 GxCamera(),
00202 FieldContainer(&sigNodeChanged),
00203 itsPixelsPerUnit(100.0)
00204 {}
00205
00206 GxFixedScaleCamera::~GxFixedScaleCamera() throw() {}
00207
00208 const FieldMap& GxFixedScaleCamera::classFields()
00209 {
00210 GVX_TRACE("GxFixedScaleCamera::classFields");
00211 static const Field FIELD_ARRAY[] =
00212 {
00213 Field("pixelsPerUnit",
00214 &GxFixedScaleCamera::getPixelsPerUnit,
00215 &GxFixedScaleCamera::setPixelsPerUnit,
00216 2.05, 1.0, 10000.0, 1.0,
00217 Field::NEW_GROUP),
00218 Field("logPixelsPerUnit",
00219 &GxFixedScaleCamera::getLogPixelsPerUnit,
00220 &GxFixedScaleCamera::setLogPixelsPerUnit,
00221 0.5, 0.0, 5.0, 0.025,
00222 Field::TRANSIENT)
00223 };
00224
00225 static FieldMap FIELD_MAP(FIELD_ARRAY);
00226
00227 return FIELD_MAP;
00228 }
00229
00230 io::version_id GxFixedScaleCamera::class_version_id() const
00231 {
00232 GVX_TRACE("GxFixedScaleCamera::class_version_id");
00233 return GXFSC_SVID;
00234 }
00235
00236 void GxFixedScaleCamera::read_from(io::reader& reader)
00237 {
00238 GVX_TRACE("GxFixedScaleCamera::read_from");
00239 readFieldsFrom(reader, classFields());
00240 }
00241
00242 void GxFixedScaleCamera::write_to(io::writer& writer) const
00243 {
00244 GVX_TRACE("GxFixedScaleCamera::write_to");
00245 writeFieldsTo(writer, classFields(), GXFSC_SVID);
00246 }
00247
00248 double GxFixedScaleCamera::getLogPixelsPerUnit() const
00249 {
00250 return log10(itsPixelsPerUnit);
00251 }
00252
00253 void GxFixedScaleCamera::setLogPixelsPerUnit(double s)
00254 {
00255 setPixelsPerUnit(pow(10.0, s));
00256 }
00257
00258 void GxFixedScaleCamera::setPixelsPerUnit(double s)
00259 {
00260 if (s <= 0.0)
00261 throw rutz::error("invalid scaling factor", SRC_POS);
00262
00263 itsPixelsPerUnit = s;
00264 }
00265
00266 void GxFixedScaleCamera::draw(Gfx::Canvas& canvas) const
00267 {
00268 GVX_TRACE("GxFixedScaleCamera::draw");
00269
00270 dbg_eval(3, width()); dbg_eval_nl(3, height());
00271 canvas.viewport(0, 0, width(), height());
00272
00273 orthoFixed(canvas, width(), height(), itsPixelsPerUnit);
00274 }
00275
00276 GxPsyphyCamera::GxPsyphyCamera() :
00277 GxCamera(),
00278 FieldContainer(&sigNodeChanged),
00279 itsDegreesPerUnit(2.05),
00280 itsViewingDistance(30.0)
00281 {}
00282
00283 GxPsyphyCamera::~GxPsyphyCamera() throw() {}
00284
00285 const FieldMap& GxPsyphyCamera::classFields()
00286 {
00287 GVX_TRACE("GxPsyphyCamera::classFields");
00288 static const Field FIELD_ARRAY[] =
00289 {
00290 Field("unitAngle",
00291 &GxPsyphyCamera::getUnitAngle,
00292 &GxPsyphyCamera::setUnitAngle,
00293 2.05, 0.1, 100.0, 0.1,
00294 Field::NEW_GROUP),
00295 Field("viewingDistIn",
00296 &GxPsyphyCamera::getViewingDistIn,
00297 &GxPsyphyCamera::setViewingDistIn,
00298 30.0, 1.0, 500.0, 1.0),
00299 };
00300
00301 static FieldMap FIELD_MAP(FIELD_ARRAY);
00302
00303 return FIELD_MAP;
00304 }
00305
00306 io::version_id GxPsyphyCamera::class_version_id() const
00307 {
00308 GVX_TRACE("GxPsyphyCamera::class_version_id");
00309 return GXPPC_SVID;
00310 }
00311
00312 void GxPsyphyCamera::read_from(io::reader& reader)
00313 {
00314 GVX_TRACE("GxPsyphyCamera::read_from");
00315 readFieldsFrom(reader, classFields());
00316 }
00317
00318 void GxPsyphyCamera::write_to(io::writer& writer) const
00319 {
00320 GVX_TRACE("GxPsyphyCamera::write_to");
00321 writeFieldsTo(writer, classFields(), GXPPC_SVID);
00322 }
00323
00324 void GxPsyphyCamera::setUnitAngle(double deg_per_unit)
00325 {
00326 if (deg_per_unit <= 0.0)
00327 throw rutz::error("unit angle must be positive", SRC_POS);
00328
00329 itsDegreesPerUnit = deg_per_unit;
00330 }
00331
00332 void GxPsyphyCamera::setViewingDistIn(double inches)
00333 {
00334 if (inches <= 0.0)
00335 throw rutz::error("viewing distance must be positive (duh)", SRC_POS);
00336
00337 itsViewingDistance = inches;
00338 }
00339
00340 void GxPsyphyCamera::draw(Gfx::Canvas& canvas) const
00341 {
00342 GVX_TRACE("GxPsyphyCamera::draw");
00343
00344 canvas.viewport(0, 0, width(), height());
00345
00346 static const double deg_to_rad = M_PI/180.0;
00347
00348 const double pixels_per_inch = 72.0;
00349
00350
00351
00352 const double inches_per_unit =
00353 tan(itsDegreesPerUnit*deg_to_rad) * itsViewingDistance;
00354
00355 const double pixels_per_unit = pixels_per_inch * inches_per_unit;
00356
00357 orthoFixed(canvas, width(), height(), pixels_per_unit);
00358 }
00359
00360 static const char __attribute__((used)) vcid_groovx_gfx_gxcamera_cc_utc20050626084024[] = "$Id: gxcamera.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00361 #endif // !GROOVX_GFX_GXCAMERA_CC_UTC20050626084024_DEFINED