afxGuiTextHud.cpp
Engine/source/afx/ui/afxGuiTextHud.cpp
Public Functions
ConsoleDocClass(afxGuiTextHud , "@brief Similar <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> GuiShapeNameHud, <a href="/coding/class/classafxguitexthud/">afxGuiTextHud</a> displays <a href="/coding/class/classshapebase/">ShapeBase</a> object names but " "also allows Gui Text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiGame\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(afxGuiTextHud , "@brief Similar <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> GuiShapeNameHud, <a href="/coding/class/classafxguitexthud/">afxGuiTextHud</a> displays <a href="/coding/class/classshapebase/">ShapeBase</a> object names but " "also allows Gui Text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiGame\n</a>" )
IMPLEMENT_CONOBJECT(afxGuiTextHud )
1 2 3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 5// Copyright (C) 2015 Faust Logic, Inc. 6// 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to 9// deal in the Software without restriction, including without limitation the 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11// sell copies of the Software, and to permit persons to whom the Software is 12// furnished to do so, subject to the following conditions: 13// 14// The above copyright notice and this permission notice shall be included in 15// all copies or substantial portions of the Software. 16// 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23// IN THE SOFTWARE. 24// 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 26 27#include "afx/arcaneFX.h" 28 29#include "gui/3d/guiTSControl.h" 30#include "gfx/gfxDrawUtil.h" 31#include "T3D/gameBase/gameConnection.h" 32#include "T3D/shapeBase.h" 33 34#include "afx/ui/afxGuiTextHud.h" 35 36//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 37 38Vector<afxGuiTextHud::HudTextSpec> afxGuiTextHud::text_items; 39 40IMPLEMENT_CONOBJECT(afxGuiTextHud); 41 42ConsoleDocClass( afxGuiTextHud, 43 "@brief Similar to GuiShapeNameHud, afxGuiTextHud displays ShapeBase object names but " 44 "also allows Gui Text effects.\n\n" 45 46 "@ingroup GuiGame\n" 47); 48 49afxGuiTextHud::afxGuiTextHud() 50{ 51 mFillColor.set( 0.25f, 0.25f, 0.25f, 0.25f ); 52 mFrameColor.set( 0, 0, 0, 1 ); 53 mTextColor.set( 0, 1, 0, 1 ); 54 mShowFill = false; 55 mShowFrame = true; 56 mVerticalOffset = 0.5f; 57 mDistanceFade = 0.1f; 58 mLabelAllShapes = false; 59 mEnableControlObjectOcclusion = false; 60} 61 62void afxGuiTextHud::initPersistFields() 63{ 64 addGroup("Colors"); 65 addField( "fillColor", TypeColorF, Offset( mFillColor, afxGuiTextHud ), 66 "..."); 67 addField( "frameColor", TypeColorF, Offset( mFrameColor, afxGuiTextHud ), 68 "..."); 69 addField( "textColor", TypeColorF, Offset( mTextColor, afxGuiTextHud ), 70 "..."); 71 endGroup("Colors"); 72 73 addGroup("Misc"); 74 addField( "showFill", TypeBool, Offset( mShowFill, afxGuiTextHud ), 75 "..."); 76 addField( "showFrame", TypeBool, Offset( mShowFrame, afxGuiTextHud ), 77 "..."); 78 addField( "verticalOffset", TypeF32, Offset( mVerticalOffset, afxGuiTextHud ), 79 "..."); 80 addField( "distanceFade", TypeF32, Offset( mDistanceFade, afxGuiTextHud ), 81 "..."); 82 addField( "labelAllShapes", TypeBool, Offset( mLabelAllShapes, afxGuiTextHud ), 83 "..."); 84 addField( "enableControlObjectOcclusion", TypeBool, Offset( mEnableControlObjectOcclusion, afxGuiTextHud ), 85 "..."); 86 endGroup("Misc"); 87 88 Parent::initPersistFields(); 89} 90 91//---------------------------------------------------------------------------- 92/// Core rendering method for this control. 93/// 94/// This method scans through all the current client ShapeBase objects. 95/// If one is named, it displays the name and damage information for it. 96/// 97/// Information is offset from the center of the object's bounding box, 98/// unless the object is a PlayerObjectType, in which case the eye point 99/// is used. 100/// 101/// @param updateRect Extents of control. 102void afxGuiTextHud::onRender( Point2I, const RectI &updateRect) 103{ 104 // Background fill first 105 if (mShowFill) 106 GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor.toColorI()); 107 108 // Must be in a TS Control 109 GuiTSCtrl *parent = dynamic_cast<GuiTSCtrl*>(getParent()); 110 if (!parent) return; 111 112 // Must have a connection and control object 113 GameConnection* conn = GameConnection::getConnectionToServer(); 114 if (!conn) 115 return; 116 117 GameBase * control = dynamic_cast<GameBase*>(conn->getControlObject()); 118 if (!control) 119 return; 120 121 // Get control camera info 122 MatrixF cam; 123 Point3F camPos; 124 VectorF camDir; 125 conn->getControlCameraTransform(0,&cam); 126 cam.getColumn(3, &camPos); 127 cam.getColumn(1, &camDir); 128 129 F32 camFovCos; 130 conn->getControlCameraFov(&camFovCos); 131 camFovCos = mCos(mDegToRad(camFovCos) / 2); 132 133 // Visible distance info & name fading 134 F32 visDistance = gClientSceneGraph->getVisibleDistance(); 135 F32 visDistanceSqr = visDistance * visDistance; 136 F32 fadeDistance = visDistance * mDistanceFade; 137 138 // Collision info. We're going to be running LOS tests and we 139 // don't want to collide with the control object. 140 static U32 losMask = TerrainObjectType | TerrainLikeObjectType | ShapeBaseObjectType; 141 142 if (!mEnableControlObjectOcclusion) 143 control->disableCollision(); 144 145 if (mLabelAllShapes) 146 { 147 // This section works just like GuiShapeNameHud and renders labels for 148 // all the shapes. 149 150 // All ghosted objects are added to the server connection group, 151 // so we can find all the shape base objects by iterating through 152 // our current connection. 153 for (SimSetIterator itr(conn); *itr; ++itr) 154 { 155 ///if ((*itr)->getTypeMask() & ShapeBaseObjectType) 156 ///{ 157 ShapeBase* shape = dynamic_cast<ShapeBase*>(*itr); 158 if ( shape ) { 159 if (shape != control && shape->getShapeName()) 160 { 161 162 // Target pos to test, if it's a player run the LOS to his eye 163 // point, otherwise we'll grab the generic box center. 164 Point3F shapePos; 165 if (shape->getTypeMask() & PlayerObjectType) 166 { 167 MatrixF eye; 168 169 // Use the render eye transform, otherwise we'll see jittering 170 shape->getRenderEyeTransform(&eye); 171 eye.getColumn(3, &shapePos); 172 } 173 else 174 { 175 // Use the render transform instead of the box center 176 // otherwise it'll jitter. 177 MatrixF srtMat = shape->getRenderTransform(); 178 srtMat.getColumn(3, &shapePos); 179 } 180 181 VectorF shapeDir = shapePos - camPos; 182 183 // Test to see if it's in range 184 F32 shapeDist = shapeDir.lenSquared(); 185 if (shapeDist == 0 || shapeDist > visDistanceSqr) 186 continue; 187 shapeDist = mSqrt(shapeDist); 188 189 // Test to see if it's within our viewcone, this test doesn't 190 // actually match the viewport very well, should consider 191 // projection and box test. 192 shapeDir.normalize(); 193 F32 dot = mDot(shapeDir, camDir); 194 if (dot < camFovCos) 195 continue; 196 197 // Test to see if it's behind something, and we want to 198 // ignore anything it's mounted on when we run the LOS. 199 RayInfo info; 200 shape->disableCollision(); 201 SceneObject *mount = shape->getObjectMount(); 202 if (mount) 203 mount->disableCollision(); 204 bool los = !gClientContainer.castRay(camPos, shapePos,losMask, &info); 205 shape->enableCollision(); 206 if (mount) 207 mount->enableCollision(); 208 209 if (!los) 210 continue; 211 212 // Project the shape pos into screen space and calculate 213 // the distance opacity used to fade the labels into the 214 // distance. 215 Point3F projPnt; 216 shapePos.z += mVerticalOffset; 217 if (!parent->project(shapePos, &projPnt)) 218 continue; 219 F32 opacity = (shapeDist < fadeDistance)? 1.0: 220 1.0 - (shapeDist - fadeDistance) / (visDistance - fadeDistance); 221 222 // Render the shape's name 223 drawName(Point2I((S32)projPnt.x, (S32)projPnt.y),shape->getShapeName(),opacity); 224 } 225 } 226 } 227 } 228 229 // This section renders all text added by afxGuiText effects. 230 for (S32 i = 0; i < text_items.size(); i++) 231 { 232 HudTextSpec* spec = &text_items[i]; 233 if (spec->text && spec->text[0] != '\0') 234 { 235 VectorF shapeDir = spec->pos - camPos; 236 237 // do range test 238 F32 shapeDist = shapeDir.lenSquared(); 239 if (shapeDist == 0 || shapeDist > visDistanceSqr) 240 continue; 241 shapeDist = mSqrt(shapeDist); 242 243 // Test to see if it's within our viewcone, this test doesn't 244 // actually match the viewport very well, should consider 245 // projection and box test. 246 shapeDir.normalize(); 247 F32 dot = mDot(shapeDir, camDir); 248 if (dot < camFovCos) 249 continue; 250 251 // Test to see if it's behind something, and we want to 252 // ignore anything it's mounted on when we run the LOS. 253 RayInfo info; 254 if (spec->obj) 255 spec->obj->disableCollision(); 256 bool los = !gClientContainer.castRay(camPos, spec->pos, losMask, &info); 257 if (spec->obj) 258 spec->obj->enableCollision(); 259 if (!los) 260 continue; 261 262 // Project the shape pos into screen space. 263 Point3F projPnt; 264 if (!parent->project(spec->pos, &projPnt)) 265 continue; 266 267 // Calculate the distance opacity used to fade text into the distance. 268 F32 opacity = (shapeDist < fadeDistance)? 1.0 : 1.0 - (shapeDist - fadeDistance) / (25.0f); 269 if (opacity > 0.01f) 270 drawName(Point2I((S32)projPnt.x, (S32)projPnt.y), spec->text, opacity, &spec->text_clr); 271 } 272 } 273 274 // Restore control object collision 275 if (!mEnableControlObjectOcclusion) 276 control->enableCollision(); 277 278 // Border last 279 if (mShowFrame) 280 GFX->getDrawUtil()->drawRect(updateRect, mFrameColor.toColorI()); 281 282 reset(); 283} 284 285//---------------------------------------------------------------------------- 286/// Render object names. 287/// 288/// Helper function for GuiShapeNameHud::onRender 289/// 290/// @param offset Screen coordinates to render name label. (Text is centered 291/// horizontally about this location, with bottom of text at 292/// specified y position.) 293/// @param name String name to display. 294/// @param opacity Opacity of name (a fraction). 295void afxGuiTextHud::drawName(Point2I offset, const char *name, F32 opacity, LinearColorF* color) 296{ 297 // Center the name 298 offset.x -= mProfile->mFont->getStrWidth((const UTF8 *)name) / 2; 299 offset.y -= mProfile->mFont->getHeight(); 300 301 // Deal with opacity and draw. 302 LinearColorF draw_color = (color) ? *color : mTextColor; 303 draw_color.alpha *= opacity; 304 GFX->getDrawUtil()->setBitmapModulation(draw_color.toColorI()); 305 GFX->getDrawUtil()->drawText(mProfile->mFont, offset, name); 306 GFX->getDrawUtil()->clearBitmapModulation(); 307} 308 309void afxGuiTextHud::addTextItem(const Point3F& pos, const char* text, LinearColorF& color, SceneObject* obj) 310{ 311 if (!text || text[0] == '\0') 312 return; 313 314 HudTextSpec spec; 315 spec.pos = pos; 316 spec.text = text; 317 spec.text_clr = color; 318 spec.obj = obj; 319 320 text_items.push_back(spec); 321} 322 323void afxGuiTextHud::reset() 324{ 325 text_items.clear(); 326} 327 328//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 329 330