00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00107 select(0, 0, GLWSelectorEntry(catagoryChoice_.getCurrentText()));
00108
00109
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
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
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
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
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
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
00426
00427
00428
00429
00430
00431
00432
00433
00434 }
00435
00436 void GLWTankViewer::selectModelByName(const char *name)
00437 {
00438 DIALOG_ASSERT(models_.size());
00439
00440
00441
00442
00443
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 }