git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched...
[scorched3d/parasti.git] / src / client / GLW / GLWTankViewer.cpp
bloba9c84a64fd03c5db9fc2e6af00a0358de74239db
1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <GLW/GLWTankViewer.h>
22 #include <tank/TankModelStore.h>
23 #include <tankgraph/TankMeshStore.h>
24 #include <3dsparse/ModelStore.h>
25 #include <client/ScorchedClient.h>
26 #include <graph/OptionsDisplay.h>
27 #include <graph/ModelRendererMesh.h>
28 #include <common/DefinesString.h>
29 #include <lang/LangResource.h>
30 #include <GLW/GLWFont.h>
31 #include <GLW/GLWTranslate.h>
33 static const float TankSquareSize = 90.0f;
34 static const float TankHalfSquareSize = TankSquareSize / 2.0f;
35 static const float TankPadding = 20.0f;
36 static const float TankInfo = 320.0f;
38 GLWTankViewer::GLWTankViewer(float x, float y, int numH, int numV) :
39 GLWidget(x, y,
40 TankSquareSize * numH + TankPadding,
41 TankSquareSize * numV + TankPadding),
42 scrollBar_(w_ - 12.0f, y + 2.0f, h_ - 4.0f, 0, 0, numV),
43 infoWindow_(x + TankSquareSize * numH + TankPadding + 10.0f,
44 y + TankSquareSize * numV + TankPadding - TankInfo + 30.0f,
45 TankInfo, TankInfo, true),
46 numH_(numH), numV_(numV),
47 rot_(0.0f), selected_(0),
48 rotXY_(0.0f), rotYZ_(0.0f),
49 rotXYD_(1.0f), rotYZD_(1.0f),
50 totalTime_(0.0f),
51 team_(0),
52 catagoryChoice_(x,
53 y + TankSquareSize * numV + TankPadding + 5.0f,
54 + TankSquareSize * numH + TankPadding)
56 std::set<std::string> &catagories =
57 ScorchedClient::instance()->getTankModels().getModelCatagories();
58 std::set<std::string>::iterator catItor;
59 for (catItor = catagories.begin();
60 catItor != catagories.end();
61 catItor++)
63 catagoryChoice_.addText(LANG_RESOURCE(*catItor, *catItor), (*catItor));
66 catagoryChoice_.setHandler(this);
67 catagoryChoice_.setCurrentPosition(0);
68 if (catagoryChoice_.getCurrentEntry())
70 select(0, 0, *catagoryChoice_.getCurrentEntry());
73 catagoryChoice_.setToolTip(new ToolTip(ToolTip::ToolTipHelp,
74 LANG_RESOURCE("MODEL_CATAGORY", "Model Catagory"),
75 LANG_RESOURCE("MODEL_CATAGORY_TOOLTIP",
76 "Displays the currently selected model catagory.\n"
77 "To make models easier to locate\n"
78 "tank models are grouped by catagory.")));
79 infoWindow_.setToolTip(new ToolTip(ToolTip::ToolTipHelp,
80 LANG_RESOURCE("CURRENT_MODEL", "Current Model"),
81 LANG_RESOURCE("CURRENT_MODEL_TOOLTIP",
82 "Displays the currently selected tank model.\n"
83 "This is the model this player will use in game.\n"
84 "Choose a new model from the selection on the\n"
85 "left.")));
88 GLWTankViewer::~GLWTankViewer()
93 void GLWTankViewer::setTeam(int team)
95 team_ = team;
97 // Save current model
98 int scrollCurrent = scrollBar_.getCurrent();
99 TankModel *model = 0;
100 if (selected_ >= 0 &&
101 selected_ < (int) models_.size())
103 model = models_[selected_].model;
106 // Show new team models
107 select(0, 0, GLWSelectorEntry(catagoryChoice_.getCurrentText()));
109 // Select old model
110 scrollBar_.setCurrent(scrollCurrent);
111 for (int i=0; i<(int)models_.size(); i++)
113 if (models_[i].model == model) selected_ = i;
117 void GLWTankViewer::select(unsigned int id,
118 const int pos,
119 GLWSelectorEntry value)
121 std::vector<ModelEntry> newmodels;
123 std::vector<TankModel *> &models =
124 ScorchedClient::instance()->getTankModels().getModels();
125 std::vector<TankModel *>::iterator modelItor;
126 for (modelItor = models.begin();
127 modelItor != models.end();
128 modelItor++)
130 TankModel *tankModel = (*modelItor);
131 if (tankModel->isOfCatagory(value.getDataText()))
133 // Check if this tank is allowed for this team
134 if (!tankModel->isOfTeam(team_) ||
135 !tankModel->isOfAi(false))
137 continue;
140 ModelEntry entry;
141 entry.model = tankModel;
142 entry.mesh = 0;
143 newmodels.push_back(entry);
147 setTankModels(newmodels);
150 void GLWTankViewer::setTankModels(std::vector<ModelEntry> &models)
152 models_.clear();
153 models_ = models;
154 scrollBar_.setMax((int) (models_.size() / numH_) + 1);
155 scrollBar_.setCurrent(0);
156 selected_ = 0;
158 // Sort the models
159 bool sorted = false;
160 while (!sorted)
162 sorted = true;
163 for (int i=0; i<(int) models_.size()-1; i++)
165 ModelEntry tmp = models_[i];
166 ModelEntry test = models_[i+1];
167 if (test.model->lessThan(tmp.model))
169 models_[i] = test;
170 models_[i+1] = tmp;
171 sorted = false;
176 // Move random model to the top
177 std::vector<ModelEntry>::iterator itor;
178 for (itor = models_.begin();
179 itor != models_.end();
180 itor++)
182 ModelEntry entry = (*itor);
183 if (0==strcmp(entry.model->getName(),"Random"))
185 models_.erase(itor);
186 std::vector<ModelEntry> tmpVector;
187 tmpVector.push_back(entry);
188 tmpVector.insert(tmpVector.end(), models_.begin(), models_.end());
189 models_ = tmpVector;
190 break;
195 const char *GLWTankViewer::getModelName()
197 const char *name = "None";
198 if (selected_ >= 0 &&
199 selected_ < (int) models_.size())
201 name = models_[selected_].model->getName();
203 return name;
206 void GLWTankViewer::simulate(float frameTime)
208 totalTime_ += frameTime;
209 rot_ += frameTime * 45.0f;
210 rotXY_ += frameTime * rotXYD_ * 5.0f;
211 rotYZ_ += frameTime * rotYZD_ * 5.0f;
212 if (rotXY_ < -45.0f)
214 rotXY_ = -45.0f;
215 rotXYD_ = 1.0f;
217 else if (rotXY_ > 45.0f)
219 rotXY_ = 45.0f;
220 rotXYD_ = -1.0f;
222 if (rotYZ_ < 0.0f)
224 rotYZ_ = 0.0f;
225 rotYZD_ = 1.0f;
227 else if (rotYZ_ > 45.0f)
229 rotYZ_ = 45.0f;
230 rotYZD_ = -1.0f;
233 scrollBar_.simulate(frameTime);
236 void GLWTankViewer::draw()
238 Vector4 sunPosition(-100.0f, 100.0f, 400.0f, 1.0f);
239 Vector4 sunDiffuse(0.9f, 0.9f, 0.9f, 1.0f);
240 Vector4 sunAmbient(0.4f, 0.4f, 0.4f, 1.0f);
241 glLightfv(GL_LIGHT1, GL_AMBIENT, sunAmbient);
242 glLightfv(GL_LIGHT1, GL_DIFFUSE, sunDiffuse);
244 glBegin(GL_LINE_LOOP);
245 drawShadedRoundBox(x_, y_, w_, h_, 6.0f, false);
246 glEnd();
248 infoWindow_.draw();
249 scrollBar_.draw();
251 GLState depthState(GLState::DEPTH_ON);
252 const float heightdiv = (h_ / float(numV_));
253 const float widthdiv = ((w_ - TankPadding - 10) / float(numH_));
255 int pos = 0;
256 for (int posV=0; posV<numV_; posV++)
258 for (int posH=0; posH<numH_; posH++, pos++)
260 int vectorPos = (scrollBar_.getCurrent() * numH_) + pos;
261 if (vectorPos < (int) models_.size() &&
262 vectorPos >= 0)
264 float posX = x_ + widthdiv * posH + TankHalfSquareSize + 2.0f;
265 float posY = y_ + heightdiv * posV + TankHalfSquareSize + 2.0f;
267 bool currselected = (vectorPos == selected_);
268 if (currselected)
270 glColor3f(0.4f, 0.4f, 0.6f);
271 glBegin(GL_LINE_LOOP);
272 float SelectSize = TankHalfSquareSize - 2.0f;
273 glVertex2f(posX - SelectSize, posY - SelectSize);
274 glVertex2f(posX + SelectSize, posY - SelectSize);
275 glVertex2f(posX + SelectSize, posY + SelectSize);
276 glVertex2f(posX - SelectSize, posY + SelectSize);
277 glEnd();
280 if (GLWToolTip::instance()->addToolTip(&toolTip_,
281 GLWTranslate::getPosX() + posX - TankHalfSquareSize,
282 GLWTranslate::getPosY() + posY - TankHalfSquareSize,
283 TankSquareSize,
284 TankSquareSize))
286 TankType *type = ScorchedClient::instance()->getTankModels().
287 getTypeByName(models_[vectorPos].model->getTypeName());
288 toolTip_.setText(
289 ToolTip::ToolTipInfo,
290 LANG_STRING(models_[vectorPos].model->getName()),
291 LANG_STRING(type->getDescription()));
294 float scale = 22.0f / 60.0f * TankSquareSize;
295 glPushMatrix();
296 glTranslatef(posX, posY - 5.0f, 0.0f);
297 glLightfv(GL_LIGHT1, GL_POSITION, sunPosition);
299 glRotatef(-45.0f, 1.0f, 0.0f, 0.0f);
300 if (currselected) glRotatef(rot_, 0.0f, 0.0f, 1.0f);
301 glScalef(scale, scale, scale);
303 drawItem(vectorPos, currselected);
304 glPopMatrix();
309 if (selected_ >= 0 &&
310 selected_ < (int) models_.size())
312 const float infoX = infoWindow_.getX() + (infoWindow_.getW() / 2.0f);
313 const float infoY = infoWindow_.getY() + (infoWindow_.getH() / 2.0f) - 35.0f;
314 glPushMatrix();
315 glTranslatef(infoX, infoY, 0.0f);
316 glLightfv(GL_LIGHT1, GL_POSITION, sunPosition);
318 drawCaption(selected_);
319 glRotatef(-45.0f, 1.0f, 0.0f, 0.0f);
320 glRotatef(rot_, 0.0f, 0.0f, 1.0f);
321 glScalef(100.0f, 100.0f, 100.0f);
323 drawItem(selected_, true);
324 glPopMatrix();
327 GLState depthStateOff(GLState::DEPTH_OFF);
328 catagoryChoice_.draw();
331 void GLWTankViewer::mouseDown(int button, float x, float y, bool &skipRest)
333 scrollBar_.mouseDown(button, x, y, skipRest);
334 if (!skipRest)
336 catagoryChoice_.mouseDown(button, x, y, skipRest);
337 if (!skipRest)
339 if (inBox(x, y, x_, y_, w_, h_))
341 int posY = int((y - y_) / (h_ / numV_));
342 int posX = int((x - x_) / (w_ / numH_));
344 int vectorPos = posX + posY * numH_ + scrollBar_.getCurrent() * numH_;
345 if (vectorPos < (int) models_.size() &&
346 vectorPos >= 0)
348 selected_ = vectorPos;
355 void GLWTankViewer::mouseDrag(int button, float mx, float my, float x, float y, bool &skipRest)
357 scrollBar_.mouseDrag(button, mx, my, x, y, skipRest);
360 void GLWTankViewer::mouseUp(int button, float x, float y, bool &skipRest)
362 scrollBar_.mouseUp(button, x, y, skipRest);
365 void GLWTankViewer::mouseWheel(float x, float y, float z, bool &skipRest)
367 if (inBox(x, y, x_, y_, w_, h_))
369 skipRest = true;
371 if (z < 0.0f) scrollBar_.setCurrent(scrollBar_.getCurrent() + 1);
372 else scrollBar_.setCurrent(scrollBar_.getCurrent() - 1);
376 void GLWTankViewer::drawCaption(int pos)
378 GLState state(GLState::DEPTH_OFF);
380 LANG_RESOURCE_VAR_1(TANK_NAME, "TANK_NAME", "Tank Name : {0}", models_[pos].model->getName());
382 Vector color(0.3f, 0.3f, 0.3f);
383 GLWFont::instance()->getGameFont()->
384 drawWidth(TankInfo - 20.0f,
385 color, 10.0f, -150.0f, 175.0f, 0.0f,
386 TANK_NAME);
388 void GLWTankViewer::drawItem(int pos, bool selected)
390 TankMesh *mesh = models_[pos].mesh;
391 if (!mesh)
393 mesh = TankMeshStore::instance()->getMesh(
394 models_[pos].model->getTankModelID());
395 models_[pos].mesh = mesh;
398 // Tank
399 Vector4 tankRot(1.0f, 0.0f, 0.0f, 0.0f);
400 float matrix[16];
401 tankRot.getOpenGLRotationMatrix(matrix);
403 Vector tankPos;
404 if (selected)
406 mesh->draw(totalTime_ * 20.0f, false,
407 matrix, tankPos, 0.0f, rotXY_, rotYZ_);
409 else
411 mesh->draw(totalTime_ * 20.0f, false,
412 matrix, tankPos, 0.0f, 45.0f, 45.0f);
415 // Ground
416 GLState state(GLState::TEXTURE_OFF);
417 glColor3f(181.0f / 255.0f, 204.0f / 255.0f, 237.0f / 255.0f);
418 glBegin(GL_QUADS);
419 glVertex2f(1.0f, 1.0f);
420 glVertex2f(-1.0f, 1.0f);
421 glVertex2f(-1.0f, -1.0f);
422 glVertex2f(1.0f, -1.0f);
423 glEnd();
425 //Shadow
427 glDepthMask(GL_FALSE);
428 glPushMatrix();
429 glScalef(1.0f, 1.0f, 0.0f);
430 models[pos]->draw(false, tankPos, 0.0f, rotXY_, rotYZ_);
431 glPopMatrix();
432 glDepthMask(GL_TRUE);
436 void GLWTankViewer::selectModelByName(const char *name)
438 DIALOG_ASSERT(models_.size());
440 // Ensure that all models have been loaded
441 //select(0, 0, "All");
443 // Select the appropriate model
444 int currentSel = 0;
445 std::vector<ModelEntry>::iterator itor;
446 for (itor = models_.begin();
447 itor != models_.end();
448 itor++, currentSel ++)
450 TankModel *current = (*itor).model;
451 if (0 == strcmp(current->getName(), name))
453 selected_ = currentSel;
454 return;