Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_ShapeAnalyser.c
Go to the documentation of this file.
4 {
5  protected bool m_bIsSpline;
6  protected bool m_bIsClosed;
7 
8  protected ref array<ref SCR_Ray> m_aAnchorRays;
9  protected ref array<ref SCR_Ray> m_aMidPointRays;
10  protected ref array<ref SCR_Ray> m_aTesselatedPointRays;
11 
12  // stats
13  protected float m_fLength2D;
14  protected float m_fLength3D;
15  protected float m_fSurface;
16  protected float m_fMinAltitude, m_fMaxAltitude;
17  protected float m_fMinSlope, m_fMaxSlope;
18 
19  //------------------------------------------------------------------------------------------------
20  bool IsClosed()
21  {
22  return m_bIsClosed;
23  }
24 
25  //------------------------------------------------------------------------------------------------
26  bool IsSpline()
27  {
28  return m_bIsSpline;
29  }
30 
31  //------------------------------------------------------------------------------------------------
32  array<ref SCR_Ray> GetPoints()
33  {
34  array<ref SCR_Ray> result = {};
35  foreach (SCR_Ray point : m_aAnchorRays)
36  {
37  result.Insert(point);
38  }
39  return result;
40  }
41 
42  //------------------------------------------------------------------------------------------------
43  array<ref SCR_Ray> GetMiddlePoints()
44  {
45  array<ref SCR_Ray> result = {};
46  foreach (SCR_Ray point : m_aMidPointRays)
47  {
48  result.Insert(point);
49  }
50  return result;
51  }
52 
53  //------------------------------------------------------------------------------------------------
54  array<ref SCR_Ray> GetTesselatedPoints()
55  {
56  array<ref SCR_Ray> result = {};
57  foreach (SCR_Ray point : m_aTesselatedPointRays)
58  {
59  result.Insert(point);
60  }
61  return result;
62  }
63 
64  //------------------------------------------------------------------------------------------------
67  array<float> GetStats()
68  {
69  return { m_fLength2D, m_fLength3D, m_fSurface, m_fMinAltitude, m_fMaxAltitude, m_fMinSlope, m_fMaxSlope };
70  }
71 
72  //------------------------------------------------------------------------------------------------
73  // constructor
75  void SCR_ShapeAnalyser(notnull ShapeEntity shapeEntity, bool isClosed)
76  {
77  m_bIsSpline = SplineShapeEntity.Cast(shapeEntity) != null;
78 
79  vector origin = shapeEntity.GetOrigin();
80 
81  array<vector> points = {};
82  shapeEntity.GetPointsPositions(points);
83 
84  int pointsCount = points.Count();
85  if (pointsCount < 2)
86  return;
87 
88  array<vector> tesselatedPoints = {};
89  shapeEntity.GenerateTesselatedShape(tesselatedPoints);
90 
91  m_aAnchorRays = {};
92  m_aTesselatedPointRays = {};
93 
94  vector prevPoint, diff;
95  vector prevTessPoint, currTessPoint;
96  vector currPoint = points[0];
97  int pointIndex;
98 
99  array<int> pointTesselatedIndices = {};
100 
101  // stats
102  array<float> polygon2D = {};
103  m_fMinAltitude = currPoint[1];
104  m_fMaxAltitude = currPoint[1];
105  m_fMinSlope = float.INFINITY;
106  m_fMaxSlope = -float.INFINITY;
107 
108  for (int i, count = tesselatedPoints.Count(); i < count; i++)
109  {
110  currTessPoint = tesselatedPoints[i];
111 
112  if (i == 0)
113  diff = tesselatedPoints[1] - currTessPoint;
114  else
115  diff = currTessPoint - prevTessPoint;
116 
117  SCR_Ray point = new SCR_Ray();
118  point.m_vPosition = origin + currTessPoint;
119 
120  float slopeRad = Math.Atan2(diff[1], vector.DistanceXZ(diff, vector.Zero));
121 
122  if (i == 0) // first
123  point.m_vDirection = (tesselatedPoints[i + 1] - currTessPoint).Normalized();
124  else if (i < count - 1) // mid-curve - averages previous and next vector
125  point.m_vDirection = (0.5 * ((currTessPoint - prevTessPoint) + (tesselatedPoints[i + 1] - currTessPoint))).Normalized();
126  // (float.AlmostEqual) equivalent to
127  // point.m_vDirection = vector.Lerp(currTessPoint - prevTessPoint, tesselatedPoints[i + 1] - currTessPoint, 0.5).Normalized();
128  else // last
129  point.m_vDirection = (currTessPoint - prevTessPoint).Normalized();
130 
131  m_aTesselatedPointRays.Insert(point);
132 
133  if (currTessPoint == currPoint)
134  {
135  pointTesselatedIndices.Insert(i);
136  m_aAnchorRays.Insert(point);
137 
138  pointIndex++;
139  if (pointIndex >= pointsCount)
140  pointIndex = 0;
141 
142  prevPoint = currPoint;
143  currPoint = points[pointIndex];
144  }
145 
146  // stats
147  if (prevTessPoint)
148  {
149  m_fLength2D += vector.DistanceXZ(prevTessPoint, currTessPoint);
150  m_fLength3D += vector.Distance(prevTessPoint, currTessPoint);
151  }
152 
153  if (point.m_vPosition[1] < m_fMinAltitude)
154  m_fMinAltitude = point.m_vPosition[1];
155 
156  if (point.m_vPosition[1] > m_fMaxAltitude)
157  m_fMaxAltitude = point.m_vPosition[1];
158 
159  if (slopeRad < m_fMinSlope)
160  m_fMinSlope = slopeRad;
161 
162  if (slopeRad > m_fMaxSlope)
163  m_fMaxSlope = slopeRad;
164 
165  polygon2D.Insert(point.m_vPosition[0]);
166  polygon2D.Insert(point.m_vPosition[2]);
167 
168  // loop
169  prevTessPoint = currTessPoint;
170  }
171 
172  m_aMidPointRays = {};
173  if (m_bIsSpline) // take the middle point
174  {
175  int prevIndex = pointTesselatedIndices[0];
176  int nextIndex;
177  for (int i = 1, count = pointTesselatedIndices.Count(); i < count; i++)
178  {
179  nextIndex = pointTesselatedIndices[i];
180  m_aMidPointRays.Insert(m_aTesselatedPointRays[prevIndex + 0.5 * (nextIndex - prevIndex)]);
181  prevIndex = nextIndex;
182  }
183  }
184  else
185  {
186  SCR_Ray currRay = m_aAnchorRays[0];
187  SCR_Ray nextRay;
188  for (int i = 1, count = m_aAnchorRays.Count(); i < count; i++) // start from 1
189  {
190  nextRay = m_aAnchorRays[i];
191  m_aMidPointRays.Insert(SCR_Ray.Lerp(currRay, nextRay, 0.5));
192  currRay = nextRay;
193  }
194 
195  if (m_bIsClosed)
196  m_aMidPointRays.Insert(SCR_Ray.Lerp(currRay, m_aAnchorRays[0], 0.5));
197  }
198 
199  m_fSurface = SCR_Math2D.GetPolygonArea(polygon2D); // closed or not
200  }
201 }
SCR_ShapeAnalyser
Definition: SCR_ShapeAnalyser.c:3
SCR_Ray
Definition: SCR_Ray.c:1