29 class WireDistanceCompositeConstraint;
31#define shape_to_world_transform( geom ) \
32 ((*geom->getShapes().begin())->getLocalTransform() * geom->getTransform())
34#define world_to_shape_transform( geom ) \
35 (shape_to_world_transform( geom ).inverse())
87#undef shape_to_world_transform
88#undef world_to_shape_transform
92 static inline
bool overlappingRange(
agx::Real range1Start,
agx::Real range1End,
agx::Real range2Start,
agx::Real range2End )
94 return (
agx::leq(range1Start, range2End ) &&
agx::geq(range1End, range2Start ) );
106 template < typename IteratorCompatibleContainer >
107 typename IteratorCompatibleContainer::const_iterator
findBeginIterator( const IteratorCompatibleContainer& container,
int nodeMask )
109 if ( container.empty() )
110 return container.end();
112 typename IteratorCompatibleContainer::const_iterator i = container.begin();
113 while ( i != container.end() && ((*i)->getType() & nodeMask) == 0 )
124 template <
typename IteratorCompatibleContainer >
125 typename IteratorCompatibleContainer::const_iterator
findEndIterator(
const IteratorCompatibleContainer& container,
int nodeMask )
128 if ( container.empty() )
129 return container.end();
131 typename IteratorCompatibleContainer::const_iterator i = container.end();
133 while ( i != container.begin() && ((*i)->getType() & nodeMask) == 0 )
149 template <
typename IteratorCompatibleContainer >
157 if ( container.empty() || beginIt == endIt )
160 typename IteratorCompatibleContainer::const_iterator i = beginIt;
162 typename IteratorCompatibleContainer::const_iterator end = endIt;
165 agx::Vec3 startPoint = (*i)->getFrame()->getWorldPosition();
168 for ( ; i != end; ++i ) {
169 endPoint = (*i)->getFrame()->getWorldPosition();
171 direction = endPoint - startPoint;
176 t = (( point - startPoint ) * direction) / direction.
length2();
180 startPoint += direction * t;
181 agx::Real d2 = ( startPoint - point ).length2();
184 if ( d2 < shortestDistanceSquared ) {
185 shortestDistanceSquared = d2;
186 bestDistance = currentDistance + t * dl;
188 currentDistance += dl;
189 startPoint = endPoint;
192 return bestDistance + pulledInBegin;
203 template <
typename IteratorCompatibleContainer >
219 template <
typename IteratorCompatibleContainer >
220 agx::Vec3 findPointOnWire(
const IteratorCompatibleContainer& container,
const agx::Vec3& point,
typename IteratorCompatibleContainer::const_iterator beginIt,
typename IteratorCompatibleContainer::const_iterator endIt,
agx::Real& shortestDistanceSquared )
222 if ( container.empty() )
230 return beginIt->get()->getFrame()->getWorldPosition();
233 typename IteratorCompatibleContainer::const_iterator i = beginIt;
234 typename IteratorCompatibleContainer::const_iterator end = endIt;
235 agxAssert( i != container.end() && end != container.begin() );
237 agx::Vec3 currPos = (*i)->getFrame()->getWorldPosition();
240 for ( ; i != end; ++i ) {
241 agx::Vec3 nextPos = (*i)->getFrame()->getWorldPosition();
247 agx::Real d = distanceAlongWire - currDistanceAlongWire;
248 return currPos + dir * d;
250 currDistanceAlongWire += length;
257 template <
typename IteratorCompatibleContainer >
258 agx::Vec3 findPointOnWire(
const IteratorCompatibleContainer& container,
const agx::Vec3& point,
typename IteratorCompatibleContainer::const_iterator beginIt,
typename IteratorCompatibleContainer::const_iterator endIt,
const agx::Vec3 n,
agx::Real& shortestDistanceSquared )
279#define planeProject( pnt ) pnt - ( normal * ( plane * pnt ) )
283 if ( container.empty() )
return agx::Vec3();
285 w1 = (*(++container.begin()))->getFrame()->getWorldPosition();
288 typename IteratorCompatibleContainer::const_iterator nodeIter = beginIt;
289 typename IteratorCompatibleContainer::const_iterator end = endIt;
291 for ( ; nodeIter != end; ++nodeIter ) {
292 const Node* currentNode =
static_cast< const Node*
>( (*nodeIter).get() );
299 t = (( pp - p1 ) * pd ) / pd.
length2();
305 dist = (p1-pp).length2();
307 if ( dist < shortestDistanceSquared )
309 shortestDistanceSquared = dist;
310 currentBest = w1 + (w2-w1) * t;
330 template <
typename IteratorCompatibleContainer >
334 return findPointOnWire( container, point, container.begin(), container.end(), dummySquaredDistance );
344 template <
typename IteratorCompatibleContainer >
348 return findPointOnWire( container, point, container.begin(), container.end(), n , dummySquaredDistance );
358 template <
typename It >
361 if ( begin == end || begin == containerEnd )
369 if ( next == containerEnd || next == end )
373 while ( next != containerEnd && next != end ) {
374 length += ( (*next)->getFrame()->getWorldPosition() - (*curr)->getFrame()->getWorldPosition() ).length();
375 if ( length > distanceFromStart )
391 template <
typename IteratorCompatibleContainer >
394 if ( container.empty() )
397 typename IteratorCompatibleContainer::const_iterator i =
getNodeIterator( distanceFromStart, container.begin(), container.end(), container.end() );
398 if ( i != container.end() )
409 template <
typename IteratorCompatibleContainer >
412 if ( container.empty() )
415 typename IteratorCompatibleContainer::iterator i =
getNodeIterator( distanceFromStart, container.begin(), container.end(), container.end() );
416 if ( i != container.end() )
424 int
AGXPHYSICS_EXPORT validateEdgePassings( const
agxCollide::Geometry* meshGeometry,const
agxCollide::Mesh* mesh,const
size_t triangleIndex, const
agx::RigidBody* rb, const
agx::Vec3 lineGeometryBegin, const
agx::Vec3 lineGeometryEnd, const
agx::Vec3 lineGeometryBeginLastNTimeSteps, const
agx::Vec3 lineGeometryEndLastNTimeSteps,
agx::Vec3 ,
agx::Real timeStep,
agx::Real wireRadius,const
agx::Real numTimeStepsBackToEvaluateFrom = 2);
426 int closestEdgeToContact(const
agxCollide::Mesh* mesh,const
size_t triangleIndex,const
agx::Vec3 pointInTriangle);
429 template <typename T>
430 static inline
bool findMeshTriangleAndEdge( const
agx::Vec3 lineGeometryBegin, const
agx::Vec3 lineGeometryEnd,
431 const
agx::Vec3 lineGeometryBeginLastNTimeSteps, const
agx::Vec3 lineGeometryEndLastNTimeSteps ,
432 size_t& triangleIndex,
size_t& edgeIndex, T* ,
433 const typename T::PointType& contactPoint, const
agxCollide::Mesh* meshShape,
434 agxCollide::Geometry* geometryMesh, const
agx::Real timeStep,
435 const
agx::Real wireRadius,const
agx::Real numTimeStepsBackToEvaluateFrom = 2 )
439 if (meshShape->getEntity() == contactPoint.shape1()) {
440 faceIndex = contactPoint.faceIndex1();
441 faceFeature = contactPoint.faceFeature1();
444 agxAssert(meshShape->getEntity() == contactPoint.shape2());
445 faceIndex = contactPoint.faceIndex2();
446 faceFeature = contactPoint.faceFeature2();
450 triangleIndex = faceIndex;
453 if ( triangleIndex == meshShape->getNumTriangles() )
457 edgeIndex = faceFeature - 3;
460 int closestEdgeIndex = validateEdgePassings(geometryMesh,meshShape,triangleIndex,geometryMesh->getRigidBody(),lineGeometryBegin,lineGeometryEnd,lineGeometryBeginLastNTimeSteps,lineGeometryEndLastNTimeSteps,contactPoint.point(),timeStep,wireRadius,numTimeStepsBackToEvaluateFrom );
462 if ( closestEdgeIndex < 0 )
468 agx::Vec3 toLineBegin = lineGeometryBegin - pointInTriangle;
469 agx::Vec3 toLineEnd = lineGeometryEnd - pointInTriangle;
472 agx::Real distToPlaneFromBegin = (toLineBegin * triangleNormalWorld );
473 agx::Real distToPlaneFromEnd = (toLineEnd * triangleNormalWorld );
474 if ( distToPlaneFromBegin * distToPlaneFromEnd > 0 )
480 if ( !
agx::equivalent( meshShape->getTriangle(triangleIndex).getNormal() * (pointInTriangleLocal - meshShape->getTriangle(triangleIndex).getVertex(0)),
agx::Real(0) ) )
482 pointInTriangle = contactPoint.point() -
agx::Vec3( contactPoint.normal() ) * contactPoint.depth() *
agx::Real(0.5);
485 closestEdgeIndex = closestEdgeToContact( meshShape, triangleIndex, pointInTriangleLocal );
497 agxCollide::ClosestPointsSolution solution;
498 agxCollide::ClosestPointsSolution parallelSolution;
499 bool isParallel =
false;
501 closestPointsSegmentSegment(edgeStart, edgeEnd, lineGeometryBegin, lineGeometryEnd, solution, isParallel, parallelSolution, epsilon );
502 agx::Real spDistanceBegin = solution.pointOn1.distance(lineGeometryBegin);
503 agx::Real spDistanceEnd = solution.pointOn1.distance(lineGeometryEnd);
505 if ( spDistanceBegin < wireRadius || spDistanceEnd < wireRadius )
506 closestEdgeIndex = -1;
509 agx::Real distanceDiff = spDistanceBegin + spDistanceEnd - lineGeometryEnd.distance(lineGeometryBegin);
511 if ( std::min( std::abs(distToPlaneFromBegin), std::abs(distToPlaneFromEnd) ) < distanceDiff )
512 closestEdgeIndex = -1;
517 if ( closestEdgeIndex < 0 )
520 edgeIndex = (size_t)closestEdgeIndex;
526 if ( meshShape->getTriangle( triangleIndex ).isValid() && meshShape->getTriangle(triangleIndex).hasHalfEdgePartner((uint8_t)edgeIndex) )
528 agx::Vec3 n1 = meshShape->getTriangle(triangleIndex ).getNormal();
529 agx::Vec3 n2 = meshShape->getTriangle(triangleIndex).getHalfEdgePartner((uint8_t)edgeIndex).getNormal();
548 retEdge = edgeEnd - edgeStart;
551 agx::Vec3 pRelStart = localContactPoint - edgeStart;
552 pRelStart = retEdge*( pRelStart*retEdge );
553 retLocalCorrectedContactPoint = edgeStart + pRelStart;
555 retEdgeStart = edgeEnd - retEdge*( edgeL );
556 retEdgeEnd = edgeStart + retEdge*( edgeL );
#define world_to_shape_transform(geom)
#define planeProject(pnt)
#define shape_to_world_transform(geom)
#define AGXPHYSICS_EXPORT
The geometry representation used by the collision detection engine.
const ShapeRefVector & getShapes() const
Class for more intuitive access to the Mesh's mesh data.
agx::Vec3 getEdgeEndVertex(uint_fast8_t localEdgeIndex) const
agx::Vec3 getEdgeStartVertex(uint_fast8_t localEdgeIndex) const
Mesh is a common base class for triangle meshes, such as Mesh or HeightField.
const Triangle getTriangle(size_t triangleIndex) const
Type
The type of Voronoi region.
static Type calculateType(unsigned index)
const agx::Vec3 & getWorldPosition() const
Class defining a node that is part of a wire.
Real normalize()
Normalize the vector so that it has length unity.
Real length() const
Length of the vector = sqrt( vec .
Real length2() const
Length squared of the vector = vec .
A class holding 4 dimensional vectors and providing basic arithmetic.
#define DOXYGEN_END_INTERNAL_BLOCK()
#define DOXYGEN_START_INTERNAL_BLOCK()
This namespace consists of a set of classes for handling geometric intersection tests including boole...
Implements a Wire model with adaptive resolution.
NodeContainer::const_iterator NodeConstIterator
static agx::Vec3 transformPointToWorld(const agx::Vec3 &p, const agxCollide::Geometry *g)
Transforms a point given in shape coordinates to world given geometry g.
IteratorCompatibleContainer::const_iterator findBeginIterator(const IteratorCompatibleContainer &container, int nodeMask)
Primitive function to find begin iterator for utility functions below.
static agx::Vec3 transformVectorToWorld(const agx::Vec3 &v, const agxCollide::Geometry *g)
Transforms a vector given in shape coordinates to world coordinates given geometry g.
const Node * getNode(const IteratorCompatibleContainer &container, agx::Real distanceFromStart)
Finds the wire node given current distance from the start of the wire (wire defined to be iterator co...
agx::Real findDistanceFromStartGivenPoint(agx::Real pulledInBegin, const IteratorCompatibleContainer &container, const agx::Vec3 &point, typename IteratorCompatibleContainer::const_iterator beginIt, typename IteratorCompatibleContainer::const_iterator endIt, agx::Real &shortestDistanceSquared)
Search vector/list container defining a wire for the 3D point -> 1D wire projection.
static agx::Vec3 transformPointToShape(const agx::Vec3 &p, const agxCollide::Geometry *g)
Transforms a point given in world coordinates to shape coordinates of geometry g.
static agx::Vec3 transformVectorToShape(const agx::Vec3 &v, const agxCollide::Geometry *g)
Transforms a vector given in world coordinates to shape coordinates of geometry g.
It getNodeIterator(agx::Real distanceFromStart, It begin, It end, It containerEnd)
This function is used by getNode, but can be used of some nodes in the beginning or end of the wire s...
agx::Vec3 findPointOnWire(const IteratorCompatibleContainer &container, const agx::Vec3 &point, typename IteratorCompatibleContainer::const_iterator beginIt, typename IteratorCompatibleContainer::const_iterator endIt, agx::Real &shortestDistanceSquared)
Projects any 3D point onto wire.
IteratorCompatibleContainer::const_iterator findEndIterator(const IteratorCompatibleContainer &container, int nodeMask)
Primitive function to find end iterator for utility functions below.
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
Vec3T< Real > Vec3
The object holding 3 dimensional vectors and providing basic arithmetic.
AGXCORE_EXPORT const Real RealMax
bool geq(double a, double b, double eps=(double) AGX_EQUIVALENT_EPSILON)
T1 clamp(T1 v, T2 minimum, T3 maximum)
AGXCORE_EXPORT const Real RealEpsilon
AGXPHYSICS_EXPORT agx::Bool equalsZero(const agx::AddedMassInteraction::Matrix6x6 &matrix, agx::Real eps=agx::RealEpsilon)
bool leq(double a, double b, double eps=(double) AGX_EQUIVALENT_EPSILON)
static constexpr Real AGX_EQUIVALENT_EPSILON
AGXPHYSICS_EXPORT agx::Bool equivalent(const agx::AddedMassInteraction::Matrix6x6 &lhs, const agx::AddedMassInteraction::Matrix6x6 &rhs, agx::Real eps=agx::RealEpsilon)