Adds a vertex to the hull with the following algorithm
horizon
which is a chain of half edges, for an edge to
belong to this group it must be the edge connecting a face that can
see eyeVertex
and a face which cannot see eyeVertex
eyeVertex
have its visible vertices removed
from the claimed VertexListhorizon
and
eyeVertex
, each face is connected with the opposite horizon face and
the face on the left/rightComputes the extremes of a tetrahedron which will be the initial hull
The min/max vertices in the x,y,z directions
Computes a chain of half edges in ccw order called the horizon
, for an
edge to be part of the horizon it must join a face that can see
eyePoint
and a face that cannot see eyePoint
The coordinates of a point
The edge used to jump to the current face
The current face being tested
The edges that form part of the horizon in ccw order
Compues the initial tetrahedron assigning to its faces all the points that are candidates to form part of the hull
Removes all the visible vertices that face
is able to see, additionally
checking the following:
If absorbingFace
doesn't exist then all the removed vertices will be
added to the unclaimed
vertex list
If absorbingFace
exists then this method will assign all the vertices of
face
that can see absorbingFace
, if a vertex cannot see absorbingFace
it's added to the unclaimed
vertex list
Merges a face with none/any/all its neighbors according to the strategy used
if mergeType
is MERGE_NON_CONVEX_WRT_LARGER_FACE then the merge will be
decided based on the face with the larger area, the centroid of the face
with the smaller area will be checked against the one with the larger area
to see if it's in the merge range [tolerance, -tolerance] i.e.
dot(centroid smaller face, larger face normal) - larger face offset > -tolerance
Note that the first check (with +tolerance) was done on computeHorizon
If the above is not true then the check is done with respect to the smaller face i.e.
dot(centroid larger face, smaller face normal) - smaller face offset > -tolerance
If true then it means that two faces are non convex (concave), even if the dot(...) - offset value is > 0 (that's the point of doing the merge in the first place)
If two faces are concave then the check must also be done on the other face but this is done in another merge pass, for this to happen the face is marked in a temporal NON_CONVEX state
if mergeType
is MERGE_NON_CONVEX then two faces will be merged only if
they pass the following conditions
dot(centroid smaller face, larger face normal) - larger face offset > -tolerance dot(centroid larger face, smaller face normal) - smaller face offset > -tolerance
Finds the next vertex to make faces with the current hull
face
be the first face existing in the claimed
vertex listface
doesn't exist then return since there're no vertices leftvertex
that face sees find the one furthest away
from face
Returns undefined when there're no more visible vertices
Computes the distance from edge
opposite face's centroid to
edge.face
Reassigns as many vertices as possible from the unclaimed list to the new faces
Creates a new array of faces from an array of points.
The array of points to create the hull from.
An array of faces.
Creates a face with the points
eyeVertex.point
,horizonEdge.tail
andhorizonEdge.tail
in ccw order