KiCad PCB EDA Suite
Loading...
Searching...
No Matches
rhi_static_margin.h
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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef RHI_STATIC_MARGIN_H
21#define RHI_STATIC_MARGIN_H
22
23#include <rhi/frame_packet.h>
24
25#include <algorithm>
26#include <cmath>
27#include <cstdint>
28#include <optional>
29
37
38namespace KIGFX
39{
40
43{
44 int x = 0;
45 int y = 0;
46};
47
48
53inline FRAME_UBO_DATA RhiWidenFrame( const FRAME_UBO_DATA& aFrame, uint32_t aMargin )
54{
55 FRAME_UBO_DATA wide = aFrame;
56 const float w = aFrame.viewport[0];
57 const float h = aFrame.viewport[1];
58
59 if( aMargin == 0 || w <= 0.0f || h <= 0.0f )
60 return wide;
61
62 const float sx = w / ( w + 2.0f * aMargin );
63 const float sy = h / ( h + 2.0f * aMargin );
64
66 for( int col = 0; col < 4; ++col )
67 {
68 wide.projection[col * 4] *= sx;
69 wide.projection[col * 4 + 1] *= sy;
70 }
71
72 wide.viewport[0] = w + 2.0f * aMargin;
73 wide.viewport[1] = h + 2.0f * aMargin;
74 return wide;
75}
76
77
79inline GRID_UBO_DATA RhiWidenGrid( const GRID_UBO_DATA& aGrid, uint32_t aMargin )
80{
81 GRID_UBO_DATA wide = aGrid;
82 const float w = aGrid.viewport[0];
83 const float h = aGrid.viewport[1];
84
85 if( aMargin == 0 || w <= 0.0f || h <= 0.0f )
86 return wide;
87
88 const float sx = w / ( w + 2.0f * aMargin );
89 const float sy = h / ( h + 2.0f * aMargin );
90
92 for( int row = 0; row < 4; ++row )
93 {
94 wide.invProjection[row] /= sx;
95 wide.invProjection[4 + row] /= sy;
96 }
97
98 wide.viewport[0] = w + 2.0f * aMargin;
99 wide.viewport[1] = h + 2.0f * aMargin;
100 return wide;
101}
102
103
105inline bool RhiViewMovedOnly( const FRAME_UBO_DATA& aDrawn, const FRAME_UBO_DATA& aNow )
106{
107 if( aDrawn.viewport[0] != aNow.viewport[0] || aDrawn.viewport[1] != aNow.viewport[1] )
108 return false;
109
110 for( int ii = 0; ii < 16; ++ii )
111 {
112 if( ii == 12 || ii == 13 )
113 continue;
114
115 const float a = aDrawn.projection[ii];
116 const float b = aNow.projection[ii];
117
118 if( std::abs( a - b ) > 1e-6f * std::max( std::abs( a ), std::abs( b ) ) )
119 return false;
120 }
121
122 return true;
123}
124
125
132inline std::optional<RHI_VIEW_SHIFT> RhiViewShift( const FRAME_UBO_DATA& aDrawn, const FRAME_UBO_DATA& aNow )
133{
134 if( !RhiViewMovedOnly( aDrawn, aNow ) )
135 return std::nullopt;
136
137 const double x = ( double( aNow.projection[12] ) - aDrawn.projection[12] ) * aNow.viewport[0] * 0.5;
138 const double y = ( double( aNow.projection[13] ) - aDrawn.projection[13] ) * aNow.viewport[1] * 0.5;
139
140 constexpr double tolerance = 0.02;
141
142 if( std::abs( x - std::round( x ) ) > tolerance || std::abs( y - std::round( y ) ) > tolerance )
143 return std::nullopt;
144
145 return RHI_VIEW_SHIFT{ static_cast<int>( std::lround( x ) ), static_cast<int>( std::lround( y ) ) };
146}
147
148
150inline bool RhiGridMovedOnly( const GRID_UBO_DATA& aDrawn, const GRID_UBO_DATA& aNow )
151{
152 GRID_UBO_DATA moved = aDrawn;
153
155 for( int ii = 0; ii < 16; ++ii )
156 {
157 const float a = aDrawn.invProjection[ii];
158 const float b = aNow.invProjection[ii];
159
160 if( ii != 12 && ii != 13 && std::abs( a - b ) > 1e-6f * std::max( std::abs( a ), std::abs( b ) ) )
161 return false;
162
163 moved.invProjection[ii] = b;
164 }
165
166 return moved == aNow;
167}
168
169} // namespace KIGFX
170
171#endif // RHI_STATIC_MARGIN_H
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:30
bool RhiViewMovedOnly(const FRAME_UBO_DATA &aDrawn, const FRAME_UBO_DATA &aNow)
std::optional< RHI_VIEW_SHIFT > RhiViewShift(const FRAME_UBO_DATA &aDrawn, const FRAME_UBO_DATA &aNow)
FRAME_UBO_DATA RhiWidenFrame(const FRAME_UBO_DATA &aFrame, uint32_t aMargin)
bool RhiGridMovedOnly(const GRID_UBO_DATA &aDrawn, const GRID_UBO_DATA &aNow)
GRID_UBO_DATA RhiWidenGrid(const GRID_UBO_DATA &aGrid, uint32_t aMargin)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:437
Per-frame uniform block matching FrameUBO in frame_ubo.glsl (std140).
float projection[16]
column-major for GLSL
Grid uniform block matching the GridUBO layout in grid.frag (std140).
How far the view has moved since the static target was drawn, in whole frame pixels.
bool moved