guiShapeNameHud.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "gui/core/guiControl.h"
  24. #include "gui/3d/guiTSControl.h"
  25. #include "console/consoleTypes.h"
  26. #include "scene/sceneManager.h"
  27. #include "T3D/gameBase/gameConnection.h"
  28. #include "T3D/shapeBase.h"
  29. #include "gfx/gfxDrawUtil.h"
  30. #include "console/engineAPI.h"
  31. #include "T3D/missionMarker.h" //> ZOD: Team coloring
  32. //----------------------------------------------------------------------------
  33. /// Displays name & damage above shape objects.
  34. ///
  35. /// This control displays the name and damage value of all named
  36. /// ShapeBase objects on the client. The name and damage of objects
  37. /// within the control's display area are overlayed above the object.
  38. ///
  39. /// This GUI control must be a child of a TSControl, and a server connection
  40. /// and control object must be present.
  41. ///
  42. /// This is a stand-alone control and relies only on the standard base GuiControl.
  43. class GuiShapeNameHud : public GuiControl {
  44. typedef GuiControl Parent;
  45. // field data
  46. ColorF mFillColor;
  47. ColorF mFrameColor;
  48. ColorF mTextColor;
  49. ColorF mLabelFillColor;
  50. ColorF mLabelFrameColor;
  51. // ZOD: Team coloring
  52. ColorF mEnemyTextColor;
  53. ColorF mNeutralTextColor;
  54. //> ZOD: End addition
  55. F32 mVerticalOffset;
  56. F32 mDistanceFade;
  57. bool mShowFrame;
  58. bool mShowFill;
  59. bool mShowLabelFrame;
  60. bool mShowLabelFill;
  61. Point2I mLabelPadding;
  62. protected:
  63. // ZOD: Team coloring
  64. //void drawName( Point2I offset, const char *buf, F32 opacity);
  65. void drawName( Point2I offset, const char *buf, F32 opacity, ColorF color);
  66. //> ZOD: End edit
  67. public:
  68. GuiShapeNameHud();
  69. // GuiControl
  70. virtual void onRender(Point2I offset, const RectI &updateRect);
  71. static void initPersistFields();
  72. DECLARE_CONOBJECT( GuiShapeNameHud );
  73. DECLARE_CATEGORY( "Gui Game" );
  74. DECLARE_DESCRIPTION( "Displays name and damage of ShapeBase objects in its bounds.\n"
  75. "Must be a child of a GuiTSCtrl and a server connection must be present." );
  76. };
  77. //-----------------------------------------------------------------------------
  78. IMPLEMENT_CONOBJECT(GuiShapeNameHud);
  79. ConsoleDocClass( GuiShapeNameHud,
  80. "@brief Displays name and damage of ShapeBase objects in its bounds. Must be a child of a GuiTSCtrl and a server connection must be present.\n\n"
  81. "This control displays the name and damage value of all named ShapeBase objects on the client. "
  82. "The name and damage of objects within the control's display area are overlayed above the object.\n\n"
  83. "This GUI control must be a child of a TSControl, and a server connection and control object must be present. "
  84. "This is a stand-alone control and relies only on the standard base GuiControl.\n\n"
  85. "@tsexample\n"
  86. "\n new GuiShapeNameHud()"
  87. "{\n"
  88. " fillColor = \"0.0 1.0 0.0 1.0\"; // Fills with a solid green color\n"
  89. " frameColor = \"1.0 1.0 1.0 1.0\"; // Solid white frame color\n"
  90. " textColor = \"1.0 1.0 1.0 1.0\"; // Solid white text Color\n"
  91. " showFill = \"true\";\n"
  92. " showFrame = \"true\";\n"
  93. " labelFillColor = \"0.0 1.0 0.0 1.0\"; // Fills with a solid green color\n"
  94. " labelFrameColor = \"1.0 1.0 1.0 1.0\"; // Solid white frame color\n"
  95. " showLabelFill = \"true\";\n"
  96. " showLabelFrame = \"true\";\n"
  97. " verticalOffset = \"0.15\";\n"
  98. " distanceFade = \"15.0\";\n"
  99. "};\n"
  100. "@endtsexample\n\n"
  101. "@ingroup GuiGame\n"
  102. );
  103. /// Default distance for object's information to be displayed.
  104. static const F32 cDefaultVisibleDistance = 500.0f;
  105. GuiShapeNameHud::GuiShapeNameHud()
  106. {
  107. mFillColor.set( 0.25f, 0.25f, 0.25f, 0.25f );
  108. mFrameColor.set( 0, 1, 0, 1 );
  109. mLabelFillColor.set( 0.25f, 0.25f, 0.25f, 0.25f );
  110. mLabelFrameColor.set( 0, 1, 0, 1 );
  111. mTextColor.set( 0, 1, 0, 1 );
  112. //> ZOD: Team coloring
  113. mEnemyTextColor.set( 1, 0, 0, 1 );
  114. mNeutralTextColor.set( 1, 1, 1, 1 );
  115. //> ZOD: End addition
  116. mShowFrame = mShowFill = true;
  117. mShowLabelFrame = mShowLabelFill = false;
  118. mVerticalOffset = 0.5f;
  119. mDistanceFade = 0.1f;
  120. mLabelPadding.set(0, 0);
  121. }
  122. void GuiShapeNameHud::initPersistFields()
  123. {
  124. addGroup("Colors");
  125. addField( "fillColor", TypeColorF, Offset( mFillColor, GuiShapeNameHud ), "Standard color for the background of the control." );
  126. addField( "frameColor", TypeColorF, Offset( mFrameColor, GuiShapeNameHud ), "Color for the control's frame." );
  127. addField( "textColor", TypeColorF, Offset( mTextColor, GuiShapeNameHud ), "Color for the text on this control." );
  128. addField( "labelFillColor", TypeColorF, Offset( mLabelFillColor, GuiShapeNameHud ), "Color for the background of each shape name label." );
  129. addField( "labelFrameColor", TypeColorF, Offset( mLabelFrameColor, GuiShapeNameHud ), "Color for the frames around each shape name label." );
  130. // ZOD: Team coloring
  131. addField( "enemyTextColor", TypeColorF, Offset( mEnemyTextColor, GuiShapeNameHud ), "Color for enemy shapes." );
  132. //> ZOD: End addition
  133. addField( "neutralTextColor", TypeColorF, Offset( mNeutralTextColor, GuiShapeNameHud ), "Color for neutral shapes." );
  134. endGroup("Colors");
  135. addGroup("Misc");
  136. addField( "showFill", TypeBool, Offset( mShowFill, GuiShapeNameHud ), "If true, we draw the background color of the control." );
  137. addField( "showFrame", TypeBool, Offset( mShowFrame, GuiShapeNameHud ), "If true, we draw the frame of the control." );
  138. addField( "showLabelFill", TypeBool, Offset( mShowLabelFill, GuiShapeNameHud ), "If true, we draw a background for each shape name label." );
  139. addField( "showLabelFrame", TypeBool, Offset( mShowLabelFrame, GuiShapeNameHud ), "If true, we draw a frame around each shape name label." );
  140. addField( "labelPadding", TypePoint2I, Offset( mLabelPadding, GuiShapeNameHud ), "The padding (in pixels) between the label text and the frame." );
  141. addField( "verticalOffset", TypeF32, Offset( mVerticalOffset, GuiShapeNameHud ), "Amount to vertically offset the control in relation to the ShapeBase object in focus." );
  142. addField( "distanceFade", TypeF32, Offset( mDistanceFade, GuiShapeNameHud ), "Visibility distance (how far the player must be from the ShapeBase object in focus) for this control to render." );
  143. endGroup("Misc");
  144. Parent::initPersistFields();
  145. }
  146. //----------------------------------------------------------------------------
  147. /// Core rendering method for this control.
  148. ///
  149. /// This method scans through all the current client ShapeBase objects.
  150. /// If one is named, it displays the name and damage information for it.
  151. ///
  152. /// Information is offset from the center of the object's bounding box,
  153. /// unless the object is a PlayerObjectType, in which case the eye point
  154. /// is used.
  155. ///
  156. /// @param updateRect Extents of control.
  157. void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
  158. {
  159. // Background fill first
  160. if (mShowFill)
  161. GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
  162. // Must be in a TS Control
  163. GuiTSCtrl *parent = dynamic_cast<GuiTSCtrl*>(getParent());
  164. if (!parent) return;
  165. // Must have a connection and control object
  166. GameConnection* conn = GameConnection::getConnectionToServer();
  167. if (!conn) return;
  168. //> ZOD: Team coloring
  169. //GameBase * control = dynamic_cast<GameBase*>(conn->getControlObject());
  170. ShapeBase * control = dynamic_cast<ShapeBase*>(conn->getControlObject());
  171. //< ZOD: End edit
  172. if (!control) return;
  173. // Get control camera info
  174. MatrixF cam;
  175. Point3F camPos;
  176. VectorF camDir;
  177. conn->getControlCameraTransform(0,&cam);
  178. cam.getColumn(3, &camPos);
  179. cam.getColumn(1, &camDir);
  180. F32 camFovCos;
  181. conn->getControlCameraFov(&camFovCos);
  182. camFovCos = mCos(mDegToRad(camFovCos) / 2);
  183. // Visible distance info & name fading
  184. F32 visDistance = gClientSceneGraph->getVisibleDistance();
  185. F32 visDistanceSqr = visDistance * visDistance;
  186. F32 fadeDistance = visDistance * mDistanceFade;
  187. // Collision info. We're going to be running LOS tests and we
  188. // don't want to collide with the control object.
  189. static U32 losMask = TerrainObjectType | ShapeBaseObjectType | StaticObjectType;
  190. control->disableCollision();
  191. //> ZOD: Team coloring
  192. ColorF renderColor;
  193. const char *fof = NULL;
  194. char buf[64];
  195. //< ZOD: End addition
  196. // All ghosted objects are added to the server connection group,
  197. // so we can find all the shape base objects by iterating through
  198. // our current connection.
  199. for (SimSetIterator itr(conn); *itr; ++itr) {
  200. ShapeBase* shape = dynamic_cast< ShapeBase* >(*itr);
  201. if ( shape ) {
  202. if (shape != control && shape->getShapeName())
  203. {
  204. //> ZOD: If cloaked, early out
  205. if ( shape->getCloakedState() )
  206. continue;
  207. // Target pos to test, if it's a player run the LOS to his eye
  208. // point, otherwise we'll grab the generic box center.
  209. Point3F shapePos;
  210. if (shape->getTypeMask() & PlayerObjectType)
  211. {
  212. MatrixF eye;
  213. // Use the render eye transform, otherwise we'll see jittering
  214. shape->getRenderEyeTransform(&eye);
  215. eye.getColumn(3, &shapePos);
  216. }
  217. else
  218. {
  219. // Use the render transform instead of the box center
  220. // otherwise it'll jitter.
  221. MatrixF srtMat = shape->getRenderTransform();
  222. srtMat.getColumn(3, &shapePos);
  223. }
  224. VectorF shapeDir = shapePos - camPos;
  225. // Test to see if it's in range
  226. F32 shapeDist = shapeDir.lenSquared();
  227. if (shapeDist == 0 || shapeDist > visDistanceSqr)
  228. continue;
  229. shapeDist = mSqrt(shapeDist);
  230. // Test to see if it's within our viewcone, this test doesn't
  231. // actually match the viewport very well, should consider
  232. // projection and box test.
  233. shapeDir.normalize();
  234. F32 dot = mDot(shapeDir, camDir);
  235. if (dot < camFovCos)
  236. continue;
  237. // Test to see if it's behind something, and we want to
  238. // ignore anything it's mounted on when we run the LOS.
  239. RayInfo info;
  240. shape->disableCollision();
  241. SceneObject *mount = shape->getObjectMount();
  242. if (mount)
  243. mount->disableCollision();
  244. bool los = !gClientContainer.castRay(camPos, shapePos,losMask, &info);
  245. shape->enableCollision();
  246. if (mount)
  247. mount->enableCollision();
  248. if (!los)
  249. continue;
  250. // Project the shape pos into screen space and calculate
  251. // the distance opacity used to fade the labels into the
  252. // distance.
  253. Point3F projPnt;
  254. shapePos.z += mVerticalOffset;
  255. if (!parent->project(shapePos, &projPnt))
  256. continue;
  257. F32 opacity = (shapeDist < fadeDistance)? 1.0:
  258. 1.0 - (shapeDist - fadeDistance) / (visDistance - fadeDistance);
  259. //> ZOD: Team coloring
  260. S32 myId = control->getTeamId();
  261. S32 targetId = shape->getTeamId();
  262. if(targetId == 0)
  263. {
  264. fof = "N";
  265. renderColor = mNeutralTextColor;
  266. }
  267. else if(myId != targetId)
  268. {
  269. fof = "E";
  270. renderColor = mEnemyTextColor;
  271. }
  272. else
  273. {
  274. fof = "F";
  275. renderColor = mTextColor;
  276. }
  277. // Append the distance from the shape to the name
  278. dSprintf(buf,sizeof(buf), "%s : %gm", shape->getShapeName(), mFloor(shapeDist));
  279. drawName(Point2I((S32)projPnt.x, (S32)projPnt.y), buf, opacity, renderColor);
  280. //< ZOD: End addition
  281. // Render the shape's name
  282. //drawName(Point2I((S32)projPnt.x, (S32)projPnt.y),shape->getShapeName(),opacity);
  283. }
  284. }
  285. }
  286. // Restore control object collision
  287. control->enableCollision();
  288. // ZOD: Waypoints
  289. SimSet *WayPointSet = Sim::getWayPointSet();
  290. SimSet::iterator i;
  291. for(i = WayPointSet->begin(); i != WayPointSet->end(); i++)
  292. {
  293. WayPoint *way = (WayPoint *) (*i);
  294. S32 myId = control->getTeamId();
  295. S32 wayId = way->getTeamId();
  296. Point3F wayPos;
  297. MatrixF srtMat = way->getTransform();
  298. srtMat.getColumn(3, &wayPos);
  299. VectorF wayDir = wayPos - control->getPosition();//camPos;
  300. F32 wayDist = wayDir.lenSquared();
  301. if (wayDist == 0)
  302. continue;
  303. wayDist = mSqrt(wayDist);
  304. Point3F projPnt;
  305. wayPos.z += mVerticalOffset;
  306. if (!parent->project(wayPos, &projPnt))
  307. continue;
  308. fof = way->mName;
  309. if(wayId == 0)
  310. renderColor = mNeutralTextColor;
  311. else if(myId != wayId)
  312. renderColor = mEnemyTextColor;
  313. else
  314. renderColor = mTextColor;
  315. dSprintf(buf,sizeof(buf), "%s : %gm", fof, mFloor(wayDist));
  316. drawName(Point2I((S32)projPnt.x, (S32)projPnt.y), buf, renderColor.alpha, renderColor);
  317. }
  318. // ZOD: End addition
  319. // Border last
  320. if (mShowFrame)
  321. GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);
  322. }
  323. //----------------------------------------------------------------------------
  324. /// Render object names.
  325. ///
  326. /// Helper function for GuiShapeNameHud::onRender
  327. ///
  328. /// @param offset Screen coordinates to render name label. (Text is centered
  329. /// horizontally about this location, with bottom of text at
  330. /// specified y position.)
  331. /// @param name String name to display.
  332. /// @param opacity Opacity of name (a fraction).
  333. void GuiShapeNameHud::drawName(Point2I offset, const char *name, F32 opacity, ColorF mTextColor)
  334. {
  335. F32 width = mProfile->mFont->getStrWidth((const UTF8 *)name) + mLabelPadding.x * 2;
  336. F32 height = mProfile->mFont->getHeight() + mLabelPadding.y * 2;
  337. Point2I extent = Point2I(width, height);
  338. // Center the name
  339. offset.x -= width / 2;
  340. offset.y -= height / 2;
  341. GFXDrawUtil* drawUtil = GFX->getDrawUtil();
  342. // Background fill first
  343. if (mShowLabelFill)
  344. drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor);
  345. // Deal with opacity and draw.
  346. mTextColor.alpha = opacity;
  347. drawUtil->setBitmapModulation(mTextColor);
  348. drawUtil->drawText(mProfile->mFont, offset + mLabelPadding, name);
  349. drawUtil->clearBitmapModulation();
  350. // Border last
  351. if (mShowLabelFrame)
  352. drawUtil->drawRect(RectI(offset, extent), mLabelFrameColor);
  353. }