guiSpeedometer.cpp
Engine/source/T3D/vehicles/guiSpeedometer.cpp
Classes:
class
A Speedometer control.
Public Functions
ConsoleDocClass(GuiSpeedometerHud , "@brief Displays the speed of the current <a href="/coding/class/classvehicle/">Vehicle</a> based <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "This <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> only works <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> server connection exists, and its <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> " "object is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classvehicle/">Vehicle</a> derived class. If either of these requirements is false, " "the <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> is not rendered.< br >" "The <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> renders the speedometer needle as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> colored quad, rotated <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "indicate the <a href="/coding/class/classvehicle/">Vehicle</a> speed as determined by the< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >minAngle</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > , " "< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >maxAngle</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > , and< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >maxSpeed</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > properties. This <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> is normally " "placed on top of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classguibitmapctrl/">GuiBitmapCtrl</a> representing the speedometer <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dial.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classguispeedometerhud/">GuiSpeedometerHud</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " maxSpeed=\"100\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " minAngle = \"215\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " maxAngle = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " color = \"1 0.3 0.3 1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " center = \"130 123\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " length = \"100\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " width = \"2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " tail = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " //Properties not specific <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> have been omitted from this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example.\n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup GuiContainers" )
Detailed Description
Public Functions
ConsoleDocClass(GuiSpeedometerHud , "@brief Displays the speed of the current <a href="/coding/class/classvehicle/">Vehicle</a> based <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "This <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> only works <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> server connection exists, and its <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> " "object is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classvehicle/">Vehicle</a> derived class. If either of these requirements is false, " "the <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> is not rendered.< br >" "The <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> renders the speedometer needle as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> colored quad, rotated <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "indicate the <a href="/coding/class/classvehicle/">Vehicle</a> speed as determined by the< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >minAngle</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > , " "< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >maxAngle</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > , and< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >maxSpeed</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > properties. This <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> is normally " "placed on top of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classguibitmapctrl/">GuiBitmapCtrl</a> representing the speedometer <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dial.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classguispeedometerhud/">GuiSpeedometerHud</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " maxSpeed=\"100\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " minAngle = \"215\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " maxAngle = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " color = \"1 0.3 0.3 1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " center = \"130 123\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " length = \"100\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " width = \"2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " tail = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " //Properties not specific <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> have been omitted from this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example.\n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup GuiContainers" )
IMPLEMENT_CONOBJECT(GuiSpeedometerHud )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23#include "gui/controls/guiBitmapCtrl.h" 24#include "console/consoleTypes.h" 25#include "T3D/gameBase/gameConnection.h" 26#include "T3D/vehicles/vehicle.h" 27#include "T3D/player.h" 28#include "gfx/primBuilder.h" 29 30//----------------------------------------------------------------------------- 31/// A Speedometer control. 32/// This gui displays the speed of the current Vehicle based 33/// control object. This control only works if a server 34/// connection exists and its control object is a vehicle. If 35/// either of these requirements is false, the control is not rendered. 36class GuiSpeedometerHud : public GuiBitmapCtrl 37{ 38 typedef GuiBitmapCtrl Parent; 39 40 F32 mSpeed; ///< Current speed 41 F32 mMaxSpeed; ///< Max speed at max need pos 42 F32 mMaxAngle; ///< Max pos of needle 43 F32 mMinAngle; ///< Min pos of needle 44 Point2F mCenter; ///< Center of needle rotation 45 LinearColorF mNeedleColor; ///< Needle Color 46 F32 mNeedleLength; 47 F32 mNeedleWidth; 48 F32 mTailLength; 49 50 GFXStateBlockRef mBlendSB; 51 52public: 53 GuiSpeedometerHud(); 54 55 void onRender( Point2I, const RectI &); 56 static void initPersistFields(); 57 DECLARE_CONOBJECT( GuiSpeedometerHud ); 58 DECLARE_CATEGORY( "Gui Game" ); 59 DECLARE_DESCRIPTION( "Displays the speed of the current Vehicle-based control object." ); 60}; 61 62 63//----------------------------------------------------------------------------- 64 65IMPLEMENT_CONOBJECT( GuiSpeedometerHud ); 66 67ConsoleDocClass( GuiSpeedometerHud, 68 "@brief Displays the speed of the current Vehicle based control object.\n\n" 69 70 "This control only works if a server connection exists, and its control " 71 "object is a Vehicle derived class. If either of these requirements is false, " 72 "the control is not rendered.<br>" 73 74 "The control renders the speedometer needle as a colored quad, rotated to " 75 "indicate the Vehicle speed as determined by the <i>minAngle</i>, " 76 "<i>maxAngle</i>, and <i>maxSpeed</i> properties. This control is normally " 77 "placed on top of a GuiBitmapCtrl representing the speedometer dial.\n\n" 78 79 "@tsexample\n" 80 "new GuiSpeedometerHud()\n" 81 "{\n" 82 " maxSpeed = \"100\";\n" 83 " minAngle = \"215\";\n" 84 " maxAngle = \"0\";\n" 85 " color = \"1 0.3 0.3 1\";\n" 86 " center = \"130 123\";\n" 87 " length = \"100\";\n" 88 " width = \"2\";\n" 89 " tail = \"0\";\n" 90 " //Properties not specific to this control have been omitted from this example.\n" 91 "};\n" 92 "@endtsexample\n\n" 93 94 "@ingroup GuiContainers" 95); 96 97GuiSpeedometerHud::GuiSpeedometerHud() 98{ 99 mSpeed = 0; 100 mMaxSpeed = 100; 101 mMaxAngle = 0; 102 mMinAngle = 200; 103 mCenter.set(0,0); 104 mNeedleWidth = 3; 105 mNeedleLength = 10; 106 mTailLength = 5; 107 mNeedleColor.set(1,0,0,1); 108} 109 110void GuiSpeedometerHud::initPersistFields() 111{ 112 addGroup("Needle"); 113 114 addField("maxSpeed", TypeF32, Offset( mMaxSpeed, GuiSpeedometerHud ), 115 "Maximum Vehicle speed (in Torque units per second) to represent on the " 116 "speedo (Vehicle speeds greater than this are clamped to maxSpeed)." ); 117 118 addField("minAngle", TypeF32, Offset( mMinAngle, GuiSpeedometerHud ), 119 "Angle (in radians) of the needle when the Vehicle speed is 0. An angle " 120 "of 0 points right, 90 points up etc)." ); 121 122 addField("maxAngle", TypeF32, Offset( mMaxAngle, GuiSpeedometerHud ), 123 "Angle (in radians) of the needle when the Vehicle speed is >= maxSpeed. " 124 "An angle of 0 points right, 90 points up etc)." ); 125 126 addField("color", TypeColorF, Offset( mNeedleColor, GuiSpeedometerHud ), 127 "Color of the needle" ); 128 129 addField("center", TypePoint2F, Offset( mCenter, GuiSpeedometerHud ), 130 "Center of the needle, offset from the GuiSpeedometerHud control top " 131 "left corner" ); 132 133 addField("length", TypeF32, Offset( mNeedleLength, GuiSpeedometerHud ), 134 "Length of the needle from center to end" ); 135 136 addField("width", TypeF32, Offset( mNeedleWidth, GuiSpeedometerHud ), 137 "Width of the needle" ); 138 139 addField("tail", TypeF32, Offset( mTailLength, GuiSpeedometerHud ), 140 "Length of the needle from center to tail" ); 141 142 endGroup("Needle"); 143 144 Parent::initPersistFields(); 145} 146 147 148//----------------------------------------------------------------------------- 149/** 150 Gui onRender method. 151 Renders an analog speedometer needle over a specified bitmap background. 152*/ 153void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect) 154{ 155 // Must have a connection 156 GameConnection* conn = GameConnection::getConnectionToServer(); 157 if (!conn) 158 return; 159 160 // Requires either a vehicle control object or a vehicle-mounted player 161 Vehicle* vehicle = dynamic_cast<Vehicle*>(conn->getControlObject()); 162 if(!vehicle){ 163 Player * player = dynamic_cast<Player*>(conn->getControlObject()); 164 if(!player) return; 165 if (!player->isMounted()) return; 166 vehicle = dynamic_cast<Vehicle*>(player->getObjectMount()); 167 if(!vehicle) return; 168 } 169 170 Parent::onRender(offset,updateRect); 171 172 // Use the vehicle's velocity as its speed... 173 mSpeed = vehicle->getVelocity().len(); 174 if (mSpeed > mMaxSpeed) 175 mSpeed = mMaxSpeed; 176 177 // Calculate center point if necessary and roll in offsets 178 Point2F center = mCenter; 179 if (mIsZero(center.x) && mIsZero(center.y)) 180 { 181 center.x = getExtent().x / 2.0f; 182 center.y = getExtent().y / 2.0f; 183 } 184 F32 fillOffset = GFX->getFillConventionOffset(); // Find the fill offset 185 Point2F viewCenter(offset.x + fillOffset + center.x, offset.y + fillOffset + center.y); 186 187 // Handle rotation calculations 188 F32 rotation, spinAngle; 189 rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed); 190 spinAngle = mDegToRad(rotation); 191 MatrixF rotMatrix(EulerF(0.0, 0.0, spinAngle)); 192 193 // Set up the needle vertex list 194 Point3F vertList[5]; 195 vertList[0].set(+mNeedleLength,-mNeedleWidth,0); 196 vertList[1].set(+mNeedleLength,+mNeedleWidth,0); 197 vertList[2].set(-mTailLength ,+mNeedleWidth,0); 198 vertList[3].set(-mTailLength ,-mNeedleWidth,0); 199 vertList[4].set(+mNeedleLength,-mNeedleWidth,0); //// Get back to the start! 200 201 // Create a GFXStateBlock description if one has not been set. 202 if (mBlendSB.isNull()) 203 { 204 GFXStateBlockDesc desc; 205 desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); 206 desc.samplersDefined = true; 207 mBlendSB = GFX->createStateBlock(desc); 208 } 209 GFX->setStateBlock(mBlendSB); 210 GFX->setTexture(0, NULL); 211 212 // Render the needle 213 PrimBuild::color4f(mNeedleColor.red, mNeedleColor.green, mNeedleColor.blue, mNeedleColor.alpha); 214 PrimBuild::begin(GFXLineStrip, 5); 215 for(int k=0; k<5; k++){ 216 rotMatrix.mulP(vertList[k]); 217 PrimBuild::vertex2f(vertList[k].x + viewCenter.x, vertList[k].y + viewCenter.y); 218 } 219 PrimBuild::end(); 220} 221