Torque3D Documentation / _generateds / guiFilterCtrl.cpp

guiFilterCtrl.cpp

Engine/source/gui/editor/guiFilterCtrl.cpp

More...

Public Functions

ConsoleDocClass(GuiFilterCtrl , "@brief A <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> that displays <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Catmull-Rom spline through <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> number of <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">points.\n\n</a>" "Currently editor use only, no real application without <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">extension.\n\n</a> " " @internal" )
DefineEngineMethod(GuiFilterCtrl , getValue , const char * , () , "Return <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tuple containing all the values in the filter." "@internal" )
DefineEngineMethod(GuiFilterCtrl , resetFiltering , void , () , "Reset the filtering." "@internal" )
DefineEngineStringlyVariadicMethod(GuiFilterCtrl , setValue , void , 3 , 20 , "(f1, f2, ...)" "Reset the filter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use the specified points, spread equidistantly across the domain." " @internal" )

Detailed Description

Public Functions

ConsoleDocClass(GuiFilterCtrl , "@brief A <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> that displays <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Catmull-Rom spline through <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> number of <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">points.\n\n</a>" "Currently editor use only, no real application without <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">extension.\n\n</a> " " @internal" )

DefineEngineMethod(GuiFilterCtrl , getValue , const char * , () , "Return <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tuple containing all the values in the filter." "@internal" )

DefineEngineMethod(GuiFilterCtrl , resetFiltering , void , () , "Reset the filtering." "@internal" )

DefineEngineStringlyVariadicMethod(GuiFilterCtrl , setValue , void , 3 , 20 , "(f1, f2, ...)" "Reset the filter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use the specified points, spread equidistantly across the domain." " @internal" )

IMPLEMENT_CONOBJECT(GuiFilterCtrl )

  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
 24#include "platform/platform.h"
 25#include "gui/editor/guiFilterCtrl.h"
 26
 27#include "console/engineAPI.h"
 28#include "console/console.h"
 29#include "console/consoleTypes.h"
 30#include "guiFilterCtrl.h"
 31#include "math/mMath.h"
 32#include "gfx/gfxDrawUtil.h"
 33
 34
 35IMPLEMENT_CONOBJECT(GuiFilterCtrl);
 36
 37ConsoleDocClass( GuiFilterCtrl,
 38            "@brief A control that displays a Catmull-Rom spline through a number of control points.\n\n"
 39            "Currently editor use only, no real application without extension.\n\n "
 40            "@internal");
 41
 42GuiFilterCtrl::GuiFilterCtrl()
 43{
 44   mControlPointRequest = 7;
 45   mFilter.setSize(7);
 46   mShowIdentity = true;
 47   mIdentity.set( 0.0f, 1.0f );
 48   identity();
 49   mCurKnot = -1;
 50}
 51
 52void GuiFilterCtrl::initPersistFields()
 53{
 54   addField("controlPoints", TypeS32, Offset(mControlPointRequest, GuiFilterCtrl),
 55      "Total number of control points in the spline curve." );
 56   addField("filter", TypeF32Vector, Offset(mFilter, GuiFilterCtrl),
 57      "Vector of control points." );
 58   addField("showIdentity", TypeBool, Offset(mShowIdentity, GuiFilterCtrl), "@internal" );
 59   addField("identity", TypePoint2F, Offset(mIdentity, GuiFilterCtrl), "@internal");
 60
 61   Parent::initPersistFields();
 62}
 63
 64DefineEngineMethod( GuiFilterCtrl, getValue, const char*, (), , "Return a tuple containing all the values in the filter."
 65           "@internal")
 66{
 67   static char buffer[512];
 68   const Filter *filter = object->get();
 69   *buffer = 0;
 70
 71   for (U32 i=0; i < filter->size(); i++)
 72   {
 73      char value[32];
 74      dSprintf(value, 32, "%1.5f ", *(filter->begin()+i) );
 75      dStrcat(buffer, value, 32);
 76   }
 77
 78   return buffer;
 79}
 80
 81DefineEngineStringlyVariadicMethod( GuiFilterCtrl, setValue, void, 3, 20, "(f1, f2, ...)"
 82              "Reset the filter to use the specified points, spread equidistantly across the domain."
 83           "@internal")
 84{
 85   Filter filter;
 86
 87   StringStackWrapper args(argc - 2, argv + 2);
 88
 89   filter.set(args.count(), args);
 90   object->set(filter);
 91}
 92
 93DefineEngineMethod( GuiFilterCtrl, resetFiltering, void, (), , "Reset the filtering."
 94           "@internal")
 95{
 96   object->identity();
 97}
 98
 99bool GuiFilterCtrl::onWake()
