GLWTankViewer.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <GLW/GLWTankViewer.h>
00022 #include <tank/TankModelStore.h>
00023 #include <tankgraph/TankMeshStore.h>
00024 #include <3dsparse/ModelStore.h>
00025 #include <client/ScorchedClient.h>
00026 #include <graph/OptionsDisplay.h>
00027 #include <graph/ModelRendererMesh.h>
00028 #include <common/DefinesString.h>
00029 #include <lang/LangResource.h>
00030 #include <GLW/GLWFont.h>
00031 #include <GLW/GLWTranslate.h>
00032 
00033 static const float TankSquareSize = 90.0f;
00034 static const float TankHalfSquareSize = TankSquareSize / 2.0f;
00035 static const float TankPadding = 20.0f;
00036 static const float TankInfo = 320.0f;
00037 
00038 GLWTankViewer::GLWTankViewer(float x, float y, int numH, int numV) :
00039         GLWidget(x, y, 
00040                                          TankSquareSize * numH + TankPadding, 
00041                                          TankSquareSize * numV + TankPadding),
00042         scrollBar_(w_ - 12.0f, y + 2.0f, h_ - 4.0f, 0, 0, numV),
00043         infoWindow_(x + TankSquareSize * numH + TankPadding + 10.0f, 
00044                                 y + TankSquareSize * numV + TankPadding - TankInfo + 30.0f, 
00045                                 TankInfo, TankInfo, true),
00046         numH_(numH), numV_(numV),
00047         rot_(0.0f), selected_(0),
00048         rotXY_(0.0f), rotYZ_(0.0f), 
00049         rotXYD_(1.0f), rotYZD_(1.0f),
00050         totalTime_(0.0f),
00051         team_(0),
00052         catagoryChoice_(x, 
00053                                         y + TankSquareSize * numV + TankPadding + 5.0f,
00054                                         + TankSquareSize * numH + TankPadding)
00055 {
00056         std::set<std::string> &catagories = 
00057                 ScorchedClient::instance()->getTankModels().getModelCatagories();
00058         std::set<std::string>::iterator catItor;
00059         for (catItor = catagories.begin();
00060                  catItor != catagories.end();
00061                  catItor++)
00062         {
00063                 catagoryChoice_.addText(LANG_RESOURCE(*catItor, *catItor), (*catItor));
00064         }
00065 
00066         catagoryChoice_.setHandler(this);
00067         catagoryChoice_.setCurrentPosition(0);
00068         if (catagoryChoice_.getCurrentEntry()) 
00069         {
00070                 select(0, 0, *catagoryChoice_.getCurrentEntry());
00071         }
00072 
00073         catagoryChoice_.setToolTip(new ToolTip(ToolTip::ToolTipHelp, 
00074                 LANG_RESOURCE("MODEL_CATAGORY", "Model Catagory"),
00075                 LANG_RESOURCE("MODEL_CATAGORY_TOOLTIP", 
00076                 "Displays the currently selected model catagory.\n"
00077                 "To make models easier to locate\n"
00078                 "tank models are grouped by catagory.")));
00079         infoWindow_.setToolTip(new ToolTip(ToolTip::ToolTipHelp, 
00080                 LANG_RESOURCE("CURRENT_MODEL", "Current Model"),
00081                 LANG_RESOURCE("CURRENT_MODEL_TOOLTIP", 
00082                 "Displays the currently selected tank model.\n"
00083                 "This is the model this player will use in game.\n"
00084                 "Choose a new model from the selection on the\n"
00085                 "left.")));
00086 }
00087 
00088 GLWTankViewer::~GLWTankViewer()
00089 {
00090 
00091 }
00092 
00093 void GLWTankViewer::setTeam(int team)
00094 {
00095         team_ = team;
00096 
00097         // Save current model
00098         int scrollCurrent = scrollBar_.getCurrent();
00099         TankModel *model = 0;
00100         if (selected_ >= 0 &&
00101                 selected_ < (int) models_.size())
00102         {
00103                 model = models_[selected_].model;
00104         }
00105 
00106         // Show new team models
00107         select(0, 0, GLWSelectorEntry(catagoryChoice_.getCurrentText()));
00108 
00109         // Select old model
00110         scrollBar_.setCurrent(scrollCurrent);
00111         for (int i=0; i<(int)models_.size(); i++)
00112         {
00113                 if (models_[i].model == model) selected_ = i;
00114         }
00115 }
00116 
00117 void GLWTankViewer::select(unsigned int id, 
00118                                                    const int pos, 
00119                                                    GLWSelectorEntry value)
00120 {
00121         std::vector<ModelEntry> newmodels;
00122 
00123         std::vector<TankModel *> &models = 
00124                 ScorchedClient::instance()->getTankModels().getModels();
00125         std::vector<TankModel *>::iterator modelItor;
00126         for (modelItor = models.begin();
00127                  modelItor != models.end();
00128                  modelItor++)
00129         {
00130                 TankModel *tankModel = (*modelItor);
00131                 if (tankModel->isOfCatagory(value.getDataText()))
00132                 {
00133                         // Check if this tank is allowed for this team
00134                         if (!tankModel->isOfTeam(team_) ||
00135                                 !tankModel->isOfAi(false))
00136                         {
00137                                 continue;
00138                         }
00139 
00140                         ModelEntry entry;
00141                         entry.model = tankModel;
00142                         entry.mesh = 0;
00143                         newmodels.push_back(entry);
00144                 }
00145         }
00146 
00147         setTankModels(newmodels);
00148 }
00149 
00150 void GLWTankViewer::setTankModels(std::vector<ModelEntry> &models)
00151 {
00152         models_.clear();
00153         models_ = models;
00154         scrollBar_.setMax((int) (models_.size() / numH_) + 1);
00155         scrollBar_.setCurrent(0);
00156         selected_ = 0;
00157 
00158         // Sort the models 
00159         bool sorted = false;
00160         while (!sorted)
00161         {
00162                 sorted = true;
00163                 for (int i=0; i<(int) models_.size()-1; i++)
00164                 {
00165                         ModelEntry tmp = models_[i];
00166                         ModelEntry test = models_[i+1];
00167                         if (test.model->lessThan(tmp.model))
00168                         {
00169                                 models_[i] = test;
00170                                 models_[i+1] = tmp;
00171                                 sorted = false;
00172                         }
00173                 }
00174         }
00175 
00176         // Move random model to the top
00177         std::vector<ModelEntry>::iterator itor;
00178         for (itor = models_.begin();
00179                 itor != models_.end();
00180                 itor++)
00181         {
00182                 ModelEntry entry = (*itor);
00183                 if (0==strcmp(entry.model->getName(),"Random"))
00184                 {
00185                         models_.erase(itor);
00186                         std::vector<ModelEntry> tmpVector;
00187                         tmpVector.push_back(entry);
00188                         tmpVector.insert(tmpVector.end(), models_.begin(), models_.end());
00189                         models_ = tmpVector;
00190                         break;
00191                 }
00192         }
00193 }
00194 
00195 const char *GLWTankViewer::getModelName()
00196 {
00197         const char *name = "None";
00198         if (selected_ >= 0 &&
00199                 selected_ < (int) models_.size())
00200         {
00201                 name = models_[selected_].model->getName();
00202         }
00203         return name;
00204 }
00205 
00206 void GLWTankViewer::simulate(float frameTime)
00207 {
00208         totalTime_ += frameTime;
00209         rot_ += frameTime * 45.0f;
00210         rotXY_ += frameTime * rotXYD_ * 5.0f;
00211         rotYZ_ += frameTime * rotYZD_ * 5.0f;
00212         if (rotXY_ < -45.0f)
00213         {
00214                 rotXY_ = -45.0f;
00215                 rotXYD_ = 1.0f;
00216         }
00217         else if (rotXY_ > 45.0f)
00218         {
00219                 rotXY_ = 45.0f;
00220                 rotXYD_ = -1.0f;
00221         }
00222         if (rotYZ_ < 0.0f)
00223         {
00224                 rotYZ_ = 0.0f;
00225                 rotYZD_ = 1.0f;
00226         }
00227         else if (rotYZ_ > 45.0f)
00228         {
00229                 rotYZ_ = 45.0f;
00230                 rotYZD_ = -1.0f;
00231         }
00232 
00233         scrollBar_.simulate(frameTime);
00234 }
00235 
00236 void GLWTankViewer::draw()
00237 {
00238         Vector4 sunPosition(-100.0f, 100.0f, 400.0f, 1.0f);
00239         Vector4 sunDiffuse(0.9f, 0.9f, 0.9f, 1.0f);
00240         Vector4 sunAmbient(0.4f, 0.4f, 0.4f, 1.0f);
00241         glLightfv(GL_LIGHT1, GL_AMBIENT, sunAmbient);
00242         glLightfv(GL_LIGHT1, GL_DIFFUSE, sunDiffuse);
00243 
00244         glBegin(GL_LINE_LOOP);
00245                 drawShadedRoundBox(x_, y_, w_, h_, 6.0f, false);
00246         glEnd();
00247 
00248         infoWindow_.draw();
00249         scrollBar_.draw();
00250 
00251         GLState depthState(GLState::DEPTH_ON);
00252         const float heightdiv = (h_ / float(numV_));
00253         const float widthdiv = ((w_ - TankPadding - 10) / float(numH_));
00254 
00255         int pos = 0;
00256         for (int posV=0; posV<numV_; posV++)
00257         {
00258                 for (int posH=0; posH<numH_; posH++, pos++)
00259                 {
00260                         int vectorPos = (scrollBar_.getCurrent() * numH_) + pos;
00261                         if (vectorPos < (int) models_.size() &&
00262                                 vectorPos >= 0)
00263                         {
00264                                 float posX = x_ + widthdiv * posH + TankHalfSquareSize + 2.0f;
00265                                 float posY = y_ + heightdiv * posV + TankHalfSquareSize + 2.0f;
00266 
00267                                 bool currselected = (vectorPos == selected_);
00268                                 if (currselected)
00269                                 {
00270                                         glColor3f(0.4f, 0.4f, 0.6f);
00271                                         glBegin(GL_LINE_LOOP);
00272                                                 float SelectSize = TankHalfSquareSize - 2.0f;
00273                                                 glVertex2f(posX - SelectSize, posY - SelectSize);
00274                                                 glVertex2f(posX + SelectSize, posY - SelectSize);
00275                                                 glVertex2f(posX + SelectSize, posY + SelectSize);
00276                                                 glVertex2f(posX - SelectSize, posY + SelectSize);
00277                                         glEnd();
00278                                 }
00279 
00280                                 if (GLWToolTip::instance()->addToolTip(&toolTip_, 
00281                                         GLWTranslate::getPosX() + posX - TankHalfSquareSize, 
00282                                         GLWTranslate::getPosY() + posY - TankHalfSquareSize, 
00283                                         TankSquareSize,
00284                                         TankSquareSize))
00285                                 {
00286                                         TankType *type = ScorchedClient::instance()->getTankModels().
00287                                                 getTypeByName(models_[vectorPos].model->getTypeName());
00288                                         toolTip_.setText(
00289                                                 ToolTip::ToolTipInfo, 
00290                                                 LANG_STRING(models_[vectorPos].model->getName()),
00291                                                 LANG_STRING(type->getDescription()));   
00292                                 }
00293 
00294                                 float scale = 22.0f / 60.0f * TankSquareSize;
00295                                 glPushMatrix();
00296                                         glTranslatef(posX, posY - 5.0f, 0.0f);
00297                                         glLightfv(GL_LIGHT1, GL_POSITION, sunPosition);
00298 
00299                                         glRotatef(-45.0f, 1.0f, 0.0f, 0.0f);
00300                                         if (currselected) glRotatef(rot_, 0.0f, 0.0f, 1.0f);
00301                                         glScalef(scale, scale, scale);
00302 
00303                                         drawItem(vectorPos, currselected);
00304                                 glPopMatrix();
00305                         }
00306                 }
00307         }
00308 
00309         if (selected_ >= 0 &&
00310                 selected_ < (int) models_.size())
00311         {
00312                 const float infoX = infoWindow_.getX() + (infoWindow_.getW() / 2.0f);
00313                 const float infoY = infoWindow_.getY() + (infoWindow_.getH() / 2.0f) - 35.0f;
00314                 glPushMatrix();
00315                         glTranslatef(infoX, infoY, 0.0f);
00316                         glLightfv(GL_LIGHT1, GL_POSITION, sunPosition);
00317 
00318                         drawCaption(selected_);
00319                         glRotatef(-45.0f, 1.0f, 0.0f, 0.0f);
00320                         glRotatef(rot_, 0.0f, 0.0f, 1.0f);
00321                         glScalef(100.0f, 100.0f, 100.0f);
00322         
00323                         drawItem(selected_, true);
00324                 glPopMatrix();
00325         }
00326 
00327         GLState depthStateOff(GLState::DEPTH_OFF);
00328         catagoryChoice_.draw();
00329 }
00330 
00331 void GLWTankViewer::mouseDown(int button, float x, float y, bool &skipRest)
00332 {
00333         scrollBar_.mouseDown(button, x, y, skipRest);
00334         if (!skipRest)
00335         {
00336                 catagoryChoice_.mouseDown(button, x, y, skipRest);
00337                 if (!skipRest)
00338                 {
00339                         if (inBox(x, y, x_, y_, w_, h_))
00340                         {
00341                                 int posY = int((y - y_) / (h_ / numV_));
00342                                 int posX = int((x - x_) / (w_ / numH_));
00343                                 
00344                                 int vectorPos = posX + posY * numH_ + scrollBar_.getCurrent() * numH_;
00345                                 if (vectorPos < (int) models_.size() &&
00346                                         vectorPos >= 0)
00347                                 {
00348                                         selected_ = vectorPos;
00349                                 }
00350                         }
00351                 }
00352         }
00353 }
00354 
00355 void GLWTankViewer::mouseDrag(int button, float mx, float my, float x, float y, bool &skipRest)
00356 {
00357         scrollBar_.mouseDrag(button, mx, my, x, y, skipRest);
00358 }
00359 
00360 void GLWTankViewer::mouseUp(int button, float x, float y, bool &skipRest)
00361 {
00362         scrollBar_.mouseUp(button, x, y, skipRest);
00363 }
00364 
00365 void GLWTankViewer::mouseWheel(float x, float y, float z, bool &skipRest)
00366 {
00367         if (inBox(x, y, x_, y_, w_, h_))
00368         {
00369                 skipRest = true;
00370 
00371                 if (z < 0.0f) scrollBar_.setCurrent(scrollBar_.getCurrent() + 1);
00372                 else scrollBar_.setCurrent(scrollBar_.getCurrent() - 1);
00373         }
00374 }
00375 
00376 void GLWTankViewer::drawCaption(int pos)
00377 {
00378         GLState state(GLState::DEPTH_OFF);
00379 
00380         LANG_RESOURCE_VAR_1(TANK_NAME, "TANK_NAME", "Tank Name : {0}", models_[pos].model->getName());
00381 
00382         Vector color(0.3f, 0.3f, 0.3f);
00383         GLWFont::instance()->getGameFont()->
00384                 drawWidth(TankInfo - 20.0f, 
00385                         color, 10.0f, -150.0f, 175.0f, 0.0f, 
00386                         TANK_NAME);
00387 }
00388 void GLWTankViewer::drawItem(int pos, bool selected)
00389 {
00390         TankMesh *mesh = models_[pos].mesh;
00391         if (!mesh)
00392         {
00393                 mesh = TankMeshStore::instance()->getMesh(
00394                         models_[pos].model->getTankModelID());
00395                 models_[pos].mesh = mesh;
00396         }
00397 
00398         // Tank
00399         Vector4 tankRot(1.0f, 0.0f, 0.0f, 0.0f);
00400         float matrix[16];
00401         tankRot.getOpenGLRotationMatrix(matrix);
00402 
00403         Vector tankPos;
00404         if (selected)
00405         {
00406                 mesh->draw(totalTime_ * 20.0f, false, 
00407                         matrix, tankPos, 0.0f, rotXY_, rotYZ_);
00408         }
00409         else
00410         {
00411                 mesh->draw(totalTime_ * 20.0f, false, 
00412                         matrix, tankPos, 0.0f, 45.0f, 45.0f);
00413         }
00414 
00415         // Ground
00416         GLState state(GLState::TEXTURE_OFF);
00417         glColor3f(181.0f / 255.0f, 204.0f / 255.0f, 237.0f / 255.0f);
00418         glBegin(GL_QUADS);
00419                 glVertex2f(1.0f, 1.0f);
00420                 glVertex2f(-1.0f, 1.0f);
00421                 glVertex2f(-1.0f, -1.0f);
00422                 glVertex2f(1.0f, -1.0f);
00423         glEnd();
00424 
00425         //Shadow
00426         /*{
00427                 glDepthMask(GL_FALSE);
00428                 glPushMatrix();
00429                         glScalef(1.0f, 1.0f, 0.0f);
00430                         models[pos]->draw(false, tankPos, 0.0f, rotXY_, rotYZ_);
00431                 glPopMatrix();
00432                 glDepthMask(GL_TRUE);
00433         }*/
00434 }
00435 
00436 void GLWTankViewer::selectModelByName(const char *name)
00437 {
00438         DIALOG_ASSERT(models_.size());
00439 
00440         // Ensure that all models have been loaded
00441         //select(0, 0, "All");
00442 
00443         // Select the appropriate model
00444         int currentSel = 0;
00445         std::vector<ModelEntry>::iterator itor;
00446         for (itor = models_.begin();
00447                  itor != models_.end();
00448                  itor++, currentSel ++)
00449         {
00450                 TankModel *current = (*itor).model;
00451                 if (0 == strcmp(current->getName(), name))
00452                 {
00453                         selected_ = currentSel;
00454                         return;
00455                 }
00456         }
00457 }

Generated on Mon Feb 16 15:14:46 2009 for Scorched3D by  doxygen 1.5.3