guiSpeedometer.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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 "gui/controls/guiBitmapCtrl.h"
  23. #include "console/consoleTypes.h"
  24. #include "T3D/gameBase/gameConnection.h"
  25. #include "T3D/vehicles/vehicle.h"
  26. #include "gfx/primBuilder.h"
  27. //-----------------------------------------------------------------------------
  28. /// A Speedometer control.
  29. /// This gui displays the speed of the current Vehicle based
  30. /// control object. This control only works if a server
  31. /// connection exists and its control object is a vehicle. If
  32. /// either of these requirements is false, the control is not rendered.
  33. class GuiSpeedometerHud : public GuiBitmapCtrl
  34. {
  35. typedef GuiBitmapCtrl Parent;
  36. F32 mSpeed; ///< Current speed
  37. F32 mMaxSpeed; ///< Max speed at max need pos
  38. F32 mMaxAngle; ///< Max pos of needle
  39. F32 mMinAngle; ///< Min pos of needle
  40. Point2F mCenter; ///< Center of needle rotation
  41. ColorF mColor; ///< Needle Color
  42. F32 mNeedleLength;
  43. F32 mNeedleWidth;
  44. F32 mTailLength;
  45. GFXStateBlockRef mBlendSB;
  46. public:
  47. GuiSpeedometerHud();
  48. void onRender( Point2I, const RectI &);
  49. static void initPersistFields();
  50. DECLARE_CONOBJECT( GuiSpeedometerHud );
  51. DECLARE_CATEGORY( "Gui Game" );
  52. DECLARE_DESCRIPTION( "Displays the speed of the current Vehicle-based control object." );
  53. };
  54. //-----------------------------------------------------------------------------
  55. IMPLEMENT_CONOBJECT( GuiSpeedometerHud );
  56. ConsoleDocClass( GuiSpeedometerHud,
  57. "@brief Displays the speed of the current Vehicle based control object.\n\n"
  58. "This control only works if a server connection exists, and its control "
  59. "object is a Vehicle derived class. If either of these requirements is false, "
  60. "the control is not rendered.<br>"
  61. "The control renders the speedometer needle as a colored quad, rotated to "
  62. "indicate the Vehicle speed as determined by the <i>minAngle</i>, "
  63. "<i>maxAngle</i>, and <i>maxSpeed</i> properties. This control is normally "
  64. "placed on top of a GuiBitmapCtrl representing the speedometer dial.\n\n"
  65. "@tsexample\n"
  66. "new GuiSpeedometerHud()\n"
  67. "{\n"
  68. " maxSpeed = \"100\";\n"
  69. " minAngle = \"215\";\n"
  70. " maxAngle = \"0\";\n"
  71. " color = \"1 0.3 0.3 1\";\n"
  72. " center = \"130 123\";\n"
  73. " length = \"100\";\n"
  74. " width = \"2\";\n"
  75. " tail = \"0\";\n"
  76. " //Properties not specific to this control have been omitted from this example.\n"
  77. "};\n"
  78. "@endtsexample\n\n"
  79. "@ingroup GuiContainers"
  80. );
  81. GuiSpeedometerHud::GuiSpeedometerHud()
  82. {
  83. mSpeed = 0;
  84. mMaxSpeed = 100;
  85. mMaxAngle = 0;
  86. mMinAngle = 200;
  87. mCenter.set(0,0);
  88. mNeedleWidth = 3;
  89. mNeedleLength = 10;
  90. mTailLength = 5;
  91. mColor.set(1,0,0,1);
  92. }
  93. void GuiSpeedometerHud::initPersistFields()
  94. {
  95. addGroup("Needle");
  96. addField("maxSpeed", TypeF32, Offset( mMaxSpeed, GuiSpeedometerHud ),
  97. "Maximum Vehicle speed (in Torque units per second) to represent on the "
  98. "speedo (Vehicle speeds greater than this are clamped to maxSpeed)." );
  99. addField("minAngle", TypeF32, Offset( mMinAngle, GuiSpeedometerHud ),
  100. "Angle (in radians) of the needle when the Vehicle speed is 0. An angle "
  101. "of 0 points right, 90 points up etc)." );
  102. addField("maxAngle", TypeF32, Offset( mMaxAngle, GuiSpeedometerHud ),
  103. "Angle (in radians) of the needle when the Vehicle speed is >= maxSpeed. "
  104. "An angle of 0 points right, 90 points up etc)." );
  105. addField("color", TypeColorF, Offset( mColor, GuiSpeedometerHud ),
  106. "Color of the needle" );
  107. addField("center", TypePoint2F, Offset( mCenter, GuiSpeedometerHud ),
  108. "Center of the needle, offset from the GuiSpeedometerHud control top "
  109. "left corner" );
  110. addField("length", TypeF32, Offset( mNeedleLength, GuiSpeedometerHud ),
  111. "Length of the needle from center to end" );
  112. addField("width", TypeF32, Offset( mNeedleWidth, GuiSpeedometerHud ),
  113. "Width of the needle" );
  114. addField("tail", TypeF32, Offset( mTailLength, GuiSpeedometerHud ),
  115. "Length of the needle from center to tail" );
  116. endGroup("Needle");
  117. Parent::initPersistFields();
  118. }
  119. //-----------------------------------------------------------------------------
  120. /**
  121. Gui onRender method.
  122. Renders a health bar with filled background and border.
  123. */
  124. void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect)
  125. {
  126. // Must have a connection and player control object
  127. GameConnection* conn = GameConnection::getConnectionToServer();
  128. if (!conn)
  129. return;
  130. Vehicle* control = dynamic_cast<Vehicle*>(conn->getControlObject());
  131. if (!control)
  132. return;
  133. Parent::onRender(offset,updateRect);
  134. // Use the vehicle's velocity as its speed...
  135. mSpeed = control->getVelocity().len();
  136. if (mSpeed > mMaxSpeed)
  137. mSpeed = mMaxSpeed;
  138. // Render the needle
  139. GFX->pushWorldMatrix();
  140. Point2F center = mCenter;
  141. if (mIsZero(center.x) && mIsZero(center.y))
  142. {
  143. center.x = getExtent().x / 2.0f;
  144. center.y = getExtent().y / 2.0f;
  145. }
  146. MatrixF newMat(1);
  147. newMat.setPosition(Point3F(getLeft() + center.x, getTop() + center.y, 0.0f));
  148. F32 rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed);
  149. AngAxisF newRot(Point3F(0.0f,0.0f,-1.0f), rotation);
  150. newRot.setMatrix(&newMat);
  151. if (mBlendSB.isNull())
  152. {
  153. GFXStateBlockDesc desc;
  154. desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
  155. desc.samplersDefined = true;
  156. desc.samplers[0].textureColorOp = GFXTOPDisable;
  157. mBlendSB = GFX->createStateBlock(desc);
  158. }
  159. GFX->setStateBlock(mBlendSB);
  160. GFX->setTexture(0, NULL);
  161. PrimBuild::begin(GFXLineStrip, 5);
  162. PrimBuild::color4f(mColor.red, mColor.green, mColor.blue, mColor.alpha);
  163. PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth);
  164. PrimBuild::vertex2f(+mNeedleLength,+mNeedleWidth);
  165. PrimBuild::vertex2f(-mTailLength ,+mNeedleWidth);
  166. PrimBuild::vertex2f(-mTailLength ,-mNeedleWidth);
  167. //// Get back to the start!
  168. PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth);
  169. PrimBuild::end();
  170. }