00001 #ifndef Impala_Application_Videolympics_VidolviWindow_h
00002 #define Impala_Application_Videolympics_VidolviWindow_h
00003
00004 #include "OglGui/Window.h"
00005 #include "Basis/Timer.h"
00006 #include "ServerConnector.h"
00007 #include "Visualization/FontHandler.h"
00008
00009 namespace Impala {
00010 namespace Application {
00011 namespace Videolympics {
00012
00013 using namespace OglGui;
00014
00015 class Point
00016 {
00017 public:
00018 Point(float nx, float ny, float nz)
00019 {
00020 x = nx; y = ny; z = nz;
00021 }
00022
00023 float x;
00024 float y;
00025 float z;
00026 };
00027
00028 class VidolviWindow : public OglGui::Window
00029 {
00030 public:
00031 VidolviWindow(OglGui::Window *parent, int w, int h) :
00032 Window(parent, w, h, false)
00033 {
00034 ILOG_DEBUG("Created VidolviWindow");
00035 oglSys.SetAllowCameraMove(GetOGLWND(), CamMove_Keys | CamMove_Mouse);
00036 mTimer = Timer(0);
00037 mUpdateNeeded = true;
00038
00039 mLastTime = 0.0;
00040 mTimer.Start();
00041
00042 phys = new PhysicsEngine();
00043 mStartLocation = map <int, Point*>();
00044 mScoreLocation = map <int, Point*>();
00045 mViews = vector<VidolviView*> ();
00046 mFontHandler = new Visualization::FontHandler();
00047 mStatusMessage = "";
00048 mState = STATE_NOTCONNECTED;
00049 mBackPlane = 0;
00050 mReconnectCount = 0;
00051
00052 firstView = true;
00053
00054 botshift = -2.5f;
00055 topshift = -2.0f;
00056 }
00057
00058
00059 void
00060 SetServer(ServerConnector *server)
00061 {
00062 mServer = server;
00063 }
00064
00065 void
00066 SetDataset(RawImageDataset *dataset)
00067 {
00068 mImages = dataset;
00069 }
00070
00071
00072 void
00073 AddTeamIcons(int nr)
00074 {
00075 mNrTeams = nr;
00076 float x, y, z;
00077 x = -(float)nr + 1.0f;
00078
00079
00080 y = botshift-4.9f;
00081 z = -17.0f;
00082
00083
00084 OGLIMAGE *header = TryReadPNG("icons/header.png");
00085 if (header != 0)
00086 {
00087
00088 OglGui::View *v = new OglGui::View(GetOGLWND(), header, 0.0f, topshift+8.25f, -16.75f, 23.0f, 2.7f, 1.0f);
00089
00090 view3DSys.SetObject3D(v->GetOGLVIEW3D(), 1);
00091 view3DSys.SetZoom(v->GetOGLVIEW3D(), 23.0f, 2.7f);
00092 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 0, GL_LINEAR);
00093 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 1, GL_LINEAR);
00094 oglSys.ReleaseOglImage(header);
00095 }
00096
00097 FlipDown();
00098 OGLIMAGE *bg = TryReadPNG("icons/background.png");
00099 if (bg != 0)
00100 {
00101 float w = nr * 2.0f;
00102 float h = nr * 2.0f;
00103 mBackPlane = new OglGui::View(GetOGLWND(), bg, 0.0f, 0.0f, z - 0.5f, w, h, 1.0f);
00104
00105 view3DSys.SetObject3D(mBackPlane->GetOGLVIEW3D(), 1);
00106 view3DSys.SetZoom(mBackPlane->GetOGLVIEW3D(), w, h);
00107 view3DSys.SetTexFilter(mBackPlane->GetOGLVIEW3D(), 0, GL_LINEAR);
00108 view3DSys.SetTexFilter(mBackPlane->GetOGLVIEW3D(), 1, GL_LINEAR);
00109 oglSys.ReleaseOglImage(bg);
00110 }
00111
00112 OGLIMAGE *pedestal = TryReadPNG("icons/pedestal.png");
00113
00114 for (int i=1; i<=nr; i++)
00115 {
00116 std::ostringstream f;
00117 f << "icons/team";
00118 f << i;
00119 f << ".png";
00120 std::string teamfile = f.str();
00121 ILOG_DEBUG("Reading team number " << teamfile);
00122 OGLIMAGE *im = TryReadPNG(teamfile.c_str());
00123 Point *p = new Point(x,y+0.0f,z -0.5f);
00124 mStartLocation[i] = p;
00125
00126 Point *ps = new Point(x,y + 0.1f, z + 0.6f);
00127 mScoreLocation[i] = ps;
00128
00129 if (im != 0)
00130 {
00131 OglGui::View *v = new OglGui::View(GetOGLWND(), im, x, y, z, 2.0f, 1.0f, 1.0f);
00132
00133 view3DSys.SetObject3D(v->GetOGLVIEW3D(), 2);
00134 view3DSys.SetZoom(v->GetOGLVIEW3D(), 2.0f, 1.0f);
00135 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 0, GL_LINEAR);
00136 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 1, GL_LINEAR);
00137 oglSys.ReleaseOglImage(im);
00138 }
00139
00140 im = 0;
00141 std::ostringstream g;
00142 g << "icons/icon";
00143 g << i;
00144 g << ".png";
00145 teamfile = g.str();
00146 ILOG_DEBUG("Reading team icon " << teamfile);
00147 im = TryReadPNG(teamfile.c_str());
00148
00149 if (im != 0)
00150 {
00151 OglGui::View *v = new OglGui::View(GetOGLWND(), im, x, y - 1.0f, z, 2.0f, 1.0f, 1.0f);
00152
00153 view3DSys.SetObject3D(v->GetOGLVIEW3D(), 2);
00154 view3DSys.SetZoom(v->GetOGLVIEW3D(), 2.0f, 1.0f);
00155 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 0, GL_LINEAR);
00156 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 1, GL_LINEAR);
00157 oglSys.ReleaseOglImage(im);
00158 }
00159
00160 if (pedestal != 0)
00161 {
00162 OglGui::View *v = new OglGui::View(GetOGLWND(), pedestal, x, y - 2.0f, z, 2.0f, 1.0f, 1.0f);
00163
00164 view3DSys.SetObject3D(v->GetOGLVIEW3D(), 2);
00165 view3DSys.SetZoom(v->GetOGLVIEW3D(), 2.0f, 1.0f);
00166 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 0, GL_LINEAR);
00167 view3DSys.SetTexFilter(v->GetOGLVIEW3D(), 1, GL_LINEAR);
00168 }
00169 x = x + 2.0f;
00170 }
00171
00172 if (pedestal) oglSys.ReleaseOglImage(pedestal);
00173
00174 }
00175
00176
00177 void
00178 GetNewImages()
00179 {
00180 static int ctr = 0;
00181
00182 static int nteamnr = 0;
00183 nteamnr ++;
00184 ctr ++;
00185 if (nteamnr >8) nteamnr = 1;
00186
00187 int teamnr = nteamnr;
00188 int shotnr = ctr;
00189
00190 while (1)
00191 {
00192 ShotPacket *x = mServer->GetPacket();
00193 if (x!=NULL)
00194 {
00195 ILOG_INFO("Received: SHOT: " << x->shotName << " TEAM:" << x->teamID << " SEQ:" << x->sequenceNo << " SHOT:" << x->shotNo << " at " << x->timestamp);
00196
00197 Point *start = mStartLocation[x->teamID];
00198 if (start != 0) {
00199 ILOG_DEBUG(" Start: team=" << x->teamID << " x=" << start->x << " y=" << start->y << " z=" << start->z);
00200 Array2dVec3UInt8* image = mImages->GetImage(x->shotNo);
00201 if (image == 0) {
00202 ILOG_ERROR("Could not load image.");
00203 continue;
00204 }
00205 VidolviView *v = new VidolviView(GetOGLWND(), image, start->x, start->y, start->z, 1.4f, 1.00f, 0.6f);
00206 v->SetRelevance(x->relevance, x->selectedByOthers);
00207 phys->RegisterPart(v->GetPPart(), x->teamID);
00208 mViews.push_back(v);
00209 } else {
00210 ILOG_ERROR("no starting point found for team " << teamnr);
00211 }
00212
00213
00214 delete x;
00215 }
00216 else
00217 {
00218 ILOG_DEBUG("no more packets.");
00219 break;
00220 }
00221 }
00222 }
00223
00224 void
00225 RemoveOldImages()
00226 {
00227 vector<VidolviView*>::iterator i = mViews.begin();
00228 while (i != mViews.end())
00229 {
00230 VidolviView *view = *i;
00231 if (view->GetPPart()->ShouldDestroy())
00232 {
00233 ILOG_DEBUG("Destroying view " << view->GetViewNr() << "...");
00234 phys->UnregisterPart(view->GetPPart());
00235 delete view;
00236 i = mViews.erase(i);
00237 } else {
00238 i++;
00239 }
00240 }
00241 ILOG_DEBUG("done.");
00242 }
00243
00244 void
00245 RemoveAllImages()
00246 {
00247 ILOG_DEBUG("Removing all images...");
00248 vector<VidolviView*>::iterator i = mViews.begin();
00249 while (i != mViews.end())
00250 {
00251 VidolviView *view = *i;
00252 ILOG_DEBUG("Destroying view " << view->GetViewNr() << "...");
00253 phys->UnregisterPart(view->GetPPart());
00254 delete view;
00255 i = mViews.erase(i);
00256 }
00257 ILOG_DEBUG("done.");
00258 }
00259
00260 void
00261 ShowScores()
00262 {
00263 glPushMatrix();
00264 OGC oldOGC;
00265 INT oldBlendInfo[3];
00266 OGCSave( &oldOGC );
00267 oglSys.StartBlend( &oldBlendInfo[0] );
00268
00269
00270
00271
00272
00273
00274 if (!mServer->GetGlobalStats()->connected)
00275 {
00276 oglSys.EndBlend( &oldBlendInfo[0] );
00277 OGCRestore( &oldOGC );
00278 glPopMatrix();
00279 return;
00280 }
00281
00282 if (mServer->GetGlobalStats()->timeSinceStart < 0)
00283 {
00284
00285 int countdown = -(int)mServer->GetGlobalStats()->timeSinceStart + 1;
00286
00287 if (mIsCountDown) {
00288 if (mCountDownLastCount != countdown) {
00289 mCountFloater = -0.02f;
00290 mCountDownLastCount = 0.0f;
00291 mCountDownLastCount = countdown;
00292 } else {
00293 mCountFloater = mCountFloater * 1.1;
00294 if (mCountFloater < -4.0f)
00295 mCountFloater = -4.0f;
00296 }
00297 } else {
00298 mIsCountDown = true;
00299 mCountFloater = -0.02f;
00300 mCountDownLastCount = countdown;
00301 FlipUp();
00302 }
00303
00304 float z = mCountFloater;
00305
00306 glColor3f(1.0f, 1.0f, 0.0f);
00307 oglSys.Printf3D(mFontHandler->GetFontBase(this), -2.2f, topshift+6.5f, -13.0f, 0.5f, 0.5f, 0.1f, "Contest starting in ... ");
00308
00309 glColor3f(0.8f, 0.8f, 0.2f);
00310 ostringstream s;
00311 s << countdown;
00312 oglSys.Printf3D(mFontHandler->GetFontBase(this), -0.8f, -0.9f, -5.0f - z * 2.0f, 2.5f, 2.5f, 0.5f, s.str().c_str());
00313
00314
00315 } else {
00316 mIsCountDown = false;
00317
00318 glColor3f(0.9f, 0.6f, 0.6f);
00319 oglSys.Printf3D(mFontHandler->GetFontBase(this), -2.2f, topshift+6.5f, -13.0f, 0.5f, 0.5f, 0.1f, mStatusMessage.c_str());
00320
00321 glColor3f(0.9f, 0.9f, 0.9f);
00322 ostringstream s;
00323 s << "Time: ";
00324 s << (int)mServer->GetGlobalStats()->timeSinceStart;
00325 oglSys.Printf3D(mFontHandler->GetFontBase(this), +5.5f, topshift+7.5f, -13.0f, 0.5f, 0.5f, 0.1f, s.str().c_str());
00326
00327 glColor3f(0.4f, 1.0f, 0.4f);
00328 ostringstream sp;
00329 sp << "Positive: ";
00330 sp << mServer->GetGlobalStats()->positive;
00331 oglSys.Printf3D(mFontHandler->GetFontBase(this), +5.5f, topshift+7.0f, -13.0f, 0.5f, 0.5f, 0.1f, sp.str().c_str());
00332
00333 glColor3f(1.0f, 0.4f, 0.4f);
00334 ostringstream sn;
00335 sn << "Negative: ";
00336 sn << mServer->GetGlobalStats()->negative;
00337 oglSys.Printf3D(mFontHandler->GetFontBase(this), +5.5f, topshift+6.5f, -13.0f, 0.5f, 0.5f, 0.1f, sn.str().c_str());
00338 }
00339
00340 oglSys.EndBlend( &oldBlendInfo[0] );
00341 OGCRestore( &oldOGC );
00342
00343 glPopMatrix();
00344
00345 for (int teamno=1; teamno <= mNrTeams; teamno++)
00346 {
00347 glPushMatrix();
00348 Point *sp = mScoreLocation[teamno];
00349 if (sp)
00350 {
00351 glTranslatef(sp->x - 0.7f, sp->y, sp->z);
00352 glColor3f(0.4f, 0.4f, 1.0f);
00353 std::ostringstream unj, pos, neg;
00354
00355
00356
00357 StatsPacket *stats = mServer->GetStats(teamno);
00358
00359 if (stats)
00360 {
00361 unj << stats->unjudged;
00362 pos << stats->positive;
00363 neg << stats->negative;
00364
00365 glTranslatef(0.0f, 0.00f, 0.0f); glColor3f(1.0f, 0.4f, 0.4f);
00366 oglSys.Printf3D(mFontHandler->GetFontBase(this), 0.0f, 0.0f, 0.0f, 0.4f, 0.4f, 0.1f,
00367 neg.str().c_str());
00368 glTranslatef(0.5f, 0.0f, 0.0f); glColor3f(0.4f, 1.0f, 0.4f);
00369 oglSys.Printf3D(mFontHandler->GetFontBase(this), 0.0f, 0.0f, 0.0f, 0.4f, 0.4f, 0.1f,
00370 pos.str().c_str());
00371 glTranslatef(0.5f, 0.0f, 0.0f); glColor3f(0.6f, 0.6f, 0.6f);
00372 oglSys.Printf3D(mFontHandler->GetFontBase(this), 0.0f, 0.0f, 0.0f, 0.4f, 0.4f, 0.1f,
00373 unj.str().c_str());
00374 }
00375 }
00376 glPopMatrix();
00377 }
00378
00379 }
00380
00381 void
00382 FlipDown()
00383 {
00384 mBackX = 0.0f;
00385 mBackY = -26.0f;
00386 mBackZ = -40.0f - 0.5f;
00387 mBackDown = true;
00388 mReconnectCount = 8;
00389 }
00390
00391 void
00392 FlipUp()
00393 {
00394 mBackX = 0.0f;
00395 mBackY = 2.0f;
00396 mBackZ = -17.0f - 0.5f;
00397 mBackDown = false;
00398 }
00399
00400 void
00401 DoFlip()
00402 {
00403 if (!mBackPlane) return;
00404 if (phys->IsFlushing()) return;
00405 float x,y,z;
00406 view3DSys.GetDimensions(mBackPlane->GetOGLVIEW3D(), &x, &y, &z, NULL, NULL, NULL);
00407 x += (mBackX - x) * 0.02;
00408 y += (mBackY - y) * 0.02;
00409 z += (mBackZ - z) * 0.02;
00410 view3DSys.SetDimensions(mBackPlane->GetOGLVIEW3D(), x,y,z,FRETAIN,FRETAIN,FRETAIN);
00411 }
00412
00413 void
00414 DoScreenSaver()
00415 {
00416 if (!mBackDown) return;
00417
00418 }
00419
00420 int mScrnSvImNr;
00421 bool firstView;
00422
00423 float topshift;
00424 float botshift;
00425
00426 void
00427 DisplayFunc()
00428 {
00429 Window::DisplayFunc();
00430
00431 if (firstView) {
00432 view3DSys.SetCamera(GetOGLWND(), 0.0f, -1.0f, +4.0f, 0.0f, 0.0f, 0.0f);
00433 firstView = false;
00434 }
00435
00436 double nowTime = mTimer.SplitTime();
00437 if (nowTime - mLastTime > 0.2) {
00438 mLastTime = nowTime;
00439
00440 if (mReconnectCount <= 0) {
00441 mServer->Update();
00442 if (!mServer->GetGlobalStats()->connected)
00443 mReconnectCount = 8;
00444 } else {
00445 mReconnectCount--;
00446 }
00447
00448 if (mServer->GetGlobalStats()->connected)
00449 {
00450 if (mState == STATE_NOTCONNECTED)
00451 FlipUp();
00452
00453 if (mServer->GetGlobalStats()->contestActive == 1)
00454 {
00455 mStatusMessage = "Contest running...";
00456 mState = STATE_RUNNING;
00457 GetNewImages();
00458 RemoveOldImages();
00459 } else {
00460 if (mServer->GetGlobalStats()->contestActive == 0)
00461 {
00462 if (mState == STATE_RUNNING || mState == STATE_ENDED)
00463 {
00464
00465 RemoveAllImages();
00466 FlipDown();
00467 }
00468 mState = STATE_GETREADY;
00469 mStatusMessage = "Get Ready!!!";
00470 } else {
00471 mState = STATE_ENDED;
00472 mStatusMessage = "Contest ended!";
00473 }
00474 }
00475 } else {
00476 mStatusMessage = "contest server offline";
00477
00478 if (mState != STATE_NOTCONNECTED) {
00479 phys->FlushStacks();
00480 FlipDown();
00481 mReconnectCount = 10;
00482 }
00483 RemoveOldImages();
00484 mState = STATE_NOTCONNECTED;
00485 }
00486 }
00487
00488 DoFlip();
00489 ShowScores();
00490
00491 if (mUpdateNeeded)
00492 GetOGLWND()->updateScene = 1;
00493
00494 phys->DoPhysics();
00495 }
00496 int mReconnectCount;
00497 int mState;
00498 static const int STATE_NOTCONNECTED = 0;
00499 static const int STATE_CONNECTED = 1;
00500 static const int STATE_GETREADY = 2;
00501 static const int STATE_RUNNING = 3;
00502 static const int STATE_ENDED = 4;
00503
00504 bool mUpdateNeeded;
00505 bool mBackDown;
00506 float mBackX, mBackY, mBackZ;
00507
00508 RawImageDataset *mImages;
00509 ServerConnector *mServer;
00510 Timer mTimer;
00511 double mLastTime;
00512 int mNrTeams;
00513
00514 OglGui::View *mBackPlane;
00515 PhysicsEngine *phys;
00516
00517 vector <VidolviView*> mViews;
00518
00519 map <int, Point*> mStartLocation;
00520 map <int, Point*> mScoreLocation;
00521
00522 std::string mStatusMessage;
00523
00524 Visualization::FontHandler *mFontHandler;
00525
00526 ILOG_VAR_DEC;
00527
00528 bool mIsCountDown;
00529 int mCountDownLastCount;
00530 float mCountFloater;
00531
00532 };
00533
00534 ILOG_VAR_INIT(VidolviWindow, Visualization.Application.Videolympics);
00535
00536
00537 }
00538 }
00539 }
00540
00541 #endif
00542