house.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Mon Sep 13 12:43:16 1999
00010 // commit: $Id: house.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/visx/house.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_VISX_HOUSE_CC_UTC20050626084015_DEFINED
00035 #define GROOVX_VISX_HOUSE_CC_UTC20050626084015_DEFINED
00036 
00037 #include "house.h"
00038 
00039 #include "geom/rect.h"
00040 #include "geom/vec3.h"
00041 
00042 #include "gfx/bbox.h"
00043 #include "gfx/canvas.h"
00044 
00045 #include "io/ioproxy.h"
00046 #include "io/reader.h"
00047 #include "io/writer.h"
00048 
00049 #include "rutz/algo.h"
00050 
00051 #include "rutz/trace.h"
00052 #include "rutz/debug.h"
00053 GVX_DBG_REGISTER
00054 
00055 using geom::rectd;
00056 using geom::vec2d;
00057 using geom::vec3d;
00058 
00060 //
00061 // File scope data
00062 //
00064 
00065 namespace
00066 {
00067   const io::version_id HOUSE_SVID = 3;
00068 
00069   void drawWindow(Gfx::Canvas& canvas, int num_vert_bars, int num_horiz_bars)
00070   {
00071     GVX_TRACE("House::drawWindow");
00072     // Draw 1x1 window centered on (0,0)
00073 
00074     {
00075       Gfx::LinesBlock block(canvas, "window bars");
00076 
00077       for (int x = 1; x < (num_vert_bars+1); ++x)
00078         {
00079           double xpos = double(x)/(num_vert_bars+1) - 0.5;
00080           canvas.vertex2(vec2d(xpos, -0.5));
00081           canvas.vertex2(vec2d(xpos,  0.5));
00082         }
00083       for (int y = 1; y < (num_horiz_bars+1); ++y)
00084         {
00085           double ypos = double(y)/(num_horiz_bars+1) - 0.5;
00086           canvas.vertex2(vec2d(-0.5, ypos));
00087           canvas.vertex2(vec2d( 0.5, ypos));
00088         }
00089     }
00090 
00091     {
00092       Gfx::QuadsBlock block(canvas, "window outline");
00093       canvas.vertex2(vec2d(-0.5, -0.5));
00094       canvas.vertex2(vec2d( 0.5, -0.5));
00095       canvas.vertex2(vec2d( 0.5, 0.5));
00096       canvas.vertex2(vec2d(-0.5, 0.5));
00097     }
00098   }
00099 
00100   void drawDoor(Gfx::Canvas& canvas)
00101   {
00102     GVX_TRACE("House::drawDoor");
00103     // Draw 1x1 door with bottom line centered on (0,0)
00104     canvas.drawRect(rectd::lbwh(-0.5, 0.0, 1.0, 1.0));
00105 
00106     Gfx::LinesBlock block(canvas, "door");
00107 
00108     canvas.vertex2(vec2d(0.25, 0.35));
00109     canvas.vertex2(vec2d(0.25, 0.45));
00110   }
00111 
00112   void drawStoryFrame(Gfx::Canvas& canvas)
00113   {
00114     GVX_TRACE("House::drawStoryFrame");
00115     // Draw 1x1 story frame centered on (0,0)
00116     canvas.drawRect(rectd::lbwh(-0.5, -0.5, 1.0, 1.0));
00117   }
00118 
00119   void drawTriangleRoof(Gfx::Canvas& canvas)
00120   {
00121     GVX_TRACE("House::drawTriangleRoof");
00122     // Draw 1x1-bounded triangle with bottom line centered on (0,0)
00123 
00124     {
00125       Gfx::TrianglesBlock block(canvas, "triangle roof");
00126       canvas.vertex2(vec2d(-0.5, 0.0));
00127       canvas.vertex2(vec2d( 0.5, 0.0));
00128       canvas.vertex2(vec2d( 0.0, 1.0));
00129     }
00130     {
00131       Gfx::LinesBlock block(canvas, "triangle roof ledge");
00132       canvas.vertex2(vec2d(-0.5, 0.0));
00133       canvas.vertex2(vec2d( 0.5, 0.0));
00134     }
00135   }
00136 
00137   void drawTrapezoidRoof(Gfx::Canvas& canvas)
00138   {
00139     GVX_TRACE("House::drawTrapezoidRoof");
00140     {
00141       Gfx::QuadsBlock block(canvas, "trapezoid roof");
00142       canvas.vertex2(vec2d(-0.5, 0.0));
00143       canvas.vertex2(vec2d( 0.5, 0.0));
00144       canvas.vertex2(vec2d( 0.4, 1.0));
00145       canvas.vertex2(vec2d(-0.4, 1.0));
00146     }
00147     {
00148       Gfx::LinesBlock block(canvas, "trapezoid roof overhand");
00149       canvas.vertex2(vec2d(-0.5, 0.0));
00150       canvas.vertex2(vec2d( 0.5, 0.0));
00151     }
00152   }
00153 
00154   void drawSquareRoof(Gfx::Canvas& canvas)
00155   {
00156     GVX_TRACE("House::drawSquareRoof");
00157     {
00158       Gfx::QuadsBlock block(canvas, "square roof");
00159       canvas.vertex2(vec2d(-0.5, 0.0));
00160       canvas.vertex2(vec2d( 0.5, 0.0));
00161       canvas.vertex2(vec2d( 0.5, 1.0));
00162       canvas.vertex2(vec2d(-0.5, 1.0));
00163     }
00164     {
00165       Gfx::LinesBlock block(canvas, "square roof overhang");
00166       canvas.vertex2(vec2d(-0.5, 0.0));
00167       canvas.vertex2(vec2d( 0.5, 0.0));
00168     }
00169   }
00170 
00171   void drawChimney(Gfx::Canvas& canvas)
00172   {
00173     GVX_TRACE("House::drawChimney");
00174     {
00175       Gfx::QuadsBlock block(canvas, "chimney");
00176       canvas.vertex2(vec2d( 0.5, 0.0));
00177       canvas.vertex2(vec2d(-0.5, 0.0));
00178       canvas.vertex2(vec2d(-0.5, 1.0));
00179       canvas.vertex2(vec2d( 0.5, 1.0));
00180     }
00181   }
00182 }
00183 
00185 //
00186 // House member definitions
00187 //
00189 
00190 const FieldMap& House::classFields()
00191 {
00192   static const Field FIELD_ARRAY[] =
00193   {
00194     Field("storyAspectRatio",
00195           &House::itsStoryAspectRatio, 3.0, 0.5, 10.0, 0.05, Field::NEW_GROUP),
00196     Field("numStories", &House::itsNumStories, 2, 1, 5, 1),
00197 
00198     Field("doorPosition", &House::itsDoorPosition, 2, 0, 5, 1, Field::NEW_GROUP),
00199     Field("doorWidth", &House::itsDoorWidth, 0.75, 0.05, 1.0, 0.05),
00200     Field("doorHeight", &House::itsDoorHeight, 0.75, 0.05, 1.0, 0.05),
00201     Field("doorOrientation",
00202           &House::itsDoorOrientation, false, false, true, true),
00203 
00204     Field("numWindows", &House::itsNumWindows, 5, 2, 6, 1, Field::NEW_GROUP),
00205     Field("windowWidth", &House::itsWindowWidth, 0.75, 0.05, 1.0, 0.05),
00206     Field("windowHeight", &House::itsWindowHeight, 0.5, 0.05, 1.0, 0.05),
00207     Field("windowVertBars", &House::itsWindowVertBars, 1, 0, 5, 1),
00208     Field("windowHorizBars", &House::itsWindowHorizBars, 1, 0, 5, 1),
00209 
00210     Field("roofShape", &House::itsRoofShape, 0, 0, 2, 1, Field::NEW_GROUP),
00211     Field("roofHeight", &House::itsRoofHeight, 0.05, 0.05, 2.0, 0.05),
00212     Field("roofOverhang", &House::itsRoofOverhang, 0.75, 0.0, 0.5, 0.05),
00213     Field("roofColor", &House::itsRoofColor, 1, 0, 1, 1),
00214 
00215     Field("chimneyXPosition",
00216           &House::itsChimneyXPosition, 0.2, -0.5, 0.5, 0.05, Field::NEW_GROUP),
00217     Field("chimneyYPosition",
00218           &House::itsChimneyYPosition, 0.5, 0.0, 1.0, 0.05),
00219     Field("chimneyWidth", &House::itsChimneyWidth, 0.06, 0.01, 0.30, 0.01),
00220     Field("chimneyHeight", &House::itsChimneyHeight, 0.5, 0.05, 2.0, 0.1)
00221   };
00222 
00223   static FieldMap HOUSE_FIELDS(FIELD_ARRAY, &GxShapeKit::classFields());
00224 
00225   return HOUSE_FIELDS;
00226 }
00227 
00228 House* House::make()
00229 {
00230 GVX_TRACE("House::make");
00231   return new House;
00232 }
00233 
00234 House::House() :
00235   itsStoryAspectRatio(3.0),
00236   itsNumStories(2),
00237 
00238   itsDoorPosition(2),
00239   itsDoorWidth(0.75),
00240   itsDoorHeight(0.75),
00241   itsDoorOrientation(false),
00242 
00243   itsNumWindows(5),
00244   itsWindowWidth(0.75),
00245   itsWindowHeight(0.5),
00246   itsWindowVertBars(1),
00247   itsWindowHorizBars(1),
00248 
00249   itsRoofShape(0),
00250   itsRoofOverhang(0.05),
00251   itsRoofHeight(0.75),
00252   itsRoofColor(1),
00253 
00254   itsChimneyXPosition(0.2),
00255   itsChimneyYPosition(0.5),
00256   itsChimneyWidth(0.06),
00257   itsChimneyHeight(0.5)
00258 {
00259 GVX_TRACE("House::House");
00260 
00261   setFieldMap(House::classFields());
00262 }
00263 
00264 House::~House() throw()
00265 {
00266 GVX_TRACE("House::~House");
00267 }
00268 
00269 io::version_id House::class_version_id() const
00270 {
00271 GVX_TRACE("House::class_version_id");
00272   return HOUSE_SVID;
00273 }
00274 
00275 void House::read_from(io::reader& reader)
00276 {
00277 GVX_TRACE("House::read_from");
00278 
00279   reader.ensure_version_id("House", 3,
00280                            "Try cvs tag xml_conversion_20040526",
00281                            SRC_POS);
00282 
00283   readFieldsFrom(reader, classFields());
00284 
00285   reader.read_base_class("GxShapeKit", io::make_proxy<GxShapeKit>(this));
00286 }
00287 
00288 void House::write_to(io::writer& writer) const
00289 {
00290 GVX_TRACE("House::write_to");
00291 
00292   writer.ensure_output_version_id("House", HOUSE_SVID, 3,
00293                               "Try groovx0.8a4", SRC_POS);
00294 
00295   writeFieldsTo(writer, classFields(), HOUSE_SVID);
00296 
00297   writer.write_base_class("GxShapeKit", io::make_const_proxy<GxShapeKit>(this));
00298 }
00299 
00301 //
00302 // Actions
00303 //
00305 
00306 void House::grGetBoundingBox(Gfx::Bbox& bbox) const
00307 {
00308 GVX_TRACE("House::grGetBoundingBox");
00309 
00310   const double main_width = itsStoryAspectRatio;
00311   const double main_height = itsNumStories + itsRoofHeight;
00312 
00313   using rutz::max;
00314 
00315   const double max_dim = max(main_height, main_width);
00316 
00317   const double extra_chimney_height =
00318     max(0.0, itsChimneyYPosition + itsChimneyHeight - itsRoofHeight);
00319 
00320   const double l = -main_width/2.0 * (1 + max(itsRoofOverhang, 0.0)) / max_dim;
00321   const double r =  main_width/2.0 * (1 + max(itsRoofOverhang, 0.0)) / max_dim;
00322   const double b = -main_height/2.0 / max_dim;
00323   const double t =  (main_height/2.0 + extra_chimney_height) / max_dim;
00324 
00325   bbox.drawRect(rectd::ltrb(l,t,r,b));
00326 }
00327 
00328 void House::grRender(Gfx::Canvas& canvas) const
00329 {
00330 GVX_TRACE("House::grRender");
00331   const double total_width = itsStoryAspectRatio;
00332   const double total_height = itsNumStories + itsRoofHeight;
00333 
00334   const double max_dimension =
00335     (total_height > total_width) ? total_height : total_width;
00336 
00337   Gfx::MatrixSaver msaver(canvas, "house");
00338   Gfx::AttribSaver asaver(canvas);
00339 
00340   // Scale so that the larger dimension (of width and height)
00341   // extends across 1.0 units in world coordinates. The smaller
00342   // dimension will extend across less than 1.0 world units.
00343   canvas.scale(vec3d(itsStoryAspectRatio/max_dimension,
00344                      1.0/max_dimension, 1.0));
00345 
00346   // Translate down by half the height of the house, then up by 0.5
00347   // units, so that we are positioned in the center of the first
00348   // story to be drawn.
00349   canvas.translate(vec3d(0.0, -total_height/2.0 + 0.5, 0.0));
00350 
00351   canvas.setPolygonFill(false);
00352 
00353 
00354   // Loop over house stories.
00355   for (int s = 0; s < itsNumStories; ++s)
00356     {
00357       drawStoryFrame(canvas);
00358 
00359       // Loop over window positions.
00360       for (int w = 0; w < itsNumWindows; ++w)
00361         {
00362           Gfx::MatrixSaver msaver(canvas, "window");
00363 
00364           double x_pos = double(w+0.5)/itsNumWindows - 0.5;
00365           if (s == 0 && w == itsDoorPosition )
00366             {
00367               // Draw door.
00368               canvas.translate(vec3d(x_pos, -0.5, 0.0));
00369               canvas.scale(vec3d(itsDoorWidth/itsNumWindows,
00370                                  itsDoorHeight, 1.0));
00371               if (itsDoorOrientation)
00372                 {
00373                   canvas.scale(vec3d(-1.0, 1.0, 1.0));
00374                 }
00375               drawDoor(canvas);
00376             }
00377           else
00378             {
00379               // Draw window.
00380               canvas.translate(vec3d(x_pos, 0.0, 0.0));
00381               canvas.scale(vec3d(itsWindowWidth/itsNumWindows,
00382                                  itsWindowHeight, 1.0));
00383               drawWindow(canvas, itsWindowVertBars, itsWindowHorizBars);
00384             }
00385         }
00386 
00387       canvas.translate(vec3d(0.0, 1.0, 0.0));
00388     }
00389 
00390 
00391   // Draw roof.
00392   canvas.translate(vec3d(0.0, -0.5, 0.0));
00393 
00394   {
00395     Gfx::MatrixSaver msaver(canvas, "roof");
00396     Gfx::AttribSaver asaver(canvas);
00397 
00398     canvas.scale(vec3d(1.0+itsRoofOverhang, itsRoofHeight, 1.0));
00399 
00400     canvas.setPolygonFill((itsRoofColor == 0));
00401 
00402     if (itsRoofShape == 0)
00403       {
00404         drawTriangleRoof(canvas);
00405       }
00406     else if (itsRoofShape == 1)
00407       {
00408         drawTrapezoidRoof(canvas);
00409       }
00410     else
00411       {
00412         drawSquareRoof(canvas);
00413       }
00414   }
00415 
00416   // Draw chimney.
00417   {
00418     Gfx::MatrixSaver msaver(canvas, "chimney");
00419     Gfx::AttribSaver asaver(canvas);
00420 
00421     canvas.translate(vec3d(itsChimneyXPosition,
00422                            itsChimneyYPosition, 0.0));
00423     canvas.scale(vec3d(itsChimneyWidth,
00424                        itsChimneyHeight, 1.0));
00425 
00426     canvas.setPolygonFill(true);
00427     drawChimney(canvas);
00428   }
00429 }
00430 
00431 static const char __attribute__((used)) vcid_groovx_visx_house_cc_utc20050626084015[] = "$Id: house.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00432 #endif // !GROOVX_VISX_HOUSE_CC_UTC20050626084015_DEFINED

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