92 float currentSegmentIndex;
106 foreach (
int i, array<vector> segment :
m_aSegments)
114 doneLength +=
vector.Distance(segment[0], segment[1]);
129 bool GetNextPoint(
float distance, out
vector result,
int anchorLimit = -1,
bool straightLine =
true,
bool doNotMove =
false,
bool xzMode =
false)
133 Print(
"SCR_ShapeNextPointHelper.GetNextPoint's distance parameter cannot be zero or negative!",
LogLevel.ERROR);
137 if (anchorLimit == -1)
142 Print(
"SCR_ShapeNextPointHelper.GetNextPoint's anchorLimit parameter is invalid (must be in range 1.." +
m_iAnchorPointsCount +
", was " + anchorLimit +
")",
LogLevel.ERROR);
148 Print(
"SCR_ShapeNextPointHelper.GetNextPoint's anchorLimit parameter is already passed (" + anchorLimit +
" requested, " +
m_iCurrentSectionIndex +
" current)",
LogLevel.WARNING);
160 currentSectionIndex++;
161 currentSectionPoint = 1;
166 array<vector> sectionPoints;
168 for (; currentSectionIndex < anchorLimit; currentSectionIndex++)
173 for (
int pointIndex = currentSectionPoint, sectionPointsCount = sectionPoints.Count(); pointIndex < sectionPointsCount; pointIndex++)
175 vector nextPoint = sectionPoints[pointIndex];
182 vector endToStartDir =
vector.Direction(nextPoint, prevPoint);
185 vector endToStartDirXZ = endToStartDir;
186 endToStartDirXZ[1] = 0;
188 sameLevelCentre[1] = nextPoint[1];
190 if (
vector.DistanceXZ(nextPoint, prevPoint) != 0)
192 Math3D.IntersectionRaySphere(nextPoint, endToStartDirXZ.Normalized(), sameLevelCentre,
distance)
193 /
vector.DistanceXZ(nextPoint, prevPoint);
195 result = nextPoint + removedRatio * endToStartDirXZ;
196 result[1] = prevPoint[1] + (1 - removedRatio) * (nextPoint[1] - prevPoint[1]);
200 endToStartDir.Normalize();
240 prevPoint = nextPoint;
243 currentSectionPoint = 1;
257 array<vector> segment;
261 result +=
vector.Distance(segment[0], segment[1]);
292 if (anchorIndex == 0)
363 int anchorPointsCount = anchorPoints.Count();
364 if (anchorPointsCount < 2)
367 int tesselatedPointsCount = tesselatedPoints.Count();
368 if (tesselatedPointsCount < anchorPointsCount)
372 if (anchorPoints[0] != tesselatedPoints[0])
379 vector anchorPos = anchorPoints[anchorIndex];
380 foreach (
vector tesselatedPoint : tesselatedPoints)
382 if (anchorIndex >= anchorPointsCount)
385 if (tesselatedPoint == anchorPoints[anchorIndex])
388 if (anchorIndex < anchorPointsCount)
389 anchorPos = anchorPoints[anchorIndex];
393 if (anchorIndex != anchorPointsCount)
400 result.
m_aAnchorPoints = SCR_ArrayHelperT<vector>.GetCopy(anchorPoints);
405 array<vector> anchorSection;
406 array<float> sectionSegmentLengths;
414 float segmentLength =
vector.Distance(currPoint, prevPoint);
418 anchorSection.Insert(currPoint);
419 sectionSegmentLengths.Insert(segmentLength);
420 result.
m_aSegments.Insert({ prevPoint, currPoint });
423 if (currPoint == nextAnchor)
429 sectionSegmentLengths.Insert(segmentLength);
433 anchorSection = { currPoint };
434 sectionSegmentLengths = {};
437 if (anchorIndex >= anchorPointsCount)
445 prevPoint = currPoint;
464 array<vector> anchorPoints = {};
465 array<vector> tesselatedPoints = {};
467 shapeEntity.GetPointsPositions(anchorPoints);
468 shapeEntity.GenerateTesselatedShape(tesselatedPoints);
470 bool isShapeClosed = shapeEntity.IsClosed();
473 WorldEditorAPI worldEditorAPI = ((WorldEditor)Workbench.GetModule(WorldEditor)).GetApi();
476 IEntitySource shapeEntitySource = worldEditorAPI.EntityToSource(shapeEntity);
477 if (shapeEntitySource)
478 shapeEntitySource.Get(
"IsClosed", isShapeClosed);
484 anchorPoints.Insert(anchorPoints[0]);
485 if (!SplineShapeEntity.Cast(shapeEntity))
486 tesselatedPoints.Insert(tesselatedPoints[0]);
491 SCR_ArrayHelperT<vector>.Reverse(anchorPoints);
492 SCR_ArrayHelperT<vector>.Reverse(tesselatedPoints);
static SCR_ShapeNextPointHelper CreateFromShape(notnull ShapeEntity shapeEntity, bool reverse=false)
vector GetCurrentPosition()
array< int > GetAnchorPointIndices()
static SCR_ShapeNextPointHelper CreateFromPoints(notnull array< vector > anchorPoints, notnull array< vector > tesselatedPoints)
int m_iCurrentSegmentIndex
void Reset()
Reset to the beginning.
ref array< vector > m_aAnchorPoints
format [anchor0, anchor1, anchor2]
float GetStraightDistanceToNextAnchor()
vector m_vCurrentDirection
float GetShapeDistanceToNextAnchor()
array< vector > GetAnchorPoints()
int m_iCurrentSectionPointIndex
vector m_vCurrentPosition
int m_iSegmentsCount
count of m_aSegments
vector GetCurrentDirection()
float GetDoneShapeLength()
ref array< vector > m_aTesselatedPoints
format [anchor0, pointA0, pointB0, anchor1, pointA1, pointB1, anchor2]
float CalculateDoneLength()
float CalculateCurrentSegmentIndex()
int m_iAnchorPointsCount
count of m_aAnchorPoints
int m_iCurrentSectionIndex
array< vector > GetTesselatedPoints()
ref array< ref array< vector > > m_aSegments
format [[segment0startPos, segment0endPos], [segment1startPos, segment1endPos]]
void SCR_ShapeNextPointHelper()
protected constructor - use CreateFrom* methods
ref array< int > m_aAnchorPointIndices
anchor indices in tesselated points
bool GetNextPoint(float distance, out vector result, int anchorLimit=-1, bool straightLine=true, bool doNotMove=false, bool xzMode=false)
float GetRemainingShapeLength()
bool SetOnAnchor(int anchorIndex)
ref array< ref array< vector > > m_aSections
format [[anchor0, tessPoint, tessPoint, anchor1], [anchor1, tessPoint, tessPoint, anchor2]]
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
proto native bool IsIndexValid(int index)
Returns whether provided element index of array is valid.