aesop-client/lib/map-kdtree/test/test.cpp

Go to the documentation of this file.
00001 /*
00002  * test.cpp
00003  *
00004  * Copyright (C) 2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Quick test for the map-kdtree library.
00008  */
00009 
00010 // includes --------------------------------------------------------------------
00011 #include "datahash/datahash_text.h"
00012 #include "glut-demo/glut-demo.h"
00013 #include "map-kdtree/map-kdtree.h"
00014 #include "mapzone/mapzone.h"
00015 #include "model-loader/model-loader.h"
00016 #include "perf/perf.h"
00017 #include "physics-loader/physics-loader.h"
00018 
00019 
00020 static const char * s_bogusPhysicsParameters = 
00021         "physics {\n"
00022         "    minCoord       -10000\n"
00023         "    maxCoord       +10000\n"
00024         "    maxTimeSteps        5\n"
00025         "    engineTimeStep   0.02\n"
00026         "    gravityAxis         1\n"
00027         "    gravity          -9.8\n"
00028         "}\n";
00029 
00030 
00031 static aesop::map_draw_stats_t s_stats;
00032 
00033 
00034 ////////////////////////////////////////////////////////////////////////////////
00035 //
00036 //      static helper methods
00037 //
00038 ////////////////////////////////////////////////////////////////////////////////
00039 
00040 static void
00041 drawZone
00042 (
00043 IN aesop::Zone * zone,
00044 IN void * context
00045 )
00046 {
00047         ASSERT(zone, "null");
00048         // ASSERT(context) -- not used
00049 
00050         // determine color based on zone type
00051         glut_color_t c;
00052         float val = 1.0;
00053         float a2 = 0.5;
00054         float deflate = 0;
00055         switch (zone->getType()) {
00056         case aesop::Zone::eType_Parent:
00057                 c.set(  0, val,   0,  a2);
00058                 deflate = 0.25;
00059                 break;
00060         case aesop::Zone::eType_Leaf:
00061                 c.set(  0,   0, val,  a2);
00062                 deflate = 0.5;
00063                 break;
00064         case aesop::Zone::eType_VirtualLeaf:
00065                 c.set( a2,   0,  a2,  a2);
00066                 deflate = 0.5;
00067                 break;
00068         default:
00069                 ASSERT(false, "Bad zone type?");
00070         }
00071 
00072         rect3d_t r;
00073         zone->getBoundingRect(r);
00074         r.inflate(-deflate);
00075 
00076         glut::drawRectLines(r, c);
00077 }
00078 
00079 
00080 
00081 static void
00082 drawNode
00083 (
00084 IN const aesop::kd_node_t& kn,
00085 IN void * context
00086 )
00087 {
00088         // ASSERT(context) -- not used
00089 
00090         glut_color_t c(1.0, 1.0, 0, 0.5);
00091 //      kn.rect.dump("Node rect");
00092         rect3d_t r = kn.rect;
00093         r.inflate(-0.01 * kn.depth);
00094 
00095         glut::drawRectLines(r, c);
00096 }
00097 
00098 
00099 
00100 ////////////////////////////////////////////////////////////////////////////////
00101 //
00102 //      Drawer -- class that implements the glut::DemoHost interface
00103 //
00104 ////////////////////////////////////////////////////////////////////////////////
00105 
00106 class Drawer : public glut::DemoHost {
00107 public:
00108         Drawer(IN const char * mapId, IN const char * storyDir) :
00109             m_mapId(mapId), m_storyDir(storyDir) { }
00110         ~Drawer(void) throw() { }
00111 
00112         // glut::DemoHost class interface methods ------------------------------
00113         float getDelta(void) { return 0.1; }
00114 
00115         void onInit(void) {
00116                 perf::Timer timer("initializing");
00117 
00118                 const char * mapId = m_mapId.c_str();
00119                 const char * storyDir = m_storyDir.c_str();
00120 
00121                 // locale
00122                 const char * locale = i18n::getHostLocale();
00123                 if (!locale) {
00124                         locale = "en_US.UTF-8";
00125                 }
00126                 DPRINTF("Using locale = '%s'", locale);
00127 
00128                 // load story
00129                 smart_ptr<story::Story> story =
00130                     story::Story::create(locale, storyDir);
00131                 ASSERT_THROW(story, "failed to create story database");
00132 
00133                 // initialize typeinst library
00134                 aesop::initializeTypeInstanceLibrary(story);
00135 
00136                 // get 3D model loader
00137                 smart_ptr<aesop::TypeComponentLoader> modelLoader =
00138                     aesop::createModelLoader(story);
00139                 ASSERT_THROW(modelLoader, "failed to create 3D model loader");
00140                 aesop::registerTypeComponentLoader(modelLoader);
00141 
00142                 // get map path
00143                 std::string path = story->getObjectPath("map", mapId);
00144                 DPRINTF("Map id: '%s'", mapId);
00145                 DPRINTF("  --> path: %s", path.c_str());
00146 
00147                 // register the default mapzone loader
00148                 smart_ptr<aesop::MapFormatReader> reader =
00149                     mapzone::getMapFormatReader();
00150                 ASSERT_THROW(reader, "failed to acquire mapzone format reader");
00151                 registerMapFormatReader(reader);
00152 
00153                 // load map
00154                 smart_ptr<aesop::Map> map = aesop::loadMap(mapId, path.c_str());
00155                 ASSERT_THROW(map, "failed to load map");
00156 
00157                 // create a datahash with bogus physics parameters
00158                 std::istringstream iss(s_bogusPhysicsParameters);
00159                 smart_ptr<Datahash> params = readHashFromStream("root", iss);
00160                 ASSERT_THROW(params, "failed to create empty datahash");
00161 
00162                 // load map dynamics
00163                 m_dynamics = aesop::MapDynamics::create(map, params);
00164                 ASSERT_THROW(m_dynamics, "failed to create map dynamics");
00165 
00166                 // create map kdtree
00167                 m_kdTree = aesop::MapKdTree::create(m_dynamics);
00168                 ASSERT_THROW(m_kdTree, "failed to create map kdtree");
00169                 }
00170 
00171         void display3D(IN const glut::render_context_t& rc,
00172                                 IN glut::RenderQueue * rq) {
00173                         ASSERT(m_dynamics, "null");
00174                         ASSERT(m_kdTree, "null");
00175                         //DPRINTF("Drawing!");
00176 
00177                         // render all objects
00178                         aesop::drawMap(m_kdTree, rc, rq, s_stats);
00179 
00180                         // draw all zones
00181                         aesop::Map * map = m_dynamics->getMap();
00182                         ASSERT(map, "null");
00183 
00184                         map->iterateZones(drawZone, NULL);
00185 
00186                         // draw kd tree
00187                         m_kdTree->walkNodes(drawNode, NULL);
00188                 }
00189 
00190 private:
00191         // private member data -------------------------------------------------
00192         std::string                     m_mapId;
00193         std::string                     m_storyDir;
00194         smart_ptr<aesop::MapKdTree>     m_kdTree;
00195         smart_ptr<aesop::MapDynamics>   m_dynamics;
00196 };
00197 
00198 
00199 
00200 ////////////////////////////////////////////////////////////////////////////////
00201 //
00202 //      entry point
00203 //
00204 ////////////////////////////////////////////////////////////////////////////////
00205 
00206 int
00207 main
00208 (
00209 IN int argc,
00210 IN const char * argv[]
00211 )
00212 {
00213         int retval = 0;
00214         ASSERT(3 == argc,
00215             "Usage: map-kdtree-test <story-dir> <map-id>");
00216         const char * storyDir = argv[1];
00217         const char * mapId = argv[2];
00218 
00219         try {
00220                 // construct title
00221                 char title[1024];
00222                 sprintf(title, "MapKdTree test [map '%s' in story '%s']",
00223                     mapId, storyDir);
00224 
00225                 // main loop
00226                 smart_ptr<glut::DemoHost> host = new Drawer(mapId, storyDir);
00227                 ASSERT(host, "null");
00228                 glut::startDemo(argc, argv, title, host);
00229         } catch (std::exception& e) {
00230                 retval = 1;
00231                 DPRINTF("Exception: %s", e.what());
00232         }
00233 
00234         perf::dumpTimingSummary(std::cerr);
00235 
00236         return retval;
00237 }
00238