Torque3D Documentation / _generateds / afxGuiTextHud.cpp

afxGuiTextHud.cpp

Engine/source/afx/ui/afxGuiTextHud.cpp

More...

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