1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
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
) :
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
),
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();
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"
88 GLWTankViewer::~GLWTankViewer()
93 void GLWTankViewer::setTeam(int team
)
98 int scrollCurrent
= scrollBar_
.getCurrent();
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()));
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
,
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();
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))
141 entry
.model
= tankModel
;
143 newmodels
.push_back(entry
);
147 setTankModels(newmodels
);
150 void GLWTankViewer::setTankModels(std::vector
<ModelEntry
> &models
)
154 scrollBar_
.setMax((int) (models_
.size() / numH_
) + 1);
155 scrollBar_
.setCurrent(0);
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
))
176 // Move random model to the top
177 std::vector
<ModelEntry
>::iterator itor
;
178 for (itor
= models_
.begin();
179 itor
!= models_
.end();
182 ModelEntry entry
= (*itor
);
183 if (0==strcmp(entry
.model
->getName(),"Random"))
186 std::vector
<ModelEntry
> tmpVector
;
187 tmpVector
.push_back(entry
);
188 tmpVector
.insert(tmpVector
.end(), models_
.begin(), models_
.end());
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();
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
;
217 else if (rotXY_
> 45.0f
)
227 else if (rotYZ_
> 45.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);
251 GLState
depthState(GLState::DEPTH_ON
);
252 const float heightdiv
= (h_
/ float(numV_
));
253 const float widthdiv
= ((w_
- TankPadding
- 10) / float(numH_
));
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() &&
264 float posX
= x_
+ widthdiv
* posH
+ TankHalfSquareSize
+ 2.0f
;
265 float posY
= y_
+ heightdiv
* posV
+ TankHalfSquareSize
+ 2.0f
;
267 bool currselected
= (vectorPos
== selected_
);
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
);
280 if (GLWToolTip::instance()->addToolTip(&toolTip_
,
281 GLWTranslate::getPosX() + posX
- TankHalfSquareSize
,
282 GLWTranslate::getPosY() + posY
- TankHalfSquareSize
,
286 TankType
*type
= ScorchedClient::instance()->getTankModels().
287 getTypeByName(models_
[vectorPos
].model
->getTypeName());
289 ToolTip::ToolTipInfo
,
290 LANG_STRING(models_
[vectorPos
].model
->getName()),
291 LANG_STRING(type
->getDescription()));
294 float scale
= 22.0f
/ 60.0f
* TankSquareSize
;
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
);
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
;
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);
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
);
336 catagoryChoice_
.mouseDown(button
, x
, y
, 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() &&
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_
))
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
,
388 void GLWTankViewer::drawItem(int pos
, bool selected
)
390 TankMesh
*mesh
= models_
[pos
].mesh
;
393 mesh
= TankMeshStore::instance()->getMesh(
394 models_
[pos
].model
->getTankModelID());
395 models_
[pos
].mesh
= mesh
;
399 Vector4
tankRot(1.0f
, 0.0f
, 0.0f
, 0.0f
);
401 tankRot
.getOpenGLRotationMatrix(matrix
);
406 mesh
->draw(totalTime_
* 20.0f
, false,
407 matrix
, tankPos
, 0.0f
, rotXY_
, rotYZ_
);
411 mesh
->draw(totalTime_
* 20.0f
, false,
412 matrix
, tankPos
, 0.0f
, 45.0f
, 45.0f
);
416 GLState
state(GLState::TEXTURE_OFF
);
417 glColor3f(181.0f
/ 255.0f
, 204.0f
/ 255.0f
, 237.0f
/ 255.0f
);
419 glVertex2f(1.0f
, 1.0f
);
420 glVertex2f(-1.0f
, 1.0f
);
421 glVertex2f(-1.0f
, -1.0f
);
422 glVertex2f(1.0f
, -1.0f
);
427 glDepthMask(GL_FALSE);
429 glScalef(1.0f, 1.0f, 0.0f);
430 models[pos]->draw(false, tankPos, 0.0f, rotXY_, rotYZ_);
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
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
;