KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ruler_item.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
27#include <layer_ids.h>
28#include <gal/painter.h>
29#include <view/view.h>
30#include <trigo.h>
31
32using namespace KIGFX::PREVIEW;
33
34static const double maxTickDensity = 10.0; // min pixels between tick marks
35static const double midTickLengthFactor = 1.5;
36static const double majorTickLengthFactor = 2.5;
37
38
39/*
40 * It would be nice to know why Cairo seems to have an opposite layer order from GAL, but
41 * only when drawing RULER_ITEMs (the TWO_POINT_ASSISTANT and ARC_ASSISTANT are immune from
42 * this issue).
43 *
44 * Until then, this egregious hack...
45 */
46static int getShadowLayer( KIGFX::GAL* aGal )
47{
48 if( aGal->IsCairoEngine() )
50 else
51 return LAYER_GP_OVERLAY;
52}
53
54
55static double getTickLineWidth( const TEXT_DIMS& textDims, bool aDrawingDropShadows )
56{
57 double width = textDims.StrokeWidth * 0.8;
58
59 if( aDrawingDropShadows )
60 width += textDims.ShadowWidth;
61
62 return width;
63}
64
65
71{
72 double divisionBase;
74 int midStep;
75};
76
77
78static TICK_FORMAT getTickFormatForScale( double aScale, double& aTickSpace, EDA_UNITS aUnits )
79{
80 // simple 1/2/5 scales per decade
81 static std::vector<TICK_FORMAT> tickFormats =
82 {
83 { 2, 10, 5 }, // |....:....|
84 { 2, 5, 0 }, // |....|
85 { 2.5, 2, 0 }, // |.|.|
86 };
87
88 // could start at a set number of MM, but that's not available in common
89 aTickSpace = 1;
90
91 // Convert to a round (mod-10) number of mils for imperial units
92 if( EDA_UNIT_UTILS::IsImperialUnit( aUnits ) )
93 aTickSpace *= 2.54;
94
95 int tickFormat = 0;
96
97 while( true )
98 {
99 const auto pixelSpace = aTickSpace * aScale;
100
101 if( pixelSpace >= maxTickDensity )
102 break;
103
104 tickFormat = ( tickFormat + 1 ) % tickFormats.size();
105 aTickSpace *= tickFormats[tickFormat].divisionBase;
106 }
107
108 return tickFormats[tickFormat];
109}
110
111
121void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
122 double aMinorTickLen, const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
123 bool aDrawingDropShadows )
124{
125 KIGFX::GAL* gal = aView->GetGAL();
127 double tickSpace;
128 TICK_FORMAT tickFormat = getTickFormatForScale( gal->GetWorldScale(), tickSpace, aUnits );
129 double majorTickLen = aMinorTickLen * ( majorTickLengthFactor + 1 );
130 VECTOR2D tickLine = aLine;
131
132 RotatePoint( tickLine, ANGLE_90 );
133
134 // number of ticks in whole ruler
135 int numTicks = (int) std::ceil( aLine.EuclideanNorm() / tickSpace );
136
137 // work out which way up the tick labels go
138 TEXT_DIMS labelDims = GetConstantGlyphHeight( gal, -1 );
139 EDA_ANGLE labelAngle = - EDA_ANGLE( tickLine );
140 VECTOR2I labelOffset = tickLine.Resize( majorTickLen );
141
142 // text is left (or right) aligned, so shadow text need a small offset to be draw
143 // around the basic text
144 int shadowXoffset = 0;
145
146 if( aDrawingDropShadows )
147 {
148 labelDims.StrokeWidth += 2 * labelDims.ShadowWidth;
149 shadowXoffset = labelDims.ShadowWidth;
150
151 // Due to the fact a shadow text is drawn left or right aligned,
152 // it needs an offset = shadowXoffset to be drawn at the same place as normal text
153 // But for some reason we need to slightly modify this offset
154 // for a better look for KiCad font (better alignment of shadow shape)
155 const float adjust = 1.2f; // Value chosen after tests
156 shadowXoffset *= adjust;
157 }
158
159 if( aView->IsMirroredX() )
160 {
161 labelOffset = -labelOffset;
162 shadowXoffset = -shadowXoffset;
163 }
164
165 TEXT_ATTRIBUTES labelAttrs;
166 labelAttrs.m_Size = labelDims.GlyphSize;
167 labelAttrs.m_StrokeWidth = labelDims.StrokeWidth;
168 labelAttrs.m_Mirrored = aView->IsMirroredX(); // Prevent text mirrored when view is mirrored
169
170 if( EDA_ANGLE( aLine ) > ANGLE_0 )
171 {
172 labelAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
173 labelAttrs.m_Angle = labelAngle;
174
175 // Adjust the text position of the shadow shape:
176 labelOffset.x -= shadowXoffset * labelAttrs.m_Angle.Cos();;
177 labelOffset.y += shadowXoffset * labelAttrs.m_Angle.Sin();;
178 }
179 else
180 {
181 labelAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
182 labelAttrs.m_Angle = labelAngle + ANGLE_180;
183
184 // Adjust the text position of the shadow shape:
185 labelOffset.x += shadowXoffset * labelAttrs.m_Angle.Cos();;
186 labelOffset.y -= shadowXoffset * labelAttrs.m_Angle.Sin();;
187 }
188
189 BOX2D viewportD = aView->GetViewport();
190 BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
191
192 viewport.Inflate( majorTickLen * 2 ); // Doesn't have to be accurate, just big enough not
193 // to exclude anything that should be partially drawn
194
195 int isign = aView->IsMirroredX() ? -1 : 1;
196
197 for( int i = 0; i < numTicks; ++i )
198 {
199 const VECTOR2D tickPos = aOrigin + aLine.Resize( tickSpace * i );
200
201 if( !viewport.Contains( tickPos ) )
202 continue;
203
204 double length = aMinorTickLen;
205 bool drawLabel = false;
206
207 if( i % tickFormat.majorStep == 0 )
208 {
209 drawLabel = true;
210 length *= majorTickLengthFactor;
211 }
212 else if( tickFormat.midStep && i % tickFormat.midStep == 0 )
213 {
214 drawLabel = true;
215 length *= midTickLengthFactor;
216 }
217
218 gal->SetLineWidth( labelAttrs.m_StrokeWidth / 2 );
219 gal->DrawLine( tickPos, tickPos + tickLine.Resize( length*isign ) );
220
221 if( drawLabel )
222 {
223 wxString label = DimensionLabel( "", tickSpace * i, aIuScale, aUnits, false );
224 font->Draw( gal, label, tickPos + labelOffset, labelAttrs, KIFONT::METRICS::Default() );
225 }
226 }
227}
228
229
240void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
241 double aTickLen, int aNumDivisions, bool aDrawingDropShadows )
242{
243 KIGFX::GAL* gal = aView->GetGAL();
244 TEXT_DIMS textDims = GetConstantGlyphHeight( gal, -1 );
245 const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
246 VECTOR2D backTickVec = aLine;
247 int isign = aView->IsMirroredX() ? -1 : 1;
248
249 RotatePoint( backTickVec, -ANGLE_90 );
250 backTickVec = backTickVec.Resize( aTickLen * isign );
251
252 BOX2D viewportD = aView->GetViewport();
253 BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
254
255 viewport.Inflate( aTickLen * 4 ); // Doesn't have to be accurate, just big enough not to
256 // exclude anything that should be partially drawn
257
258 for( int i = 0; i < aNumDivisions + 1; ++i )
259 {
260 const VECTOR2D backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
261
262 if( !viewport.Contains( backTickPos ) )
263 continue;
264
265 gal->SetLineWidth( getTickLineWidth( textDims, aDrawingDropShadows ) );
266 gal->DrawLine( backTickPos, backTickPos + backTickVec );
267 }
268}
269
270
272 EDA_UNITS userUnits, bool aFlipX, bool aFlipY )
273 : EDA_ITEM( NOT_USED ), // Never added to anything - just a preview
274 m_geomMgr( aGeomMgr ),
275 m_userUnits( userUnits ),
276 m_iuScale( aIuScale ),
277 m_flipX( aFlipX ),
278 m_flipY( aFlipY )
279{
280}
281
282
284{
285 BOX2I tmp;
286
287 if( m_geomMgr.GetOrigin() == m_geomMgr.GetEnd() )
288 return tmp;
289
290 // this is an edit-time artefact; no reason to try and be smart with the bounding box
291 // (besides, we can't tell the text extents without a view to know what the scale is)
292 tmp.SetMaximum();
293 return tmp;
294}
295
296
297std::vector<int> RULER_ITEM::ViewGetLayers() const
298{
299 std::vector<int> layers{ LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY };
300 return layers;
301}
302
303
304void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
305{
306 KIGFX::GAL* gal = aView->GetGAL();
307 RENDER_SETTINGS* rs = aView->GetPainter()->GetSettings();
308 bool drawingDropShadows = ( aLayer == getShadowLayer( gal ) );
309
311 gal->SetLayerDepth( gal->GetMinDepth() );
312
313 VECTOR2D origin = m_geomMgr.GetOrigin();
314 VECTOR2D end = m_geomMgr.GetEnd();
315
316 gal->SetIsStroke( true );
317 gal->SetIsFill( false );
318 gal->SetTextMirrored( false );
319
320 if( m_color )
321 gal->SetStrokeColor( *m_color );
322 else
324
325 if( drawingDropShadows )
327
328 gal->ResetTextAttributes();
329 TEXT_DIMS textDims = GetConstantGlyphHeight( gal );
330
331 // draw the main line from the origin to cursor
332 gal->SetLineWidth( getTickLineWidth( textDims, drawingDropShadows ) );
333 gal->DrawLine( origin, end );
334
335 VECTOR2D rulerVec( end - origin );
336
337 wxArrayString cursorStrings = GetDimensionStrings();
338
339 // Choose a text quadrant that keeps the measurement text on-screen while avoiding
340 // overlapping the ruler geometry. Start with the preferred direction (away from the
341 // origin) and fall back to other quadrants as needed to keep the label visible.
342 int prefX = rulerVec.y < 0.0 ? -1 : 1;
343 int prefY = rulerVec.x < 0.0 ? 1 : -1;
344
345 double scale = gal->GetWorldScale();
346
347 TEXT_DIMS dims = GetConstantGlyphHeight( gal );
349 double width = 0.0;
350
351 for( const wxString& s : cursorStrings )
352 {
353 VECTOR2I extents = font->StringBoundaryLimits( s, dims.GlyphSize, dims.StrokeWidth, false, false,
355 width = std::max( width, (double) extents.x );
356 }
357
358 double height = dims.LinePitch * cursorStrings.size();
359
360 // Convert to screen coordinates for visibility checks
361 VECTOR2D cursorScreen = gal->ToScreen( end );
362 VECTOR2I screenSize = gal->GetScreenPixelSize();
363 double offsetX = 15.0; // same as DrawTextNextToCursor()
364 double offsetY = dims.LinePitch * scale; // vertical spacing from cursor
365
366 auto fits = [&]( int sx, int sy )
367 {
368 double left, right, top, bottom;
369 double xStart = cursorScreen.x + ( sx < 0 ? offsetX : -offsetX );
370
371 if( sx < 0 )
372 {
373 left = xStart;
374 right = left + width * scale;
375 }
376 else
377 {
378 right = xStart;
379 left = right - width * scale;
380 }
381
382 if( sy > 0 ) // above cursor
383 {
384 bottom = cursorScreen.y - offsetY;
385 top = bottom - height * scale;
386 }
387 else // below cursor
388 {
389 top = cursorScreen.y + offsetY;
390 bottom = top + height * scale;
391 }
392
393 return left >= 0 && right <= screenSize.x && top >= 0 && bottom <= screenSize.y;
394 };
395
396 std::vector<VECTOR2I> candidates = { { prefX, prefY }, { -prefX, prefY },
397 { prefX, -prefY }, { -prefX, -prefY } };
398
399 VECTOR2I chosen = candidates[0];
400 double bestDot = -1.0;
401
402 for( const VECTOR2I& c : candidates )
403 {
404 double dot = c.x * prefX + c.y * prefY;
405
406 if( dot >= 0 && fits( c.x, c.y ) )
407 {
408 if( dot > bestDot )
409 {
410 bestDot = dot;
411 chosen = c;
412 }
413 }
414 }
415
416 VECTOR2D quadrant( chosen.x, chosen.y );
417 DrawTextNextToCursor( aView, end, quadrant, cursorStrings, drawingDropShadows );
418
419 // basic tick size
420 double minorTickLen = 5.0 / gal->GetWorldScale();
421 double majorTickLen = minorTickLen * majorTickLengthFactor;
422
423 minorTickLen = std::min( minorTickLen, (double) INT_MAX / 2.0 );
424 majorTickLen = std::min( majorTickLen, (double) INT_MAX / 2.0 );
425
426 if( m_showTicks )
427 {
428 drawTicksAlongLine( aView, origin, rulerVec, minorTickLen, m_iuScale, m_userUnits, drawingDropShadows );
429 drawBacksideTicks( aView, origin, rulerVec, majorTickLen, 2, drawingDropShadows );
430 }
431
433 {
434 const EDA_ANGLE arrowAngle{ 30.0 };
435 VECTOR2D arrowHead = rulerVec;
436 RotatePoint( arrowHead, arrowAngle );
437 arrowHead = arrowHead.Resize( majorTickLen );
438
439 gal->DrawLine( end, end - arrowHead );
440
441 arrowHead = rulerVec;
442 RotatePoint( arrowHead, -arrowAngle );
443 arrowHead = arrowHead.Resize( majorTickLen );
444
445 gal->DrawLine( end, end - arrowHead );
446 }
447 else
448 {
449 // draw the back of the origin "crosshair"
450 gal->DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
451 }
452}
453
454
456{
457 const VECTOR2D rulerVec = m_geomMgr.GetEnd() - m_geomMgr.GetOrigin();
458 VECTOR2D temp = rulerVec;
459
460 if( m_flipX )
461 temp.x = -temp.x;
462
463 if( m_flipY )
464 temp.y = -temp.y;
465
466 wxArrayString cursorStrings;
467
468 cursorStrings.push_back( DimensionLabel( "x", temp.x, m_iuScale, m_userUnits ) );
469 cursorStrings.push_back( DimensionLabel( "y", temp.y, m_iuScale, m_userUnits ) );
470
471 cursorStrings.push_back( DimensionLabel( "r", rulerVec.EuclideanNorm(), m_iuScale, m_userUnits ) );
472
473 EDA_ANGLE angle = -EDA_ANGLE( rulerVec );
474 cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), angle.AsDegrees(), m_iuScale,
476 return cursorStrings;
477}
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
BOX2< VECTOR2D > BOX2D
Definition box2.h:923
constexpr const Vec & GetPosition() const
Definition box2.h:211
constexpr void SetMaximum()
Definition box2.h:80
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:558
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:168
constexpr const SizeVec & GetSize() const
Definition box2.h:206
double Sin() const
Definition eda_angle.h:178
double AsDegrees() const
Definition eda_angle.h:116
double Cos() const
Definition eda_angle.h:197
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:39
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:147
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics) const
Draw a string.
Definition font.cpp:250
VECTOR2I StringBoundaryLimits(const wxString &aText, const VECTOR2I &aSize, int aThickness, bool aBold, bool aItalic, const METRICS &aFontMetrics) const
Compute the boundary limits of aText (the bounding box of all shapes).
Definition font.cpp:427
static const METRICS & Default()
Definition font.cpp:52
Attribute save/restore for GAL attributes.
Abstract interface for drawing on a 2D-surface.
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
VECTOR2D ToScreen(const VECTOR2D &aPoint) const
Compute the point position in screen coordinates from given world coordinates.
const COLOR4D & GetStrokeColor() const
Get the stroke color.
void ResetTextAttributes()
Reset text attributes to default styling.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
void SetTextMirrored(const bool aMirrored)
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
virtual bool IsCairoEngine()
Return true if the GAL engine is a Cairo based type.
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
double GetMinDepth() const
const VECTOR2I & GetScreenPixelSize() const
Return GAL canvas size in pixels.
double GetWorldScale() const
Get the world scale.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
std::vector< int > ViewGetLayers() const override
RULER_ITEM(const TWO_POINT_GEOMETRY_MANAGER &m_geomMgr, const EDA_IU_SCALE &aIuScale, EDA_UNITS userUnits, bool aFlipX, bool aFlipY)
Return the bounding box of the item covering all its layers.
const TWO_POINT_GEOMETRY_MANAGER & m_geomMgr
Definition ruler_item.h:100
wxArrayString GetDimensionStrings() const
Get the strings for the dimensions of the ruler.
std::optional< COLOR4D > m_color
Definition ruler_item.h:105
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override final
Draw the parts of the object belonging to layer aLayer.
const BOX2I ViewBBox() const override
Return the all the layers within the VIEW the object is painted on.
const EDA_IU_SCALE & m_iuScale
Definition ruler_item.h:102
Represent a very simple geometry manager for items that have a start and end point.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:66
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition view.cpp:530
GAL * GetGAL() const
Return the GAL this view is using to draw graphical primitives.
Definition view.h:202
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition view.h:250
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:220
GR_TEXT_H_ALIGN_T m_Halign
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:283
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition vector2d.h:385
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:415
EDA_UNITS
Definition eda_units.h:48
@ LAYER_GP_OVERLAY
General purpose overlay.
Definition layer_ids.h:278
@ LAYER_AUX_ITEMS
Auxiliary items (guides, rule, etc).
Definition layer_ids.h:282
@ LAYER_SELECT_OVERLAY
Selected items overlay.
Definition layer_ids.h:279
KICOMMON_API bool IsImperialUnit(EDA_UNITS aUnit)
Definition eda_units.cpp:47
COLOR4D GetShadowColor(const COLOR4D &aColor)
void DrawTextNextToCursor(KIGFX::VIEW *aView, const VECTOR2D &aCursorPos, const VECTOR2D &aTextQuadrant, const wxArrayString &aStrings, bool aDrawingDropShadows)
Draw strings next to the cursor.
wxString DimensionLabel(const wxString &prefix, double aVal, const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, bool aIncludeUnits=true)
Get a formatted string showing a dimension to a sane precision with an optional prefix and unit suffi...
TEXT_DIMS GetConstantGlyphHeight(KIGFX::GAL *aGal, int aRelativeSize=0)
Set the GAL glyph height to a constant scaled value, so that it always looks the same on screen.
static double getTickLineWidth(const TEXT_DIMS &textDims, bool aDrawingDropShadows)
static const double maxTickDensity
static TICK_FORMAT getTickFormatForScale(double aScale, double &aTickSpace, EDA_UNITS aUnits)
void drawBacksideTicks(KIGFX::VIEW *aView, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aTickLen, int aNumDivisions, bool aDrawingDropShadows)
Draw simple ticks on the back of a line such that the line is divided into n parts.
void drawTicksAlongLine(KIGFX::VIEW *aView, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aMinorTickLen, const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, bool aDrawingDropShadows)
Draw labeled ticks on a line.
static const double majorTickLengthFactor
static int getShadowLayer(KIGFX::GAL *aGal)
static const double midTickLengthFactor
const int scale
Description of a "tick format" for a scale factor - how many ticks there are between medium/major tic...
int majorStep
ticks between major ticks
double divisionBase
multiple from the last scale
int midStep
ticks between medium ticks (0 if no medium ticks)
VECTOR2I end
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:229
@ NOT_USED
the 3d code uses this value
Definition typeinfo.h:79
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694