You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.h

154 lines
5.7 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_UTILS_POLYGONMATH2D_H
#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_UTILS_POLYGONMATH2D_H
#pragma once
#include "CryFixedArray.h"
//==================================================================================================
// Name: FixedPodArray
// Desc: Extension of CryFixedArray to add useful functionality
// Note: This should be promoted into CryFixedArray in the long term
// Author: Chris Bunner
//==================================================================================================
template <class T, unsigned int N>
class FixedPodArray
: public CryFixedArray<T, N>
{
typedef CryFixedArray<T, N> CFA;
public:
ILINE void resize(const uint size)
{
if (size <= N)
{
CFA::m_curSize[0] = size;
}
else
{
CryLogAlways("FixedPodArray::resize() failing as size too large - NOT resizing array");
CRY_ASSERT_MESSAGE(0, "FixedPodArray::resize() failing as size too large - NOT resizing array");
}
}
ILINE void erase(const uint index, const uint count = 1)
{
const uint size = CFA::m_curSize[0];
if (index == size - count)
{
// Simple remove
CFA::m_curSize[0] -= count;
}
else if (index + count < size)
{
// Shuffle set of elements along
const uint range = size - (index + count);
memmove(&CFA::at(index), &CFA::at(index + count), sizeof(T) * range);
CFA::m_curSize[0] -= count;
}
else
{
CryLogAlways("FixedPodArray::erase() failing as element range invalid - NOT removing element");
CRY_ASSERT_MESSAGE(0, "FixedPodArray::erase() failing as element range invalid - NOT removing element");
}
}
ILINE void insert_before(const T& elem, const uint index)
{
const uint size = CFA::m_curSize[0];
if (index < size && size < N)
{
// Shuffle set of elements along
const uint count = size - index;
memmove(&CFA::at(index + 1), &CFA::at(index), sizeof(T) * count);
// Add new element
memcpy(&CFA::at(index), &elem, sizeof(T));
++CFA::m_curSize[0];
}
else
{
CryLogAlways("FixedPodArray::insert_before() failing as element index invalid - NOT inserting element");
CRY_ASSERT_MESSAGE(0, "FixedPodArray::insert_before() failing as element index invalid - NOT inserting element");
}
}
ILINE int find(const T& elem)
{
const uint size = CFA::m_curSize[0];
const int invalid = -1;
int index = invalid;
for (uint i = 0; i < size; ++i)
{
if (CFA::at(i) == elem)
{
index = i;
break;
}
}
return index;
}
};
//==================================================================================================
// Name: PolygonMath2D
// Desc: Polygon math helper functions optimized for breakable glass sim
// Note: Functions often assume clockwise polygon point order
// Author: Chris Bunner
//==================================================================================================
// Common polygon array types
#define POLY_ARRAY_SIZE 45
typedef FixedPodArray<Vec2, POLY_ARRAY_SIZE> TPolygonArray;
typedef FixedPodArray<int, POLY_ARRAY_SIZE> TPolyIndexArray;
// 2D triangle helpers
bool PointInTriangle2D(const Vec2& pt, const Vec2& a, const Vec2& b, const Vec2& c);
bool TriangleIsConvex2D(const Vec2& a, const Vec2& b, const Vec2& c);
// 2D intersection helpers
int LineCircleIntersect2D(const Vec2& pt0, const Vec2& pt1, const Vec2& center, const float radiusSq, float& intersectA, float& intersectB);
// 2D polygon helpers
bool PointInPolygon2D(const Vec2& pt, const Vec2* pPolygon, const int numPts);
float CalculatePolygonArea2D(const Vec2* pPolygon, const int numPts);
Vec2 CalculatePolygonBounds2D(const Vec2* pPolygon, const int numPts);
Vec2 CalculatePolygonCenter2D(const Vec2* pPolygon, const int numPts);
bool CalculatePolygonSharedPerimeter2D(const Vec2* pPolygonA, const int numPtsA, const Vec2* pPolygonB, const int numPtsB, float& connectionA, float& connectionB);
void TriangulatePolygon2D(const Vec2* pPolygon, const int numPolyPts, PodArray<Vec2>* pVertices, PodArray<uint8>* pIndices);
void SplitPolygonAroundPoint(TPolygonArray& outline, const Vec2& splitPt, const float splitRadius, TPolygonArray& splitInnerOutline);
void SplitPolygonAroundPoint(PodArray<Vec2>& outline, const Vec2& splitPt, const float splitRadius, TPolygonArray& splitInnerOutline);
// Helper with result enum
enum EPolygonInCircle2D
{
EPolygonInCircle2D_Inside = 0,
EPolygonInCircle2D_Outside,
EPolygonInCircle2D_Overlap
};
EPolygonInCircle2D PolygonInCircle2D(const Vec2& center, const float radius, const Vec2* pPolygon, const int numPts);
#endif // _POLYGON_MATH_2D_