100{
101   if (!Parent::onWake())
102      return false;
103
104   if (U32(mControlPointRequest) != mFilter.size())
105   {
106      mFilter.setSize(mControlPointRequest);
107      identity();
108   }
109
110   mCurKnot = -1;
111
112   return true;
113}
114
115
116void GuiFilterCtrl::identity()
117{
118   S32 size = mFilter.size()-1;
119   for (U32 i=0; S32(i) <= size; i++)
120   {
121      F32 step = (F32)i/(F32)size;
122      mFilter[i] = mLerp( mIdentity.x, mIdentity.y, step );
123   }
124}
125
126
127void GuiFilterCtrl::onMouseDown(const GuiEvent &event)
128{
129   mouseLock();
130   setFirstResponder();
131
132   Point2I p = globalToLocalCoord(event.mousePoint);
133
134   // determine which knot (offset same as in onRender)
135   F32 w = F32(getWidth()-4) / F32(mFilter.size()-1);
136   F32 val = (F32(p.x) + (w / 2.f)) / w;
137   mCurKnot = S32(val);
138
139   mFilter[mCurKnot] = 1.0f - F32(getMin(getMax(0, p.y), getHeight())/(F32)getHeight());
140   setUpdate();
141}
142
143
144void GuiFilterCtrl::onMouseDragged(const GuiEvent &event)
145{
146   if ( mCurKnot < 0 )
147      return;
148
149   mouseLock();
150   setFirstResponder();
151
152   Point2I p = globalToLocalCoord(event.mousePoint);
153   mFilter[mCurKnot] = 1.0f - F32(getMin(getMax(0, p.y), getHeight())/(F32)getHeight());
154   setUpdate();
155}
156
157void GuiFilterCtrl::onMouseUp(const GuiEvent &)
158{
159   if ( mCurKnot < 0 )
160      return;
161
162   mouseUnlock();
163   execConsoleCallback();
164}
165
166void GuiFilterCtrl::onPreRender()
167{
168   if(U32(mControlPointRequest) != mFilter.size())
169   {
170      mFilter.setSize(mControlPointRequest);
171      identity();
172      setUpdate();
173   }
174}
175
176void GuiFilterCtrl::onRender(Point2I offset, const RectI &updateRect)
177{
178   Point2I pos = offset;
179   Point2I ext = getExtent();
180
181   RectI bgRect(pos, ext);
182   GFX->getDrawUtil()->drawRectFill(bgRect, ColorI(255,255,255));
183   GFX->getDrawUtil()->drawRect(bgRect, ColorI(0,0,0));
184
185   // shrink by 2 pixels
186   pos.x += 2;
187   pos.y += 2;
188   ext.x -= 4;
189   ext.y -= 4;
190
191   // draw the identity line
192   if ( mShowIdentity )
193   {
194      GFX->getDrawUtil()->drawLine( pos.x, pos.y + ( ext.y * ( 1.0f - mIdentity.x ) ), 
195                                    pos.x + ext.x, pos.y + ( ext.y * ( 1.0f - mIdentity.y ) ), 
196                                    ColorI( 230, 230, 230 ) );
197   }
198
199   // draw the curv
200   GFXVertexBufferHandle<GFXVertexPCT> verts(GFX, ext.x, GFXBufferTypeVolatile);
201
202   verts.lock();
203
204   F32 scale = 1.f / F32( ext.x );
205   for ( U32 i = 0; i < ext.x; i++)
206   {
207      F32 index = F32(i) * scale;
208      S32 y = (S32)(ext.y*(1.0f-mFilter.getValue(index)));
209
210      verts[i].point.set( (F32)(pos.x + i), (F32)(pos.y + y), 0.0f );
211      verts[i].color = ColorI( 103, 103, 103 );
212   }
213
214   verts.unlock();
215
216   GFX->setVertexBuffer( verts );
217   GFX->drawPrimitive( GFXLineStrip, 0, ext.x - 1 );
218
219   // draw the knots
220   for (U32 k=0; k < mFilter.size(); k++)
221   {
222      RectI knotRect;
223     knotRect.point.x = (S32)(((F32)ext.x/(F32)(mFilter.size()-1)*(F32)k));
224     knotRect.point.y = (S32)(ext.y - ((F32)ext.y * mFilter[k]));
225     knotRect.point += pos + Point2I(-2,-2);
226     knotRect.extent = Point2I(5,5);
227
228      GFX->getDrawUtil()->drawRectFill(knotRect, ColorI(255,0,0));
229   }
230
231   renderChildControls(offset, updateRect);
232}
233
234
235
236//--------------------------------------
237void Filter::set(S32 argc, const char *argv[])
238{
239   setSize(0);
240   if (argc == 1)
241   {  // in the form of one string "1.0 1.0 1.0"
242      char list[1024];
243      dStrcpy(list, *argv, 1024);    // strtok modifies the string so we need to copy it
244      char *value = dStrtok(list, " ");
245      while (value)
246      {
247         push_back(dAtof(value));
248         value = dStrtok(NULL, " ");
249      }
250   }
251   else
252   {  // in the form of seperate strings "1.0" "1.0" "1.0"
253      for (; argc ; argc--, argv++)
254         push_back(dAtof(*argv));
255   }
256}
257
258
259//--------------------------------------
260F32 Filter::getValue(F32 x) const
261{
262   if (size() < 2)
263      return 0.0f;
264
265   x = mClampF(x, 0.0f, 1.0f);
266   x *= F32(size()-1);
267
268   F32 p0,p1,p2,p3;
269   S32 i1 = (S32)mFloor(x);
270   S32 i2 = i1+1;
271   F32 dt = x - F32(i1);
272
273   p1 = *(begin()+i1);
274   p2 = *(begin()+i2);
275
276   if (i1 == 0)
277      p0 = p1 + (p1 - p2);
278   else
279      p0 = *(begin()+i1-1);
280
281   if (i2 == S32(size()-1))
282      p3 = p2 + (p2 - p1);
283   else
284      p3 = *(begin()+i2+1);
285
286   return mClampF( mCatmullrom(dt, p0, p1, p2, p3), 0.0f, 1.0f );
287}
288
289
290
291
292
293
294