Line data Source code
1 : /* Copyright (C) 2020 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_HELPER_RENDER
19 : #define INCLUDED_HELPER_RENDER
20 :
21 : #include <vector>
22 :
23 : class CSimContext;
24 : class CVector2D;
25 : class CVector3D;
26 : class CFixedVector3D;
27 : class CMatrix3D;
28 : class CBoundingBoxAligned;
29 : class CBoundingBoxOriented;
30 :
31 : struct SOverlayLine;
32 : struct SOverlayTexturedLine;
33 :
34 0 : struct SDashedLine
35 : {
36 : /// Packed array of consecutive dashes' points. Use m_StartIndices to navigate it.
37 : std::vector<CVector2D> m_Points;
38 :
39 : /**
40 : * Start indices in m_Points of each dash. Dash n starts at point m_StartIndices[n] and ends at the point with index
41 : * m_StartIndices[n+1] - 1, or at the end of the m_Points vector. Use the GetEndIndex(n) convenience method to abstract away the
42 : * difference and get the (exclusive) end index of dash n.
43 : */
44 : std::vector<size_t> m_StartIndices;
45 :
46 : /// Returns the (exclusive) end point index (i.e. index within m_Points) of dash n.
47 0 : size_t GetEndIndex(size_t i)
48 : {
49 : // for the last dash, there is no next starting index, so we need to use the end index of the m_Points array instead
50 0 : return (i < m_StartIndices.size() - 1 ? m_StartIndices[i+1] : m_Points.size());
51 : }
52 : };
53 :
54 : namespace SimRender
55 : {
56 :
57 : /**
58 : * Constructs overlay line from given points, conforming to terrain.
59 : *
60 : * @param[in] xz List of x,z coordinate pairs representing the line.
61 : * @param[in,out] overlay Updated overlay line now conforming to terrain.
62 : * @param[in] floating If true, the line conforms to water as well.
63 : * @param[in] heightOffset Height above terrain to offset the line.
64 : */
65 : void ConstructLineOnGround(
66 : const CSimContext& context, const std::vector<float>& xz,
67 : SOverlayLine& overlay,
68 : bool floating, float heightOffset = 0.25f);
69 :
70 : /**
71 : * Constructs overlay line as a circle with given center and radius, conforming to terrain.
72 : *
73 : * @param[in] x,z Coordinates of center of circle.
74 : * @param[in] radius Radius of circle to construct.
75 : * @param[in,out] overlay Updated overlay line representing this circle.
76 : * @param[in] floating If true, the circle conforms to water as well.
77 : * @param[in] heightOffset Height above terrain to offset the circle.
78 : * @param heightOffset The vertical offset to apply to points, to raise the line off the terrain a bit.
79 : */
80 : void ConstructCircleOnGround(
81 : const CSimContext& context, float x, float z, float radius,
82 : SOverlayLine& overlay,
83 : bool floating, float heightOffset = 0.25f);
84 :
85 : /**
86 : * Constructs overlay line as an outlined circle sector (an arc with straight lines between the
87 : * endpoints and the circle's center), conforming to terrain.
88 : */
89 : void ConstructClosedArcOnGround(
90 : const CSimContext& context, float x, float z, float radius,
91 : float start, float end,
92 : SOverlayLine& overlay,
93 : bool floating, float heightOffset = 0.25f);
94 :
95 : /**
96 : * Constructs overlay line as rectangle with given center and dimensions, conforming to terrain.
97 : *
98 : * @param[in] x,z Coordinates of center of rectangle.
99 : * @param[in] w,h Width/height dimensions of the rectangle.
100 : * @param[in] a Clockwise angle to orient the rectangle.
101 : * @param[in,out] overlay Updated overlay line representing this rectangle.
102 : * @param[in] floating If true, the rectangle conforms to water as well.
103 : * @param[in] heightOffset Height above terrain to offset the rectangle.
104 : */
105 : void ConstructSquareOnGround(
106 : const CSimContext& context, float x, float z, float w, float h, float a,
107 : SOverlayLine& overlay,
108 : bool floating, float heightOffset = 0.25f);
109 :
110 : /**
111 : * Constructs a solid outline of an arbitrarily-aligned bounding @p box.
112 : *
113 : * @param[in] box
114 : * @param[in,out] overlayLine Updated overlay line representing the oriented box.
115 : */
116 : void ConstructBoxOutline(const CBoundingBoxOriented& box, SOverlayLine& overlayLine);
117 :
118 : /**
119 : * Constructs a solid outline of an axis-aligned bounding @p box.
120 : *
121 : * @param[in] bound
122 : * @param[in,out] overlayLine Updated overlay line representing the AABB.
123 : */
124 : void ConstructBoxOutline(const CBoundingBoxAligned& box, SOverlayLine& overlayLine);
125 :
126 : /**
127 : * Constructs a simple gimbal outline with the given radius and center.
128 : *
129 : * @param[in] center
130 : * @param[in] radius
131 : * @param[in,out] out Updated overlay line representing the gimbal.
132 : * @param[in] numSteps The amount of steps to trace a circle's complete outline. Must be a (strictly) positive multiple of four.
133 : * For small radii, you can get away with small values; setting this to 4 will create a diamond shape.
134 : */
135 : void ConstructGimbal(const CVector3D& center, float radius, SOverlayLine& out, size_t numSteps = 16);
136 :
137 : /**
138 : * Constructs 3D axis marker overlay lines for the given coordinate system.
139 : * The XYZ axes are colored RGB, respectively.
140 : *
141 : * @param[in] coordSystem Specifies the coordinate system.
142 : * @param[out] outX,outY,outZ Constructed overlay lines for each axes.
143 : */
144 : void ConstructAxesMarker(const CMatrix3D& coordSystem, SOverlayLine& outX, SOverlayLine& outY, SOverlayLine& outZ);
145 :
146 : /**
147 : * Updates the given points so each point is averaged with its neighbours, resulting in
148 : * a somewhat smoother curve, assuming the points are roughly equally spaced.
149 : *
150 : * @param[in,out] points List of points to smooth.
151 : * @param[in] closed if true, then the points are treated as a closed path (the last is connected
152 : * to the first).
153 : */
154 : void SmoothPointsAverage(std::vector<CVector2D>& points, bool closed);
155 :
156 : /**
157 : * Updates the given points to include intermediate points interpolating between the original
158 : * control points, using a rounded nonuniform spline.
159 : *
160 : * @param[in,out] points List of points to interpolate.
161 : * @param[in] closed if true, then the points are treated as a closed path (the last is connected
162 : * to the first).
163 : * @param[in] offset The points are shifted by this distance in a direction 90 degrees clockwise from
164 : * the direction of the curve.
165 : * @param[in] segmentSamples Amount of intermediate points to sample between every two control points.
166 : */
167 : void InterpolatePointsRNS(std::vector<CVector2D>& points, bool closed, float offset, int segmentSamples = 4);
168 :
169 : /**
170 : * Creates a dashed line from the given line, dash length, and blank space between.
171 : *
172 : * @param[in] linePoints List of points specifying the input line.
173 : * @param[out] dashedLineOut The dashed line returned as a list of smaller lines
174 : * @param[in] dashLength Length of a single dash. Must be strictly positive.
175 : * @param[in] blankLength Length of a single blank between dashes. Must be strictly positive.
176 : */
177 : void ConstructDashedLine(const std::vector<CVector2D>& linePoints, SDashedLine& dashedLineOut,
178 : const float dashLength, const float blankLength);
179 :
180 : /**
181 : * Subdivides a list of @p points into segments of maximum length @p maxSegmentLength that are of equal size between every two
182 : * control points. The resulting subdivided list of points is written back to @p points.
183 : *
184 : * @param points The list of intermediate points to subdivide.
185 : * @param maxSegmentLength The maximum length of a single segment after subdivision. Must be strictly positive.
186 : * @param closed Should the provided list of points be treated as a closed shape? If true, the resulting list of points will include
187 : * extra subdivided points between the last and the first point.
188 : */
189 : void SubdividePoints(std::vector<CVector2D>& points, float maxSegmentLength, bool closed);
190 :
191 : /**
192 : * Sets the coordinates of a rectangular textured overlay, for example used by selection rings of structures.
193 : */
194 : void ConstructTexturedLineBox(SOverlayTexturedLine& overlay, const CVector2D& origin, const CFixedVector3D& rotation, const float sizeX, const float sizeZ);
195 :
196 : /**
197 : * Sets the coordinates of a circular textured overlay, for example by selection rings of units or attack range visualization.
198 : */
199 : void ConstructTexturedLineCircle(SOverlayTexturedLine& overlay, const CVector2D& origin, const float overlay_radius);
200 :
201 : } // namespace
202 :
203 : #endif // INCLUDED_HELPER_RENDER
|