|
ORTS
|
00001 // $Id $ 00002 00003 // SimpleTerrain Widget Implementation 00004 #include "SimpleTerrainWidget.H" 00005 #include "ST_PFEngine.H" 00006 #include "GfxModule.H" 00007 #include "GfxGlobal.H" 00008 #include "Profiler.H" 00009 00010 #include "Game.H" 00011 #include "GameStateModule.H" 00012 00013 using namespace std; 00014 using boost::shared_ptr; 00015 00016 namespace SimpleTerrain { 00017 00018 //=================================================================== 00019 00020 SimpleTerrainOverlay::SimpleTerrainOverlay(const ST_Terrain &terrain, GfxModule &gfxm_) 00021 : dot(gfxm_), gfxm(&gfxm_) 00022 { 00023 enabled = false; 00024 terrain_p = &terrain; 00025 forcefield_p = 0; 00026 } 00027 SimpleTerrainOverlay::SimpleTerrainOverlay(const ST_ForceField &terrain, GfxModule &gfxm_) 00028 : dot(gfxm_), gfxm(&gfxm_) 00029 { 00030 // enabled = false; 00031 enabled = true; 00032 forcefield_p = &terrain; 00033 terrain_p = 0; 00034 } 00035 00036 //------------------------------------------------------------------- 00037 00038 bool SimpleTerrainOverlay::handle_event(const Event &e) 00039 { 00040 if (e.get_who() == GfxModule::FROM) { 00041 if (e.get_what() == GfxModule::DRAW_MSG) { 00042 draw(); 00043 return true; 00044 } 00045 } 00046 return false; 00047 } 00048 00049 //------------------------------------------------------------------- 00050 00051 void SimpleTerrainOverlay::draw() 00052 { 00053 PROFILE("TerrainOverlay"); 00054 00055 if (!enabled) return; 00056 00057 bool draw_air = false; 00058 00059 shared_ptr<const ST_Terrain::PFEngine::Map> map; 00060 if (forcefield_p){ 00061 if (!forcefield_p->pfEngine) return; 00062 map = draw_air ? forcefield_p->pfEngine->get_air_map() : forcefield_p->pfEngine->get_ground_map(); 00063 } 00064 else{ 00065 if (!terrain_p->pfEngine) return; 00066 map = draw_air ? terrain_p->pfEngine->get_air_map() : terrain_p->pfEngine->get_ground_map(); 00067 } 00068 00069 00070 //if (!st_terrain->pfEngine) return; 00071 00072 //shared_ptr<const ST_Terrain::PFEngine::Map> map = draw_air ? st_terrain->pfEngine->get_air_map() : st_terrain->pfEngine->get_ground_map(); 00073 00074 sint4 map_width = map->get_w(); 00075 sint4 map_height = map->get_h(); 00076 00077 sint4 gw = gfxm->get_game().get_map().get_width(); 00078 sint4 gh = gfxm->get_game().get_map().get_height(); 00079 00080 real4 dx = (real4)gw / (real4)(map_width-1); 00081 real4 dy = (real4)gh / (real4)(map_height-1); 00082 00083 { 00084 PROFILE("draw tiles"); 00085 #if 1 00086 dot.begin_squares(); 00087 FORS (xi, map_width) { 00088 FORS (yi, map_height) { 00089 if ((*map)(xi, yi).max_size > 0 || (*map)(xi, yi).cost != 0 ) { 00090 00091 Vec3<real4> c; 00092 real4 v = (*map)(xi, yi).max_size / 20.0; 00093 c = Vec3<real4>(v, 0, 0); 00094 // if ((*map)(xi, yi).max_size < 1) c = Vec3<real4>(1, 0, 0); 00095 // if ((*map)(xi, yi).cost > 0) c = Vec3<real4>(0, 1, 1); 00096 00097 real4 x1 = (xi-0.5) * dx; 00098 real4 x2 = (xi+0.5) * dx; 00099 real4 y1 = (yi-0.5) * dy; 00100 real4 y2 = (yi+0.5) * dy; 00101 00102 dot.draw_square(x1, y1, x2, y2, c); 00103 } 00104 } 00105 } 00106 dot.end_squares(); 00107 #endif 00108 } 00109 00110 { 00111 PROFILE("draw lines"); 00112 if (terrain_p){ 00113 const std::list<ST_Task> &tasks = terrain_p->tasks; 00114 00115 Vec3<real4> c(1,1,1); 00116 00117 dot.begin_lines(); 00118 FORALL (tasks, j) { 00119 if (!j->path) continue; 00120 const UnitPath &upath = *j->path; 00121 const Vector<Loc> &path = upath.path; 00122 00123 real4 x1, y1; 00124 if (path.size() > 1) { 00125 x1 = map->world2x(path[0].x); 00126 y1 = map->world2y(path[0].y); 00127 x1 *= dx; 00128 y1 *= dy; 00129 00130 for (uint4 i = 1; i < path.size(); ++i) { 00131 real4 x2 = map->world2x(path[i].x); 00132 real4 y2 = map->world2y(path[i].y); 00133 x2 *= dx; 00134 y2 *= dy; 00135 00136 dot.draw_line(x1, y1, x2, y2, c, 1.0); 00137 00138 x1 = x2; 00139 y1 = y2; 00140 } 00141 } 00142 } 00143 00144 dot.end_lines(); 00145 } 00146 else{ 00147 const std::list<FF_Task> &tasks = forcefield_p->tasks; 00148 00149 Vec3<real4> c(1,1,1); 00150 00151 dot.begin_lines(); 00152 FORALL (tasks, j) { 00153 if (!j->path) continue; 00154 const UnitPath_FF &upath = *j->path; 00155 const Vector<Loc> &path = upath.path; 00156 00157 real4 x1, y1; 00158 if (path.size() > 1) { 00159 x1 = map->world2x(path[0].x); 00160 y1 = map->world2y(path[0].y); 00161 x1 *= dx; 00162 y1 *= dy; 00163 00164 for (uint4 i = 1; i < path.size(); ++i) { 00165 real4 x2 = map->world2x(path[i].x); 00166 real4 y2 = map->world2y(path[i].y); 00167 x2 *= dx; 00168 y2 *= dy; 00169 00170 dot.draw_line(x1, y1, x2, y2, c, 1.0); 00171 00172 x1 = x2; 00173 y1 = y2; 00174 } 00175 } 00176 } 00177 00178 dot.end_lines(); 00179 } 00180 } 00181 00182 glEnable(GL_TEXTURE_2D); 00183 } 00184 00185 //=================================================================== 00186 //=================================================================== 00187 00188 SimpleTerrainWidget::SimpleTerrainWidget(const ST_Terrain &terrain, GfxModule *gfxm) 00189 { 00190 if (gfxm) { 00191 overlay = new SimpleTerrainOverlay(terrain, *gfxm); 00192 gfxm->add_handler(overlay); 00193 // overlay->enable(); 00194 } else { 00195 overlay = 0; 00196 } 00197 00198 draw_tiles = true; 00199 draw_air = false; 00200 wwidth = 0; 00201 wheight = 0; 00202 00203 set_name("ST_Terrain"); 00204 terrain_p = &terrain; 00205 forcefield_p = 0; 00206 } 00207 00208 SimpleTerrainWidget::SimpleTerrainWidget(const ST_ForceField &terrain, GfxModule *gfxm) 00209 { 00210 if (gfxm) { 00211 overlay = new SimpleTerrainOverlay(terrain, *gfxm); 00212 gfxm->add_handler(overlay); 00213 overlay->enable(); 00214 } else { 00215 overlay = 0; 00216 } 00217 00218 draw_tiles = true; 00219 draw_air = false; 00220 wwidth = 0; 00221 wheight = 0; 00222 00223 set_name("ST_ForceField"); 00224 forcefield_p = &terrain; 00225 terrain_p = 0; 00226 } 00227 00228 //------------------------------------------------------------------- 00229 00230 SimpleTerrainWidget::~SimpleTerrainWidget() 00231 { 00232 if (overlay) delete overlay; 00233 } 00234 00235 //=================================================================== 00236 00237 stype SimpleTerrainWidget::event_key_down(stype key, stype /*mod*/, stype x, stype y) 00238 { 00239 if (is_outside(x,y)) return stype(); 00240 cout << "event_key_down" << endl; 00241 00242 shared_ptr<const ST_Terrain::PFEngine::Map> map; 00243 00244 if (forcefield_p){ 00245 map = draw_air ? forcefield_p->pfEngine->get_air_map() : forcefield_p->pfEngine->get_ground_map(); 00246 } 00247 else{ 00248 map = draw_air ? terrain_p->pfEngine->get_air_map() : terrain_p->pfEngine->get_ground_map(); 00249 } 00250 00251 00252 // shared_ptr<const ST_Terrain::PFEngine::Map> map = draw_air ? st_terrain->pfEngine->get_air_map() : st_terrain->pfEngine->get_ground_map(); 00253 00254 char index = (char)key.to_int(); 00255 00256 switch(index){ 00257 00258 case '\t': 00259 if (overlay) { 00260 if (overlay->is_enabled()) { 00261 overlay->disable(); 00262 } else { 00263 overlay->enable(); 00264 } 00265 } 00266 return stype(1); 00267 00268 case 't': 00269 draw_tiles = !draw_tiles; 00270 return stype(1); 00271 00272 case 'a': 00273 draw_air = !draw_air; 00274 // map = draw_air ? air_map : gnd_map; 00275 return stype(1); 00276 00277 case 'p': 00278 FORS (y, map->get_h()) { 00279 FORS (x, map->get_w()) { 00280 if ((*map)(x,y).max_size >= 0) cout << " "; 00281 cout << (int)((*map)(x, y).max_size); 00282 } 00283 cout << endl; 00284 } 00285 case 'c': 00286 FORS (y, map->get_h()) { 00287 FORS (x, map->get_w()) { 00288 cout << " "; 00289 cout << (int)((*map)(x, y).cost); 00290 } 00291 cout << endl; 00292 } 00293 return stype(1); 00294 00295 default: 00296 break; 00297 } 00298 00299 return stype(); 00300 } 00301 00302 //=================================================================== 00303 00304 stype SimpleTerrainWidget::draw() 00305 { 00306 if (!!off) return stype(); 00307 00308 shared_ptr<const ST_Terrain::PFEngine::Map> map; 00309 00310 00311 if (forcefield_p){ 00312 if(!forcefield_p->pfEngine) return stype(); 00313 map = draw_air ? forcefield_p->pfEngine->get_air_map() : forcefield_p->pfEngine->get_ground_map(); 00314 } 00315 else{ 00316 if(!terrain_p->pfEngine) return stype(); 00317 map = draw_air ? terrain_p->pfEngine->get_air_map() : terrain_p->pfEngine->get_ground_map(); 00318 } 00319 00320 //shared_ptr<const ST_Terrain::PFEngine::Map> map = draw_air ? st_terrain->pfEngine->get_air_map() : st_terrain->pfEngine->get_ground_map(); 00321 00322 wwidth = map->get_w(); 00323 wheight = map->get_h(); 00324 00325 sint4 x = this->x.to_int(); 00326 sint4 y = this->y.to_int(); 00327 sint4 w = this->w.to_int(); 00328 sint4 h = this->h.to_int(); 00329 00330 real8 xd = (real8)w/(real8)wwidth; 00331 real8 yd = (real8)h/(real8)wheight; 00332 00333 draw_grid(wwidth, wheight); 00334 00335 FORS (xi, wwidth) { 00336 FORS (yi, wheight) { 00337 if ((*map)(xi, yi).max_size <= 0 || (*map)(xi, yi).cost != 0 ) { 00338 if ((*map)(xi, yi).max_size < 1) glColor4f(1, 0, 0, 1.0); 00339 if ((*map)(xi, yi).cost > 0) glColor4f(0, 1, 1, 1.0); 00340 glBegin(GL_QUADS); 00341 00342 glVertex2f( x+xi*xd , y+h-yi*yd -yd ); 00343 glVertex2f( x+xi*xd+xd , y+h-yi*yd -yd ); 00344 glVertex2f( x+xi*xd+xd , y+h-yi*yd+yd-yd ); 00345 glVertex2f( x+xi*xd , y+h-yi*yd+yd-yd ); 00346 00347 glEnd(); 00348 } 00349 } 00350 } 00351 00352 #if 1 00353 if (terrain_p){ 00354 const std::list<ST_Task> &tasks = terrain_p->tasks; 00355 FORALL (tasks, j) { 00356 if (!j->path) continue; 00357 const UnitPath &upath = *j->path; 00358 const Vector<Loc> &path = upath.path; 00359 00360 glColor4f(1, 1, 1, 1); 00361 glBegin(GL_LINE_STRIP); 00362 00363 FORALL (path, i) { 00364 sint4 wix = map->world2x(i->x); 00365 sint4 wiy = map->world2y(i->y); 00366 glVertex2f((real8)x+ ((real8)wix * xd), 00367 (real8)y+(real8)h-((real8)wiy * yd)); 00368 } 00369 00370 glEnd(); 00371 00372 //unit 00373 const Object *obj = upath.obj; 00374 sint4 ux, uy; 00375 obj->get_center(ux, uy); 00376 00377 glColor4f(1, 1, 1, 1); 00378 glBegin(GL_QUADS); 00379 00380 sint4 wux = map->world2x(ux); 00381 sint4 wuy = map->world2y(uy); 00382 00383 glVertex2f(x+(wux*xd), y+h-(wuy*yd)-yd); 00384 glVertex2f(x+(wux*xd)+xd, y+h-(wuy*yd)-yd); 00385 glVertex2f(x+(wux*xd)+xd, y+h-(wuy*yd) ); 00386 glVertex2f(x+(wux*xd), y+h-(wuy*yd) ); 00387 00388 glEnd(); 00389 } 00390 } 00391 else{ //st_terrain is a ST_ForceField 00392 const std::list<FF_Task> &tasks = forcefield_p->tasks; 00393 FORALL (tasks, j) { 00394 if (!j->path) continue; 00395 const UnitPath_FF &upath = *j->path; 00396 const Vector<Loc> &path = upath.path; 00397 00398 glColor4f(1, 1, 1, 1); 00399 glBegin(GL_LINE_STRIP); 00400 00401 FORALL (path, i) { 00402 sint4 wix = map->world2x(i->x); 00403 sint4 wiy = map->world2y(i->y); 00404 glVertex2f((real8)x+ ((real8)wix * xd), 00405 (real8)y+(real8)h-((real8)wiy * yd)); 00406 } 00407 00408 glEnd(); 00409 00410 //unit 00411 const Object *obj = upath.obj; 00412 sint4 ux, uy; 00413 obj->get_center(ux, uy); 00414 00415 glColor4f(1, 1, 1, 1); 00416 glBegin(GL_QUADS); 00417 00418 sint4 wux = map->world2x(ux); 00419 sint4 wuy = map->world2y(uy); 00420 00421 glVertex2f(x+(wux*xd), y+h-(wuy*yd)-yd); 00422 glVertex2f(x+(wux*xd)+xd, y+h-(wuy*yd)-yd); 00423 glVertex2f(x+(wux*xd)+xd, y+h-(wuy*yd) ); 00424 glVertex2f(x+(wux*xd), y+h-(wuy*yd) ); 00425 00426 glEnd(); 00427 } 00428 } 00429 00430 #endif 00431 00432 glEnable(GL_TEXTURE_2D); 00433 00434 return stype(); 00435 } 00436 00437 //=================================================================== 00438 00439 #if 0 00440 void SimpleTerrainWidget::set_env(Environment* env_){ 00441 env = env_; 00442 wwidth = map->get_w(); 00443 wheight = map->get_h(); 00444 } 00445 #endif 00446 00447 //=================================================================== 00448 00449 }