Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_ForestGeneratorOutlinePositionChecker.c
Go to the documentation of this file.
2 {
3  protected ref array<ref array<vector>> m_aOutlineSegments = {}; //<! points are 2D, format { X, 0, Z }
4  protected ref array<vector> m_aOutlineCentres = {};
5  protected ref array<float> m_aOutlineRadii = {}; // are you radii?
6  protected float m_fSetDistanceSq;
7 
8  //------------------------------------------------------------------------------------------------
12  bool IsPosDistanceEqualOrCloserThan(vector pos, float distance)
13  {
14  pos[1] = 0; // 2D conversion
15 
16  distance *= distance;
17  foreach (int i, array<vector> segment : m_aOutlineSegments)
18  {
19  if (Math3D.PointLineSegmentDistanceSqr(pos, segment[0], segment[1]) <= distance)
20  return true;
21  }
22 
23  return false;
24  }
25 
26  //------------------------------------------------------------------------------------------------
30  bool IsPosWithinSetDistance(vector pos)
31  {
32  pos[1] = 0; // 2D conversion
33 
34  foreach (int i, array<vector> segment : m_aOutlineSegments)
35  {
36  if (Math3D.PointLineSegmentDistanceSqr(pos, segment[0], segment[1]) <= m_fSetDistanceSq)
37  return true;
38  }
39 
40  return false;
41  }
42 
43  //------------------------------------------------------------------------------------------------
45  protected static array<float> GetOutlineDiffLines(notnull array<float> oldPoints, notnull array<float> newPoints)
46  {
47  // points can only be added one by one
48  // points can be deleted in group and non-sequentially (e.g delete point 1-5-6 out of 10)
49  // points can be moved in group and non-sequentially
50 
51  int oldCount = oldPoints.Count();
52  int newCount = newPoints.Count();
53 
54  if (newCount > oldCount)
55  return GetOutlineDiffLines_PointAdded(oldPoints, newPoints);
56 
57  if (newCount < oldCount)
58  return GetOutlineDiffLines_PointsRemoved(oldPoints, newPoints);
59 
60  return GetOutlineDiffLines_PointsMoved(oldPoints, newPoints);
61  }
62 
63  //------------------------------------------------------------------------------------------------
64  // wanted result:
65  // e.g points @ index 0, 2 and 3 are removed
66  // old: { x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6 }
67  // new: { x1, y1, x4, y4, x5, y5, x6, y6 }
68  // returns:
69  // result[0] { m1-p0-p1, m1-p2-p1, m1-p3-p1 }
70  // result[1] { m1-p1-p1, m1-p4-p1, m1-p6-p1 (because p0 removed) }
71  protected static array<float> GetOutlineDiffLines_PointsRemoved(notnull array<float> oldPoints, notnull array<float> newPoints)
72  {
73  int oldCount = oldPoints.Count();
74  int newCount = newPoints.Count();
75 
76  if (oldCount < 3)
77  return {};
78 
79  array<int> removedIndices = {};
80  array<int> relatedIndices = {};
81 
82  // first, get removed indices and related new indices
83  int indexOld;
84  for (int i; i < newCount; i += 2) // step 2
85  {
86  bool isRelated = false;
87 
88  for (; indexOld < oldCount; indexOld += 2)
89  {
90  if (newPoints[i] != oldPoints[indexOld] || newPoints[i + 1] != oldPoints[indexOld + 1])
91  {
92  removedIndices.Insert(indexOld * 0.5);
93  isRelated = true;
94  }
95  else
96  {
97  indexOld += 2;
98  break;
99  }
100  }
101 
102  if (isRelated)
103  relatedIndices.Insert(i * 0.5);
104  }
105 
106  if (indexOld < oldCount) // if there was more, add last and first point (if not already added)
107  {
108  if (!relatedIndices.Contains(0))
109  relatedIndices.Insert(0);
110 
111  if (!relatedIndices.Contains(newCount * 0.5 - 1))
112  relatedIndices.Insert(newCount * 0.5 - 1);
113  }
114 
115  array<float> tmp; // for ease of writing, otherwise linecount++++++
116 
117  array<float> result = {};
118  foreach (int removedIndex : removedIndices)
119  {
120  int floatIndex = removedIndex * 2;
121  if (floatIndex == 0)
122  {
123  tmp = {
124  oldPoints[oldCount - 2], oldPoints[oldCount - 1], oldPoints[0], oldPoints[1], // old-1 to oldPoint
125  oldPoints[0], oldPoints[1], oldPoints[2], oldPoints[3], // oldPoint to old+1
126  };
127  }
128  else if (floatIndex == oldCount - 2) // -2
129  {
130  tmp = {
131  oldPoints[oldCount - 4], oldPoints[oldCount - 3], oldPoints[oldCount - 2], oldPoints[oldCount - 1], // old-1 to oldPoint
132  oldPoints[oldCount - 2], oldPoints[oldCount - 1], oldPoints[0], oldPoints[1], // oldPoint to old+1
133  };
134  }
135  else
136  {
137  tmp = {
138  oldPoints[floatIndex - 2], oldPoints[floatIndex - 1], oldPoints[floatIndex], oldPoints[floatIndex + 1], // old-1 to oldPoint
139  oldPoints[floatIndex], oldPoints[floatIndex + 1], oldPoints[floatIndex + 2], oldPoints[floatIndex + 3], // oldPoint to old+1
140  };
141  }
142 
143  foreach (float value : tmp)
144  {
145  result.Insert(value);
146  }
147  }
148 
149  if (newCount > 2)
150  {
151  foreach (int relatedIndex : relatedIndices)
152  {
153  int floatIndex = relatedIndex * 2;
154  if (floatIndex == 0)
155  {
156  tmp = {
157  newPoints[newCount - 2], newPoints[newCount - 1], newPoints[0], newPoints[1], // old-1 to oldPoint
158  newPoints[0], newPoints[1], newPoints[2], newPoints[3], // oldPoint to old+1
159  };
160  }
161  else if (floatIndex == newCount - 2) // -2
162  {
163  tmp = {
164  newPoints[newCount - 4], newPoints[newCount - 3], newPoints[newCount - 2], newPoints[newCount - 1], // old-1 to oldPoint
165  newPoints[newCount - 2], newPoints[newCount - 1], newPoints[0], newPoints[1], // oldPoint to old+1
166  };
167  }
168  else
169  {
170  tmp = {
171  newPoints[floatIndex - 2], newPoints[floatIndex - 1], newPoints[floatIndex], newPoints[floatIndex + 1], // old-1 to oldPoint
172  newPoints[floatIndex], newPoints[floatIndex + 1], newPoints[floatIndex + 2], newPoints[floatIndex + 3], // oldPoint to old+1
173  };
174  }
175 
176  foreach (float value : tmp)
177  {
178  result.Insert(value);
179  }
180  }
181  }
182 
183  return result;
184  }
185 
186  //------------------------------------------------------------------------------------------------
188  protected static array<float> GetOutlineDiffLines_PointsMoved(notnull array<float> oldPoints, notnull array<float> newPoints)
189  {
190  // count is identical here
191  int count = oldPoints.Count();
192  if (count < 3)
193  return {};
194 
195  int lastIndex = count - 2;
196 
197  float prevOldPoint[2];
198  float currOldPoint[2];
199  float nextOldPoint[2];
200 
201  float prevNewPoint[2];
202  float currNewPoint[2];
203  float nextNewPoint[2];
204 
205  array<float> tmp; // for ease of writing, otherwise linecount++++++
206  array<float> result = {};
207  for (int i; i < count; i += 2) // step 2
208  {
209  if (oldPoints[i] != newPoints[i] || newPoints[i + 1] != newPoints[i + 1])
210  {
211  currOldPoint = { oldPoints[i], oldPoints[i + 1] };
212  currNewPoint = { newPoints[i], newPoints[i + 1] };
213 
214  if (i == 0) // first point
215  {
216  prevOldPoint = { oldPoints[lastIndex], oldPoints[lastIndex + 1] };
217  nextOldPoint = { oldPoints[i + 2], oldPoints[i + 3] };
218 
219  prevNewPoint = { newPoints[lastIndex], newPoints[lastIndex + 1] };
220  nextNewPoint = { newPoints[i + 2], newPoints[i + 3] };
221  }
222  else if (i == lastIndex) // last point
223  {
224  prevOldPoint = { oldPoints[i - 2], oldPoints[i - 1] };
225  nextOldPoint = { oldPoints[0], oldPoints[1] };
226 
227  prevNewPoint = { newPoints[i - 2], oldPoints[i - 1] };
228  nextNewPoint = { newPoints[0], oldPoints[1] };
229  }
230  else // normal point
231  {
232  prevOldPoint = { oldPoints[i - 2], oldPoints[i - 1] };
233  nextOldPoint = { oldPoints[i + 2], oldPoints[i + 3] };
234 
235  prevNewPoint = { newPoints[i - 2], oldPoints[i - 1] };
236  nextNewPoint = { newPoints[i + 2], newPoints[i + 3] };
237  }
238 
239  tmp = {
240  prevOldPoint[0], prevOldPoint[1], currOldPoint[0], currOldPoint[1], // old-1 to oldPoint
241  nextOldPoint[0], nextOldPoint[1], currOldPoint[0], currOldPoint[1], // old+1 to oldPoint
242 
243  prevNewPoint[0], prevNewPoint[1], currNewPoint[0], currNewPoint[1], // new-1 to newPoint
244  nextNewPoint[0], nextNewPoint[1], currNewPoint[0], currNewPoint[1], // new+1 to newPoint
245  };
246 
247  foreach (float value : tmp)
248  {
249  result.Insert(value);
250  }
251 /*
252  Print("moved {" +
253  currOldPoint[0] + ", " + currOldPoint[1] +
254  "} to {" +
255  currNewPoint[0] + ", " + currNewPoint[1] +
256  "}");
257 */
258  }
259  }
260 
261  return result;
262  }
263 
264  //------------------------------------------------------------------------------------------------
266  protected static array<float> GetOutlineDiffLines_PointAdded(notnull array<float> oldPoints, notnull array<float> newPoints)
267  {
268  int newCount = newPoints.Count();
269  if (newCount < 3)
270  return {};
271 
272  int oldCount = oldPoints.Count();
273  int index = -1;
274  for (int i; i < oldCount; i += 2) // step 2
275  {
276  if (oldPoints[i] != newPoints[i] || oldPoints[i + 1] != newPoints[i + 1])
277  {
278  index = i;
279  break;
280  }
281  }
282 
283  bool isLastPoint = false;
284  if (index == -1) // no difference found, it is then the last point
285  {
286  isLastPoint = true;
287  index = oldCount + 2;
288  }
289 
290  float newPoint[2] = { newPoints[index], newPoints[index + 1] };
291 
292  float prevPoint[2];
293  float nextPoint[2];
294 
295  if (index == 0) // first point - cannot happen in World Editor AFAIK
296  {
297  prevPoint = { oldPoints[oldCount - 2], oldPoints[oldCount - 1] };
298  nextPoint = { oldPoints[index + 2], oldPoints[index + 3] };
299  }
300  else if (isLastPoint) // last point
301  {
302  prevPoint = { newPoints[index - 2], oldPoints[index - 1] };
303  nextPoint = { oldPoints[0], oldPoints[1] };
304  }
305  else // normal point
306  {
307  prevPoint = { oldPoints[index - 2], oldPoints[index - 1] };
308  nextPoint = { oldPoints[index + 2], oldPoints[index + 3] };
309  }
310 
311  float oldPoint[2] = { // virtual middle of old segment
312  nextPoint[0] + 0.5 * (nextPoint[0] - prevPoint[0]),
313  nextPoint[1] + 0.5 * (nextPoint[1] - prevPoint[1]),
314  };
315 
316  return {
317  prevPoint[0], prevPoint[1], oldPoint[0], oldPoint[1], // p-1 to oldPoint
318  nextPoint[0], nextPoint[1], oldPoint[0], oldPoint[1], // p+1 to oldPoint
319 
320  prevPoint[0], prevPoint[1], newPoint[0], newPoint[1], // p-1 to newPoint
321  nextPoint[0], nextPoint[1], newPoint[0], newPoint[1], // p+1 to newPoint
322  };
323  }
324 
325  //------------------------------------------------------------------------------------------------
326  void SCR_ForestGeneratorOutlinePositionChecker(notnull array<float> oldPoints, notnull array<float> newPoints, float setDistance)
327  {
328  array<float> allOutlinePoints = GetOutlineDiffLines(oldPoints, newPoints);
329 
330  array<vector> segment; // cannot use vector segment[2] due to { xxx[i] } below
331  for (int i, count = allOutlinePoints.Count(); i < count; i += 4) // step 4
332  {
333  segment = {
334  { allOutlinePoints[i], 0, allOutlinePoints[i + 1] },
335  { allOutlinePoints[i + 2], 0, allOutlinePoints[i + 3] },
336  };
337 
338  m_aOutlineSegments.Insert(segment);
339  m_aOutlineCentres.Insert(vector.Lerp(segment[0], segment[1], 0.5));
340  m_aOutlineRadii.Insert(vector.DistanceXZ(segment[0], segment[1]) * 0.5);
341  }
342 
343  m_fSetDistanceSq = setDistance * setDistance;
344  }
345 }
SCR_ForestGeneratorOutlinePositionChecker
Definition: SCR_ForestGeneratorOutlinePositionChecker.c:1
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17