Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
PrefabGeneratorEntity.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameLib/Scripted/Generator", description: "PrefabGeneratorEntity", dynamicBox: true, visible: false)]
3 {
4 }
5 
6 class PrefabGeneratorEntity : SCR_GeneratorBaseEntity // TODO: make it use SCR_ObstacleDetector
7 {
8  /*
9  Prefabs
10  */
11 
12  [Attribute(category: "Prefabs", uiwidget: UIWidgets.ResourcePickerThumbnail, desc: "Prefab list", params: "et")]
13  protected ref array<ResourceName> m_PrefabNames; // m_a
14 
15  [Attribute(category: "Prefabs", desc: "Weights", params: "et")]
16  protected ref array<float> m_Weights; // m_a
17 
18  [Attribute(category: "Prefabs", desc: "If checked prefabs are placed only to vertices")]
19  protected bool m_bOnlyToVertices;
20 
21  [Attribute(category: "Prefabs", defvalue: "5", desc: "Distance between spawned assets along the spline/polyline")]
22  protected float m_fDistance;
23 
24  [Attribute(category: "Prefabs", defvalue: "1", desc: "If checked prefabs are aligned with the shape")]
25  protected bool m_bAlignWithShape;
26 
27  [Attribute(category: "Prefabs", desc: "Only when aligning with shape")]
28  protected bool m_bUseXAsForward;
29 
30  [Attribute(category: "Prefabs", desc: "Flip forward")]
31  protected bool m_bFlipForward;
32 
33  /*
34  Offset
35  */
36 
37  [Attribute(category: "Offset", desc: "How much we offset from center to the side")]
38  protected float m_fOffsetRight;
39 
40  [Attribute(category: "Offset", desc: "How much offset variability we want in meters when using offset from the center")]
41  protected float m_fOffsetVariance;
42 
43  [Attribute(category: "Offset", desc: UIWidgets.EditBox, "Gap from the centerline")]
44  protected float m_fGap;
45 
46  [Attribute(category: "Offset", desc: "Random Spacing Offset")]
47  protected bool m_fRandomSpacing; // m_b
48 
49  [Attribute(category: "Offset", desc: "How much we offset in world up vector")]
50  protected float m_fOffsetUp;
51 
52  [Attribute(category: "Offset", desc: "Forward offset")]
53  protected float m_fOffsetForward;
54 
55  /*
56  Perlin
57  */
58 
59  [Attribute(category: "Perlin", desc: "Prefab spawn density uses Perlin distribution")]
60  protected bool m_bPerlinDens;
61 
62  [Attribute(category: "Perlin", desc: "Spawns prefabs if perlin value is above this threshold", "-1 1")]
63  protected float m_fPerlinThreshold;
64 
65  [Attribute(desc: "Prefab spawn type uses Perlin distribution. Prefabs in the prefab array are stacked up from lower to higher indicies on the Y axis")]
67 
68  [Attribute(desc: "Prefab size uses Perlin")]
69  protected bool m_bPerlinSize;
70 
71  [Attribute(category: "Perlin", defvalue: "40", desc: "Perlin frequency, higher values mean smoother transitions")]
72  protected float m_fPerlinFrequency;
73 
74  [Attribute(category: "Perlin", desc: "Perlin seed", params: "0 1000")]
75  protected float m_fPerlinSeed;
76 
77  [Attribute(category: "Perlin", defvalue: "1", desc: "Perlin Amplitude")]
78  protected float m_fPerlinAmplitude;
79 
80  [Attribute(category: "Perlin", desc: "Perlin Phase Offset")]
81  protected float m_fPerlinOffset;
82 
83  [Attribute(category: "Perlin", desc: "Disables asset generation bellow perlin threshold")]
84  protected bool m_fPerlinThrowAway; // m_b
85 
86  [Attribute(category: "Debug", desc: "Draw developer debug")]
87  protected bool m_bDrawDebug;
88 
89 #ifdef WORKBENCH
90 
91  protected ref array<ref SCR_PrefabGeneratorAssetPoint> m_aPoints = {};
92 
93  protected static ref array<ref Shape> s_aDebugShapes = {};
94 
95  //------------------------------------------------------------------------------------------------
96  protected override bool _WB_OnKeyChanged(BaseContainer src, string key, BaseContainerList ownerContainers, IEntity parent)
97  {
98  super._WB_OnKeyChanged(src, key, ownerContainers, parent);
99 
100  if (key == "coords")
101  return false;
102 
103  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
104  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
105  return false;
106 
107  IEntitySource entSrc = src.ToEntitySource();
108 
109  IEntitySource thisSrc = worldEditorAPI.EntityToSource(this);
110  IEntitySource parentSrc = thisSrc.GetParent();
111  BaseContainerTools.WriteToInstance(this, thisSrc);
112 
113  OnShapeChanged(parentSrc, ShapeEntity.Cast(parent), {}, {});
114  return true;
115  }
116 
117  //------------------------------------------------------------------------------------------------
118  protected vector GetPos(BaseContainerList points, int i)
119  {
120  BaseContainer point = points.Get(i);
121  vector pos;
122  point.Get("Position", pos);
123  return pos;
124  }
125 
126  //------------------------------------------------------------------------------------------------
127  protected override void OnShapeInitInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity)
128  {
129  super.OnShapeInitInternal(shapeEntitySrc, shapeEntity);
130 
131  if (!shapeEntity)
132  shapeEntity = ShapeEntity.Cast(_WB_GetEditorAPI().SourceToEntity(shapeEntitySrc));
133 
134  OnShapeChanged(shapeEntitySrc, shapeEntity, {}, {});
135  }
136 
137  //------------------------------------------------------------------------------------------------
139  protected void OffsetPointsMeta(notnull array<ref SCR_PrefabGeneratorPointMeta> metas, float offset)
140  {
141  array<ref SCR_PrefabGeneratorPointMeta> metasTemp = {};
142 
144  foreach (SCR_PrefabGeneratorPointMeta meta : metas)
145  {
146  tmpMeta = new SCR_PrefabGeneratorPointMeta();
147  tmpMeta.m_vPos = meta.m_vPos;
148  tmpMeta.m_bGenerate = meta.m_bGenerate;
149  metasTemp.Insert(tmpMeta);
150  }
151 
152  vector matWorld[4];
153  if (m_bDrawDebug)
154  GetWorldTransform(matWorld);
155 
156  vector forwardPrev = "1 1 1";
157  for (int i, count = metas.Count(); i < count; i++)
158  {
159  vector forwardNext;
160 
161  if (i < count - 1)
162  forwardNext = metas.Get(i + 1).m_vPos - metas.Get(i).m_vPos;
163  else
164  forwardNext = -forwardPrev;
165 
166  if (i == 0)
167  forwardPrev = -forwardNext;
168 
169  forwardNext.Normalize();
170  forwardPrev.Normalize();
171 
172  float dotProductPrevNext = vector.Dot(forwardPrev, forwardNext);
173  bool almostLine = dotProductPrevNext < -0.95;
174  vector diagonal = forwardNext + forwardPrev;
175 
176  vector normalRight = -forwardPrev * "0 1 0";
177  normalRight.Normalize();
178  float dotProductNormNext = vector.Dot(normalRight, forwardNext);
179  bool isLeft = dotProductNormNext > 0;
180 
181  vector nextModified = dotProductPrevNext * forwardNext;
182  float dist = vector.Distance(nextModified, forwardPrev);
183  float diff;
184  if (dist !=0)
185  diff = offset / dist;
186 
187  diagonal *= diff;
188 
189  if (!isLeft)
190  diagonal = diagonal * -1;
191 
192  if (almostLine)
193  {
194  vector vec = forwardNext - forwardPrev;
195  vector right = vec * "0 1 0";
196  right.Normalize();
197  diagonal = right * offset;
198  }
199 
200  metas.Get(i).m_vPos = metasTemp.Get(i).m_vPos + diagonal;
201  forwardPrev = -forwardNext;
202 
203  // debug
204  if (m_bDrawDebug)
205  {
206  diagonal = metas[i].m_vPos.Multiply4(matWorld); // variable reuse
207  s_aDebugShapes.Insert(Shape.Create(ShapeType.LINE, ARGB(255, 255, 255, 255), ShapeFlags.NOZBUFFER, diagonal, diagonal + forwardNext));
208  s_aDebugShapes.Insert(Shape.Create(ShapeType.LINE, ARGB(255, 0, 255, 0), ShapeFlags.NOZBUFFER, diagonal, diagonal + forwardPrev));
209  s_aDebugShapes.Insert(Shape.Create(ShapeType.LINE, ARGB(255, 255, 0, 0), ShapeFlags.NOZBUFFER, metasTemp[i].m_vPos.Multiply4(matWorld), diagonal));
210  }
211  }
212  }
213 
214  //------------------------------------------------------------------------------------------------
216  protected float SamplePerlin(float time, float frequency = 20, float seed = 1, float amplitude = 1, float phaseOffset = 0)
217  {
218  if (frequency == 0 || amplitude == 0) // division/multiplication by zero protection
219  return 0;
220 
221  return Math.PerlinNoise(time / frequency, seed * 100, seed * 1000) * amplitude;
222  }
223 
224  //------------------------------------------------------------------------------------------------
226  protected void GenerateAssetPoints(array<ref SCR_PrefabGeneratorPointMeta> metas)
227  {
228  float stepDistance = m_fDistance;
229 
230  if (m_bPerlinDens)
231  stepDistance = 0.01; // TODO:make constant
232 
233  float distanceWalked = 0;
234  if (m_fOffsetForward)
235  stepDistance = m_fOffsetForward;
236 
237  float space = 0;
238  float moveDist = 0;
239  vector lastPos = "0 0 0";
240  bool firstPoint = true;
241  bool draw = true;
242 
243  for (int i = 0, countMinusOne = metas.Count() - 1; i < countMinusOne; i++)
244  {
245  vector posThis = metas[i].m_vPos;
246  //Print(posThis);
247  lastPos = posThis;
248  vector forward = metas[i + 1].m_vPos - posThis;
249  float dist = forward.Length();
250  space += dist;
251 
252  // check for disabled generation on line segment
253  draw = metas.Get(i).m_bGenerate;
255 
256  while (space >= stepDistance)
257  {
258  float leftOver = space - dist;
259  if (leftOver < 0)
260  leftOver = 0;
261 
262  if (firstPoint)
263  {
264  moveDist = 0;
265  stepDistance = 0;
266  firstPoint = false;
267  if (m_fOffsetForward)
268  {
269  stepDistance = m_fOffsetForward;
270  moveDist = dist - (space - stepDistance);
271  }
272  }
273  else
274  {
275  stepDistance = m_fDistance;
276 
277  if (m_fRandomSpacing)
278  {
279  stepDistance = m_fDistance + Math.RandomFloat(-m_fDistance * 0.5, m_fDistance * 0.5);
280  if (leftOver> stepDistance)
281  leftOver = 0;
282  }
283 
284  moveDist = stepDistance - leftOver;
285  }
286 
287  space -= moveDist + leftOver;
288  distanceWalked += stepDistance;
289  vector newPos;
290  float valuePerlin = SamplePerlin(distanceWalked + m_fPerlinOffset, m_fPerlinFrequency, m_fPerlinSeed, m_fPerlinAmplitude);
291 
292  newPos = lastPos + forward.Normalized() * moveDist;
293  lastPos = newPos;
294  genPoint = new SCR_PrefabGeneratorAssetPoint();
295  genPoint.m_vPos = newPos;
296  genPoint.m_vForward = forward;
297  genPoint.m_fPerlinWeight = valuePerlin;
298 
299  if (m_bPerlinDens)
300  {
301  float invValue = Math.InverseLerp(m_fPerlinThreshold, 1, valuePerlin);
302  invValue = Math.Clamp(invValue, 0, 1);
303  stepDistance = Math.Lerp(m_fDistance, 1, invValue); // TODO: expose values
304  }
305 
306  bool throwAway = false;
307  if (m_fPerlinThrowAway)
308  {
309  if (valuePerlin < m_fPerlinThreshold)
310  {
311  stepDistance = 0.01;
312  throwAway = true;
313  }
314  }
315 
316  genPoint.m_bDraw = draw && !throwAway;
317  m_aPoints.Insert(genPoint);
318  }
319  }
320  }
321 
322  //------------------------------------------------------------------------------------------------
323  protected void GenerateMetaListLine(notnull BaseContainerList points, notnull out array<ref SCR_PrefabGeneratorPointMeta> pointsMeta)
324  {
325  BaseContainerList dataArr;
326  BaseContainer data;
328  typename pointDataTypename;
329  for (int i = 0, count = points.Count(); i < count; i++)
330  {
331  data = points.Get(i);
332  dataArr = data.GetObjectArray("Data");
333  bool generate = true;
334  vector pos;
335  data.Get("Position", pos);
336 
337  if (dataArr)
338  {
339  for (int j = 0, dataCount = dataArr.Count(); j < dataCount; j++)
340  {
341  data = dataArr.Get(j); // variable reuse
342  pointDataTypename = data.GetClassName().ToType();
343  if (pointDataTypename && pointDataTypename.IsInherited(PrefabGeneratorPointData))
344  {
345  if (data.Get("m_bGenerate", generate))
346  break;
347  }
348  }
349  }
350 
351  meta = new SCR_PrefabGeneratorPointMeta();
352  meta.m_bGenerate = generate;
353  meta.m_vPos = pos;
354  pointsMeta.Insert(meta);
355  }
356  }
357 
358  //------------------------------------------------------------------------------------------------
359  protected void GenerateMetaListSpline(array<ref SCR_PrefabGeneratorPointMeta> pointsMetaLine, array<vector> tesselatedPoints, array<ref SCR_PrefabGeneratorPointMeta> pointsMetaSpline)
360  {
361  if (!tesselatedPoints)
362  return;
363 
364  bool generate = true;
366  foreach (vector tesselatedPoint : tesselatedPoints)
367  {
368  foreach (SCR_PrefabGeneratorPointMeta meta : pointsMetaLine)
369  {
370  if (tesselatedPoint == meta.m_vPos) // matching point on the spline with a point on the polyline to ascertain whether asset generation is disabled in point data or not for this segment
371  {
372  generate = meta.m_bGenerate;
373  break;
374  }
375  }
376 
377  tmpMeta = new SCR_PrefabGeneratorPointMeta();
378  tmpMeta.m_bGenerate = generate;
379  tmpMeta.m_vPos = tesselatedPoint;
380  pointsMetaSpline.Insert(tmpMeta);
381  }
382  }
383 
384  //------------------------------------------------------------------------------------------------
385  protected override void OnShapeChangedInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity, array<vector> mins, array<vector> maxes)
386  {
387  s_aDebugShapes.Clear();
388  m_aPoints.Clear();
389 
390  if (!shapeEntitySrc)
391  return;
392 
393  BaseContainerList points = shapeEntitySrc.GetObjectArray("Points");
394  if (points != null)
395  {
396  array<ref SCR_PrefabGeneratorPointMeta> pointsMetaLine = {};
397  GenerateMetaListLine(points, pointsMetaLine);
398 
399  int pointCount = points.Count();
400  if (pointCount == 0)
401  return;
402 
403  bool isShapeClosed;
404  shapeEntitySrc.Get("IsClosed", isShapeClosed);
405 
406  if (pointCount > 2 && isShapeClosed)
407  pointsMetaLine.Insert(pointsMetaLine[0]);
408 
409  if (m_fOffsetRight != 0)
410  OffsetPointsMeta(pointsMetaLine, m_fOffsetRight);
411 
412  typename shapeTypename = shapeEntitySrc.GetClassName().ToType();
413  if (!m_bOnlyToVertices && m_fDistance > 0 && shapeTypename && shapeTypename.IsInherited(PolylineShapeEntity))
414  {
415  GenerateAssetPoints(pointsMetaLine);
416  if (m_bDrawDebug)
417  DrawCurveDebug(pointsMetaLine);
418  }
419  else if (!m_bOnlyToVertices && m_fDistance > 0 && shapeTypename && shapeTypename.IsInherited(SplineShapeEntity))
420  {
421  array<vector> pointsCurve = {};
422  shapeEntity.GenerateTesselatedShape(pointsCurve);
423 
424  array<ref SCR_PrefabGeneratorPointMeta> pointsMetaSpline = {};
425 
426  GenerateMetaListSpline(pointsMetaLine, pointsCurve, pointsMetaSpline);
427 
428  if (pointCount > 2 && isShapeClosed)
429  pointsMetaSpline.Insert(pointsMetaSpline[0]);
430 
431  if (m_fOffsetRight != 0)
432  OffsetPointsMeta(pointsMetaSpline, m_fOffsetRight);
433 
434  GenerateAssetPoints(pointsMetaSpline);
435 
436  if (m_bDrawDebug)
437  DrawCurveDebug(pointsMetaSpline);
438  }
439  else if (m_bOnlyToVertices)
440  {
441  if (m_bDrawDebug)
442  DrawCurveDebug(pointsMetaLine);
443 
444  // First point special care
446  genPoint.m_vPos = pointsMetaLine[0].m_vPos;
447 
448  if (pointsMetaLine)
449  genPoint.m_bDraw = pointsMetaLine.Get(0).m_bGenerate;
450 
451  if (isShapeClosed && pointCount > 2)
452  genPoint.m_vForward = pointsMetaLine[1].m_vPos - pointsMetaLine[pointCount - 1].m_vPos.Normalized();
453  else if (pointCount > 1)
454  genPoint.m_vForward = (pointsMetaLine[1].m_vPos - pointsMetaLine[0].m_vPos).Normalized();
455 
456  m_aPoints.Insert(genPoint);
457 
458  // Middle points
459  for (int i = 1, count = pointsMetaLine.Count(); i < count; i++)
460  {
461  genPoint = new SCR_PrefabGeneratorAssetPoint();
462  genPoint.m_vPos = pointsMetaLine[i % pointCount].m_vPos;
463 
464  genPoint.m_bDraw = pointsMetaLine.Get(i).m_bGenerate;
465 
466  if (i < count - 1 || isShapeClosed)
467  genPoint.m_vForward = (pointsMetaLine[(i + 1) % pointCount].m_vPos - pointsMetaLine[i - 1].m_vPos).Normalized();
468  else if (i == count - 1)
469  genPoint.m_vForward = (pointsMetaLine[i % pointCount].m_vPos - pointsMetaLine[i - 1].m_vPos).Normalized();
470 
471  m_aPoints.Insert(genPoint);
472  }
473  }
474  else
475  {
476  return;
477  }
478  }
479 
480  Generate();
481  }
482 
483  //------------------------------------------------------------------------------------------------
485  protected void Generate()
486  {
487  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
488  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
489  return;
490 
491  bool hasOneFilledPrefab;
492  foreach (ResourceName prefabName : m_PrefabNames)
493  {
494  if (!prefabName.IsEmpty())
495  {
496  hasOneFilledPrefab = true;
497  break;
498  }
499  }
500 
501  if (!hasOneFilledPrefab)
502  return;
503 
504  IEntitySource entSrc = worldEditorAPI.EntityToSource(this);
505 
506  for (int i = entSrc.GetNumChildren() - 1; i >= 0; --i)
507  {
508  worldEditorAPI.DeleteEntity(entSrc.GetChild(i));
509  }
510 
511  bool isGeneratorVisible = worldEditorAPI.IsEntityVisible(entSrc);
512  vector worldMat[4];
513  GetWorldTransform(worldMat);
514  BaseContainerList editorData;
515 
516  foreach (SCR_PrefabGeneratorAssetPoint localPoint : m_aPoints)
517  {
518  if (!localPoint.m_bDraw)
519  continue;
520 
521  vector worldPos = localPoint.m_vPos.Multiply4(worldMat);
522 
523  vector rot;
524  vector mat[4];
525  Math3D.DirectionAndUpMatrix(localPoint.m_vForward, vector.Up, mat);
526  vector right = mat[0];
527  vector angles = Math3D.MatrixToAngles(mat);
528 
529  if (m_fOffsetVariance != 0)
530  {
531  float offsetRandom = Math.RandomFloat(-m_fOffsetVariance * 0.5 + m_fGap * 0.5, m_fOffsetVariance * 0.5 - m_fGap * 0.5);
532  if (offsetRandom < 0)
533  offsetRandom -= m_fGap * 0.5;
534  else
535  offsetRandom += m_fGap * 0.5;
536 
537  worldPos = worldPos + offsetRandom * right;
538  }
539 
540  if (m_bAlignWithShape)
541  {
542  if (m_bUseXAsForward)
543  angles[0] = angles[0] - 90;
544 
545  if (m_bFlipForward)
546  angles[0] = angles[0] + 180;
547 
548  rot = { angles[1], angles[0], angles[2] };
549  }
550 
551  int index;
552 
554  {
555  float value = Math.Clamp(localPoint.m_fPerlinWeight, m_fPerlinThreshold, 1);
556  float invValue = Math.InverseLerp(m_fPerlinThreshold, 1, value);
557 
558  index = Math.Clamp(SCR_ArrayHelper.GetWeightedIndex(m_Weights, invValue), 0, m_PrefabNames.Count() - 1);
559  }
560  else
561  {
562  index = Math.Clamp(SCR_ArrayHelper.GetWeightedIndex(m_Weights, Math.RandomFloat01()), 0, m_PrefabNames.Count() - 1);
563  }
564 
565  string asset = m_PrefabNames[index];
566 
567  IEntitySource src = worldEditorAPI.CreateEntityExt(asset, "", 0, null, worldPos, rot, TraceFlags.WORLD);
568 
569  if (m_bPerlinSize)
570  {
571  editorData = src.GetObjectArray("editorData");
572 
573  if (editorData && editorData.Count() > 0)
574  {
575  float valuePrln = Math.Clamp(localPoint.m_fPerlinWeight, m_fPerlinThreshold, 1);
576  //Print("raw perlin:" +localPoint.m_fPerlinWeight);
577  float invValue = Math.InverseLerp(m_fPerlinThreshold, 1, valuePrln);
578  vector val;
579  editorData.Get(0).Get("randomScale", val);
580 
581  string scale = (Math.Lerp(val[0], val[1], invValue)).ToString();
582  worldEditorAPI.SetVariableValue(src, null, "scale", scale);
583  }
584  }
585 
586  if (m_fOffsetUp != 0)
587  {
588  vector entPos;
589  src.Get("coords", entPos);
590  entPos[1] = entPos[1] + m_fOffsetUp;
591  string coords = entPos[0].ToString() + " " + entPos[1].ToString() + " " + entPos[2].ToString();
592  worldEditorAPI.SetVariableValue(src, null, "coords", coords);
593  }
594 
595  worldEditorAPI.SetEntityVisible(src, isGeneratorVisible, false);
596  worldEditorAPI.ParentEntity(entSrc, src, true);
597  }
598  }
599 
600  //------------------------------------------------------------------------------------------------
602  protected void DrawCurveDebug(array<ref SCR_PrefabGeneratorPointMeta> metas)
603  {
604  const int DEBUG_CURVE_LINE_SIZE = 8192;
605  const float DEBUG_Y_MULTIPLIER = 5;
606  static vector m_PerlinDebugLine[DEBUG_CURVE_LINE_SIZE];
607  static vector m_ZeroDebugLine[DEBUG_CURVE_LINE_SIZE];
608  static vector m_EdgeDebugLine[DEBUG_CURVE_LINE_SIZE];
609  static vector m_ThresholdDebugLine[DEBUG_CURVE_LINE_SIZE];
610 
611  float stepDistance = 0.1;
612  float distanceWalked = 0;
613  vector lastPos = "0 0 0";
614  float space = 0;
615  float moveDist = 0;
616 
617  array<vector> line = {};
618  int itemsNum = 0;
619 
620  vector matWrld[4];
621  GetWorldTransform(matWrld);
622 
623  int i = 0;
624  for (int countMinusOne = metas.Count() - 1; i < countMinusOne; i++)
625  {
626  vector posThis = metas[i].m_vPos;
627  lastPos = posThis;
628  vector forward = metas[i + 1].m_vPos - posThis;
629  float dist = forward.Length();
630  space += dist;
631 
632  m_ZeroDebugLine[i] = posThis.Multiply4(matWrld);
633 
634  if (i == countMinusOne - 1)
635  m_ZeroDebugLine[i + 1] = metas[i + 1].m_vPos.Multiply4(matWrld);
636 
637  while (space >= stepDistance)
638  {
639  float leftOver = space - dist;
640  if (leftOver < 0)
641  leftOver = 0;
642 
643  moveDist = stepDistance - leftOver;
644 
645  space -= moveDist + leftOver;
646  distanceWalked += stepDistance;
647  vector stepPos;
648  vector perlinPointPos;
649 
650  stepPos = lastPos + forward.Normalized() * moveDist;
651  lastPos = stepPos;
652 
653  vector mat[4];
654  vector up = {0, 1, 0};
655  Math3D.DirectionAndUpMatrix(forward, up, mat);
656  vector right = mat[0];
657 
658  float valuePerlin = SamplePerlin(distanceWalked + m_fPerlinOffset, m_fPerlinFrequency, m_fPerlinSeed, m_fPerlinAmplitude);
659  //Print(distanceWalked);
660  //Print(valuePerlin);
661  perlinPointPos = stepPos + right * valuePerlin * DEBUG_Y_MULTIPLIER;
662 
663  if (itemsNum < DEBUG_CURVE_LINE_SIZE)
664  {
665  m_PerlinDebugLine[itemsNum] = perlinPointPos.Multiply4(matWrld);
666  m_EdgeDebugLine[itemsNum] = (stepPos + right * DEBUG_Y_MULTIPLIER).Multiply4(matWrld);
667  m_ThresholdDebugLine[itemsNum] = (stepPos + right * DEBUG_Y_MULTIPLIER * m_fPerlinThreshold).Multiply4(matWrld);
668  itemsNum++;
669  }
670  }
671  }
672 
673  s_aDebugShapes.Insert(Shape.CreateLines(ARGB(255, 255, 255, 0), ShapeFlags.NOZBUFFER, m_PerlinDebugLine, itemsNum));
674  s_aDebugShapes.Insert(Shape.CreateLines(ARGB(255, 0, 255, 0), ShapeFlags.NOZBUFFER, m_ZeroDebugLine, i+ 1));
675  s_aDebugShapes.Insert(Shape.CreateLines(ARGB(255, 255, 0, 0), ShapeFlags.NOZBUFFER, m_EdgeDebugLine, itemsNum));
676  s_aDebugShapes.Insert(Shape.CreateLines(ARGB(255, 0, 0, 255), ShapeFlags.NOZBUFFER, m_ThresholdDebugLine, itemsNum));
677  }
678 
679  //------------------------------------------------------------------------------------------------
681  // unused
682  protected void PerlinDebug()
683  {
684  string filePath = "d:\\test.dds";
685  array<int> data = {};
686 
687  const int WIDTH = 1024;
688  const int HEIGHT = 1024;
689 
690  for (int y = 0; y < HEIGHT; y++)
691  {
692  for (int x = 0; x < WIDTH; x++)
693  {
694  int count = x * y;
695 
696  float perlinVal = Math.PerlinNoise(x / m_fPerlinFrequency, y / m_fPerlinFrequency);
697  //Print(perlinVal);
698 
699  int pixel = ARGB(255, perlinVal * 255, perlinVal * 255, perlinVal * 255);
700  data.Insert(pixel);
701  }
702  }
703 
704  // save dds to file
705  if (!TexTools.SaveImageData(filePath, WIDTH, HEIGHT, data))
706  {
707  //Print("Can't save image", LogLevel.ERROR);
708  return;
709  }
710  }
711 
712 #endif // WORKBENCH
713 
714  //------------------------------------------------------------------------------------------------
715  // constructor
716  protected void PrefabGeneratorEntity(IEntitySource src, IEntity parent)
717  {
718  }
719 }
m_fGap
protected float m_fGap
Definition: PrefabGeneratorEntity.c:44
m_fPerlinSeed
protected float m_fPerlinSeed
Definition: PrefabGeneratorEntity.c:75
SCR_GeneratorBaseEntity
SCR_GeneratorBaseEntityClass GeneratorBaseEntityClass SCR_GeneratorBaseEntity(IEntitySource src, IEntity parent)
Definition: SCR_GeneratorBaseEntity.c:335
m_fPerlinOffset
protected float m_fPerlinOffset
Definition: PrefabGeneratorEntity.c:81
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
m_fOffsetForward
protected float m_fOffsetForward
Definition: PrefabGeneratorEntity.c:53
m_bPerlinDens
protected bool m_bPerlinDens
Definition: PrefabGeneratorEntity.c:60
SCR_ArrayHelper
Definition: SCR_ArrayHelper.c:1
SCR_PrefabGeneratorAssetPoint
Definition: SCR_PrefabGeneratorAssetPoint.c:1
PrefabGeneratorEntityClass
Definition: PrefabGeneratorEntity.c:2
m_fOffsetUp
protected float m_fOffsetUp
Definition: PrefabGeneratorEntity.c:50
m_bPerlinSize
protected bool m_bPerlinSize
Definition: PrefabGeneratorEntity.c:69
m_fRandomSpacing
protected bool m_fRandomSpacing
Definition: PrefabGeneratorEntity.c:47
SCR_PrefabGeneratorPointMeta
Definition: SCR_PrefabGeneratorPointMeta.c:1
HEIGHT
@ HEIGHT
Definition: SCR_HUDSizeCalculator.c:3
m_fDistance
protected float m_fDistance
Definition: PrefabGeneratorEntity.c:22
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
Attribute
PrefabGeneratorEntityClass SCR_GeneratorBaseEntityClass Attribute(category:"Prefabs", uiwidget:UIWidgets.ResourcePickerThumbnail, desc:"Prefab list", params:"et")] protected ref array< ResourceName > m_PrefabNames
GetPos
override bool GetPos(out vector pos)
Definition: SCR_EditableFactionComponent.c:325
m_bUseXAsForward
protected bool m_bUseXAsForward
Definition: PrefabGeneratorEntity.c:28
m_fOffsetRight
protected float m_fOffsetRight
Definition: PrefabGeneratorEntity.c:38
PrefabGeneratorEntity
protected void PrefabGeneratorEntity(IEntitySource src, IEntity parent)
Definition: PrefabGeneratorEntity.c:716
m_fPerlinThreshold
protected float m_fPerlinThreshold
Definition: PrefabGeneratorEntity.c:63
m_bPerlinAssetDistribution
protected bool m_bPerlinAssetDistribution
Definition: PrefabGeneratorEntity.c:66
m_fPerlinAmplitude
protected float m_fPerlinAmplitude
Definition: PrefabGeneratorEntity.c:78
m_fOffsetVariance
protected float m_fOffsetVariance
Definition: PrefabGeneratorEntity.c:41
m_Weights
protected ref array< float > m_Weights
Definition: PrefabGeneratorEntity.c:16
PrefabGeneratorPointData
Definition: PrefabGeneratorPointData.c:1
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
m_bDrawDebug
protected bool m_bDrawDebug
Definition: PrefabGeneratorEntity.c:87
m_fPerlinFrequency
protected float m_fPerlinFrequency
Definition: PrefabGeneratorEntity.c:72
m_bAlignWithShape
protected bool m_bAlignWithShape
Definition: PrefabGeneratorEntity.c:25
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
WIDTH
@ WIDTH
Definition: SCR_HUDSizeCalculator.c:4
m_bOnlyToVertices
protected bool m_bOnlyToVertices
Definition: PrefabGeneratorEntity.c:19
m_bFlipForward
protected bool m_bFlipForward
Definition: PrefabGeneratorEntity.c:31
SCR_GeneratorBaseEntityClass
Definition: SCR_GeneratorBaseEntity.c:1
m_fPerlinThrowAway
protected bool m_fPerlinThrowAway
Definition: PrefabGeneratorEntity.c:84
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180