11#ifndef JAU_GAMP_GRAPH_OUTLINE_HPP_
12#define JAU_GAMP_GRAPH_OUTLINE_HPP_
30 using namespace jau::enums;
31 using namespace jau::math;
33 using jau::math::geom::AABBox3f;
34 using jau::math::geom::plane::AffineTransform;
55 enum class DirtyBits : uint16_t {
67 mutable DirtyBits m_dirtyBits;
68 mutable bool m_complexShape;
78 : m_vertices(vertCapacity),
79 m_closed(false), m_bbox(),
81 m_dirtyBits(DirtyBits::none),
85 constexpr void reserve(
size_type newVertCapacity) { m_vertices.reserve(newVertCapacity); }
87 constexpr bool empty() const noexcept {
return m_vertices.empty(); }
105 if( position < m_vertices.size() ) {
106 m_dirtyBits |= DirtyBits::bounds | DirtyBits::winding | DirtyBits::complexShape;
107 m_vertices.erase(position);
112 return m_vertices.size() == 0;
119 return m_vertices[m_vertices.size()-1];
122 constexpr bool isClosed() const noexcept {
return m_closed; }
142 m_vertices.push_back(first);
144 m_vertices.insert(m_vertices.begin(), last);
160 if( !
is_set(m_dirtyBits, DirtyBits::winding) ) {
165 m_winding = Winding::CCW;
167 m_winding = computeWinding();
169 m_dirtyBits &= ~DirtyBits::winding;
174 Winding computeWinding() const noexcept;
186 if( enforce != had_winding ) {
194 m_dirtyBits &= ~DirtyBits::winding;
208 if( !
is_set(m_dirtyBits, DirtyBits::complexShape) ) {
209 return m_complexShape;
211 m_complexShape = !computeIsComplex();
213 m_dirtyBits &= ~DirtyBits::complexShape;
214 return m_complexShape;
218 bool computeIsComplex() const noexcept;
220 void validateBoundingBox() const noexcept {
223 for(
const Vertex& v : m_vertices) {
230 if (
is_set(m_dirtyBits, DirtyBits::bounds) ) {
231 validateBoundingBox();
245 m_vertices.push_back(
vertex);
246 if ( !
is_set(m_dirtyBits, DirtyBits::bounds) ) {
247 m_bbox.resize(
vertex.coord());
249 m_dirtyBits |= DirtyBits::winding | DirtyBits::complexShape;
263 m_vertices.insert(position,
vertex);
264 if ( !
is_set(m_dirtyBits, DirtyBits::bounds) ) {
265 m_bbox.resize(
vertex.coord());
267 m_dirtyBits |= DirtyBits::winding | DirtyBits::complexShape;
273 for(
const Vertex& v : m_vertices) {
276 newOutline.m_closed = m_closed;
287 const float otherSize = other.bounds().size();
290 }
else if(thisSize < otherSize){
307 if(
bounds() != o.bounds() ) {
311 if(
vertex(i) != o.vertex(i) ) {
bool setClosed(bool closeTail)
Ensure this outline is closed.
constexpr void reserve(size_type newVertCapacity)
void addVertex(const Vertex &vertex)
Appends a vertex to the outline loop/strip.
constexpr const VertexList & vertices() const noexcept
bool isEmpty() const noexcept
bool isComplex() const noexcept
Returns cached or computed result if whether this Outlines polyline is a complex shape.
constexpr bool empty() const noexcept
constexpr bool isClosed() const noexcept
constexpr bool operator==(const Outline &o) const noexcept
constexpr const Vertex & vertex(size_type i) const noexcept
constexpr size_type vertexCount() const noexcept
void setWinding(Winding enforce)
Sets Winding to this outline.
constexpr Vertex & vertex(size_type i) noexcept
constexpr Outline(size_type vertCapacity)
Outline transform(const AffineTransform &t) const
Returns a transformed copy of this instance using the given AffineTransform.
constexpr VertexList & vertices() noexcept
int compareTo(const Outline &other) const noexcept
Compare two outline's Bounding Box size.
Winding getWinding() const noexcept
Returns the cached or computed winding of this Outlines polyline using VectorUtil#area(ArrayList).
const AABBox3f & bounds() const noexcept
void removeVertex(size_type position)
Removes the Vertex element at the given position.
const Vertex & lastVertex() const noexcept
void addVertex(size_type position, const Vertex &vertex)
Insert the Vertex element at the given position to the outline loop/strip.
static constexpr size_type max_elements
byte-size uint32_t limit: 1'073'741'823 (FIXME: Adjust to actual type, i.e. Vertex = 2x Vec3f?...
constexpr const Vec3f & coord() const noexcept
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Axis Aligned Bounding Box.
constexpr AABBox3f & reset() noexcept
Reset this box to the inverse low/high, allowing the next resize(float, float, float) command to hit.
constexpr float size() const noexcept
Get the size of this aabbox3f where the size is represented by the length of the vector between low a...
AABBox3f & resize(const AABBox3f &o) noexcept
Resize the aabbox3f to encapsulate another AABox.
#define JAU_MAKE_BITFIELD_ENUM_STRING_MEMBER(type,...)
constexpr bool is_set(const E mask, const E bits) noexcept
constexpr bool equals2(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
jau::darray< Vertex, uint32_t > VertexList
jau::darray< Outline, uint32_t > OutlineList