18 #include "precompiled.h"
36 SOverlayLine& overlay,
bool floating,
float heightOffset)
38 PROFILE(
"ConstructLineOnGround");
57 overlay.
m_Coords.reserve(xz.size()/2 * 3);
59 for (
size_t i = 0; i < xz.size(); i += 2)
71 SOverlayLine& overlay,
bool floating,
float heightOffset)
88 size_t numPoints =
clamp((
size_t)(radius*4.0f), (
size_t)12, (
size_t)48);
90 overlay.
m_Coords.reserve((numPoints + 1) * 3);
92 for (
size_t i = 0; i <= numPoints; ++i)
94 float a = (float)i * 2 * (
float)
M_PI / (float)numPoints;
95 float px = x + radius * sinf(a);
96 float pz = z + radius * cosf(a);
105 static void SplitLine(std::vector<std::pair<float, float> >& coords,
float x1,
float y1,
float x2,
float y2)
107 float length = sqrtf(
SQR(x1 - x2) +
SQR(y1 - y2));
111 float xPieceLength = (x1 - x2) / (
float)pieces;
112 float yPieceLength = (y1 - y2) / (
float)pieces;
113 for (
size_t i = 1; i <= (pieces - 1); ++i)
115 coords.push_back(std::make_pair(x1 - (xPieceLength * (
float)i), y1 - (yPieceLength * (
float)i)));
118 coords.push_back(std::make_pair(x2, y2));
122 SOverlayLine& overlay,
bool floating,
float heightOffset)
141 std::vector<std::pair<float, float> > coords;
146 coords.push_back(std::make_pair(x - w/2*c + h/2*s, z + w/2*s + h/2*c));
148 SplitLine(coords, x - w/2*c + h/2*s, z + w/2*s + h/2*c, x - w/2*c - h/2*s, z + w/2*s - h/2*c);
149 SplitLine(coords, x - w/2*c - h/2*s, z + w/2*s - h/2*c, x + w/2*c - h/2*s, z - w/2*s - h/2*c);
150 SplitLine(coords, x + w/2*c - h/2*s, z - w/2*s - h/2*c, x + w/2*c + h/2*s, z - w/2*s + h/2*c);
151 SplitLine(coords, x + w/2*c + h/2*s, z - w/2*s + h/2*c, x - w/2*c + h/2*s, z + w/2*s + h/2*c);
153 overlay.
m_Coords.reserve(coords.size() * 3);
155 for (
size_t i = 0; i < coords.size(); ++i)
157 float px = coords[i].first;
158 float pz = coords[i].second;
222 ENSURE(numSteps > 0 && numSteps % 4 == 0);
226 size_t fullCircleSteps = numSteps;
227 const float angleIncrement = 2.f*
M_PI/fullCircleSteps;
242 for (
size_t i = 0; i < fullCircleSteps/4; ++i)
245 rotationVector = xzRotation.
Rotate(rotationVector);
254 for (
size_t i = 0; i < fullCircleSteps; ++i)
257 rotationVector = xyRotation.
Rotate(rotationVector);
263 for (
size_t i = fullCircleSteps/4; i < fullCircleSteps; ++i)
266 rotationVector = xzRotation.
Rotate(rotationVector);
274 for (
size_t i = 0; i <= fullCircleSteps; ++i)
277 rotationVector = yzRotation.
Rotate(rotationVector);
307 PROFILE(
"SmoothPointsAverage");
309 size_t n = points.size();
313 std::vector<CVector2D> newPoints;
314 newPoints.resize(points.size());
319 newPoints[0] = (points[n-1] + points[0] + points[1]) / 3.f;
320 newPoints[n-1] = (points[n-2] + points[n-1] + points[0]) / 3.f;
324 newPoints[0] = points[0];
325 newPoints[n-1] = points[n-1];
329 for (
size_t i = 1; i < n-1; ++i)
330 newPoints[i] = (points[i-1] + points[i] + points[i+1]) / 3.f;
332 points.swap(newPoints);
338 CVector2D p = a0*(t*t*t) + a1*(t*t) + a2*t + a3;
341 CVector2D dp = (a0*(3*t*t) + a1*(2*t) + a2).Normalized();
349 PROFILE(
"InterpolatePointsRNS");
350 ENSURE(segmentSamples > 0);
352 std::vector<CVector2D> newPoints;
361 size_t n = points.size();
374 size_t imax = closed ? n : n-1;
375 newPoints.reserve(imax*segmentSamples);
383 for (
size_t i = 0; i < imax; ++i)
392 if (!closed && (i == 0))
395 p0 = points[0] + (points[0] - points[1]);
398 p0 = points[(i-1+n)%n];
401 if (!closed && (i == n-2))
404 p3 = points[n-1] + (points[n-1] - points[n-2]);
407 p3 = points[(i+2)%n];
411 float l1 = (p2 - p1).
Length();
415 CVector2D v1 = (s0 + s1).Normalized() * l1;
416 CVector2D v2 = (s1 + s2).Normalized() * l1;
419 a0 = p1*2 + p2*-2 + v1 + v2;
420 a1 = p1*-3 + p2*3 + v1*-2 + v2*-1;
425 for (
int sample = 0; sample < segmentSamples; sample++)
426 newPoints.push_back(
EvaluateSpline(sample/((
float) segmentSamples), a0, a1, a2, a3, offset));
435 points.swap(newPoints);
444 if (blankLength <= 0)
447 if (keyPoints.size() < 2)
460 bool buildingDash =
true;
461 float curDashLength = 0;
465 dashedLineOut.
m_Points.push_back(keyPoints[0]);
472 while(i < keyPoints.size() - 1)
475 CVector2D segmentVector = keyPoints[i + 1] - dashLastPoint;
476 float segmentLength = segmentVector.
Length();
478 float targetLength = (buildingDash ? dashLength : blankLength);
479 if (curDashLength + segmentLength > targetLength)
483 float cutLength = targetLength - curDashLength;
488 buildingDash = !buildingDash;
489 dashLastPoint = cutPoint;
496 dashedLineOut.
m_Points.push_back(cutPoint);
513 dashedLineOut.
m_Points.push_back(keyPoints[i+1]);
515 curDashLength += segmentLength;
516 dashLastPoint = keyPoints[i+1];
528 out_numSteps = ceilf(
float(2*
M_PI)/maxAngle);
529 out_stepAngle = float(2*
M_PI)/out_numSteps;
536 size_t numControlPoints = points.size();
537 if (numControlPoints < 2)
540 ENSURE(maxSegmentLength > 0);
542 size_t endIndex = numControlPoints;
543 if (!closed && numControlPoints > 2)
546 std::vector<CVector2D> newPoints;
548 for (
size_t i = 0; i < endIndex; i++)
551 const CVector2D& nextPoint = points[(i+1) % numControlPoints];
552 const CVector2D line(nextPoint - curPoint);
556 newPoints.push_back(curPoint);
559 float lineLength = line.
Length();
560 size_t numSegments = (size_t) ceilf(lineLength / maxSegmentLength);
561 float segmentLength = lineLength / numSegments;
563 for (
size_t s = 1; s < numSegments; ++s)
565 newPoints.push_back(curPoint + lineDirection * (s * segmentLength));
569 points.swap(newPoints);
Line-based overlay, with world-space coordinates, rendered in the world potentially behind other obje...
const ssize_t TERRAIN_TILE_SIZE
metres [world space units] per tile in x and z
virtual float GetExactGroundLevel(float x, float z)=0
void ConstructDashedLine(const std::vector< CVector2D > &linePoints, SDashedLine &dashedLineOut, const float dashLength, const float blankLength)
Creates a dashed line from the given line, dash length, and blank space between.
static void out(const wchar_t *fmt,...)
void InterpolatePointsRNS(std::vector< CVector2D > &points, bool closed, float offset, int segmentSamples=4)
Updates the given points to include intermediate points interpolating between the original control po...
static CVector2D EvaluateSpline(float t, CVector2D a0, CVector2D a1, CVector2D a2, CVector2D a3, float offset)
CVector3D Rotate(const CVector3D &vec) const
Contains pointers to various 'global' objects that are needed by the simulation code, to allow easy access without using real (evil) global variables.
const entity_id_t SYSTEM_ENTITY
Entity ID for singleton 'system' components.
std::vector< float > m_Coords
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
void ConstructCircleOnGround(const CSimContext &context, float x, float z, float radius, SOverlayLine &overlay, bool floating, float heightOffset=0.25f)
Constructs overlay line as a circle with given center and radius, conforming to terrain.
void ConstructLineOnGround(const CSimContext &context, const std::vector< float > &xz, SOverlayLine &overlay, bool floating, float heightOffset=0.25f)
Constructs overlay line from given points, conforming to terrain.
CVector2D Normalized() const
void SubdividePoints(std::vector< CVector2D > &points, float maxSegmentLength, bool closed)
Subdivides a list of points into segments of maximum length maxSegmentLength that are of equal size b...
void PushCoords(const CVector3D &v)
void AngularStepFromChordLen(const float maxChordLength, const float radius, float &out_stepAngle, unsigned &out_numSteps)
Computes angular step parameters out_stepAngle and out_numSteps, given a maxChordLength on a circle o...
virtual float GetExactWaterLevel(float x, float z)=0
Get the current water level at the given point.
std::vector< CVector2D > m_Points
Packed array of consecutive dashes' points. Use m_StartIndices to navigate it.
std::vector< size_t > m_StartIndices
Start indices in m_Points of each dash.
A simplified syntax for accessing entity components.
Helper functions related to rendering.
static void SplitLine(std::vector< std::pair< float, float > > &coords, float x1, float y1, float x2, float y2)
void ConstructSquareOnGround(const CSimContext &context, float x, float z, float w, float h, float a, SOverlayLine &overlay, bool floating, float heightOffset=0.25f)
Constructs overlay line as rectangle with given center and dimensions, conforming to terrain...
void GetCorner(int u, int v, int w, CVector3D &out) const
Returns the corner at coordinate (u, v, w).
void SmoothPointsAverage(std::vector< CVector2D > &points, bool closed)
Updates the given points so each point is averaged with its neighbours, resulting in a somewhat smoot...
void FromAxisAngle(const CVector3D &axis, float angle)
float ChordToCentralAngle(const float chordLength, const float radius)
Given a circle of radius radius, and a chord of length chordLength on this circle, computes the central angle formed by connecting the chord's endpoints to the center of the circle.
void ConstructAxesMarker(const CMatrix3D &coordSystem, SOverlayLine &outX, SOverlayLine &outY, SOverlayLine &outZ)
Constructs 3D axis marker overlay lines for the given coordinate system.
CVector3D GetTranslation() const
static float Length(const SVec3 v)
void ConstructBoxOutline(const CBoundingBoxOriented &box, SOverlayLine &overlayLine)
Constructs a solid outline of an arbitrarily-aligned bounding box.
T clamp(T value, T min, T max)
void ConstructGimbal(const CVector3D ¢er, float radius, SOverlayLine &out, size_t numSteps=16)
Constructs a simple gimbal outline with the given radius and center.
Helper functions related to geometry algorithms.