17#ifndef AGXSDK_LINECOLLISIONUTILS_H
18#define AGXSDK_LINECOLLISIONUTILS_H
32 return val > boundLower - threshold && val < boundUpper + threshold;
51 return (edge*(contactPoint*edge));
61 contactToCenter -= edge * (edge * contactToCenter);
62 v21 -= edge * (edge * v21);
63 v23 -= edge * (edge * v23);
138 v[ 0 ].first.set( -hex, -hey, -hez );
139 v[ 0 ].second.set( -hex, hey, -hez );
141 v[ 1 ].first.set( -hex, -hey, hez );
142 v[ 1 ].second.set( -hex, hey, hez );
144 v[ 2 ].first.set( hex, -hey, hez );
145 v[ 2 ].second.set( hex, hey, hez );
147 v[ 3 ].first.set( hex, -hey, -hez );
148 v[ 3 ].second.set( hex, hey, -hez );
152 v[ 4 ].first.set( -hex, -hey, -hez );
153 v[ 4 ].second.set( -hex, -hey, hez );
155 v[ 5 ].first.set( -hex, -hey, hez );
156 v[ 5 ].second.set( hex, -hey, hez );
158 v[ 6 ].first.set( hex, -hey, -hez );
159 v[ 6 ].second.set( hex, -hey, hez );
161 v[ 7 ].first.set( -hex, -hey, -hez );
162 v[ 7 ].second.set( hex, -hey, -hez );
166 v[ 8 ].first.set( -hex, hey, -hez );
167 v[ 8 ].second.set( -hex, hey, hez );
169 v[ 9 ].first.set( -hex, hey, hez );
170 v[ 9 ].second.set( hex, hey, hez );
172 v[ 10].first.set( hex, hey, -hez );
173 v[ 10].second.set( hex, hey, hez );
175 v[ 11].first.set( -hex, hey, -hez );
176 v[ 11].second.set( hex, hey, -hez );
204 agx::Real a = 2 * ( dir * R ) / segmentLengthSq;
211 roots = std::sqrt( roots );
237 return Q1Found || Q2Found;
245 agx::Real lengthInPlane = planeNormal * ( B - A );
250 agx::Real s = ( planeNormal * ( planeOrigin - A ) ) / lengthInPlane;
251 Q = A + ( B - A ) * s;
252 return inBound( s, 0 - nearEndsThreshold, 1 + nearEndsThreshold, 0 );
263 agx::Real l2 = ( intersectionPoint - circleOrigin ).length2();
265 return l2 < circleRadius * circleRadius && !
agx::equalsZero( l2-circleRadius*circleRadius, nearEndsThreshold*2 ) ;
290 : m_start( start ), m_end( end )
292 m_normalized = end-start;
306 for (
int i = 0; i < 3; ++i ) {
307 if (m_normalized[i] > max) {
309 max = m_normalized[i];
321 m_normalized = m_end-m_start;
329 negateWhereNormalEntriesAreZero( edgeStart );
330 negateWhereNormalEntriesAreZero( edgeEnd );
339 return agx::Vec3( edge[ 0 ] == 0 ? value : 0, edge[ 1 ] == 0 ? value : 0, edge[ 2 ] == 0 ? value : 0 );
347 for (
int i = 0; i < 3; ++i ) {
348 if ( edge[ i ] == 0 ) {
349 oppositeEdgeStart[ i ] *= -1;
350 oppositeEdgeEnd[ i ] *= -1;
360 void negateWhereNormalEntriesAreZero(
agx::Vec3& v )
const
362 v[ 0 ] *=
agx::Real(m_normalized[ 0 ] == 0 ? -1 : 1);
363 v[ 1 ] *=
agx::Real(m_normalized[ 1 ] == 0 ? -1 : 1);
364 v[ 2 ] *=
agx::Real(m_normalized[ 2 ] == 0 ? -1 : 1);
411 agx::Vec3 radialDir = shapeContactPosition;
450 uint8_t vertexIndex = localEdgeIndex;
452 vertexIndex = (uint8_t)((localEdgeIndex + 1)%3);
462 startEdgeIndex = (uint8_t)((startEdgeIndex + 1)%3);
464 startEdgeIndex = (uint8_t)((startEdgeIndex + 2)%3);
466 return startEdgeIndex;
471 uint8_t localEdgeIndex = 0;
472 if ( oppositeVertexIndex > iteratedVertexIndex )
474 if ( oppositeVertexIndex == 2 )
476 if ( iteratedVertexIndex == 0 )
481 else if ( oppositeVertexIndex == 1 )
486 if ( oppositeVertexIndex == 1 )
491 else if ( oppositeVertexIndex == 0 )
493 if ( iteratedVertexIndex == 2 )
499 return localEdgeIndex;
524 triangleIteratorVertex++;
526 while ( triangleIteratorVertex.
isValid() && !triangleIteratorVertex.
atEnd() ) {
530 if ( tempTriangleIndex == triangleIndex )
541 if ( tempTriangleIndex != triangleIndex )
546 size_t localVertexIndex = 0;
551 localVertexIndex = 0;
557 localVertexIndex = 1;
563 localVertexIndex = 2;
567 triangleIteratorVertex++;
590 bool secondIsVerified =
false;
591 uint8_t localEdgeIndex = 0;
592 if ( tempAngle2 < tempAngle1)
600 tempAngle1 = tempAngle2;
602 secondIsVerified =
true;
607 if ( tempAngle1 < angle )
609 if ( !secondIsVerified )
615 triangleIteratorVertex++;
620 tempNewTriangleStartIndex = tempTriangleIndex;
621 tempNewEdgeLocalStartIndex = localEdgeIndex;
628 triangleIteratorVertex++;
634 tempNewTriangleStartIndex = triangleIndex;
635 tempNewEdgeLocalStartIndex = edgeIndex;
663 if ( dist - removedDist < 0 )
666 t = (dist - removedDist)/dist;
673 for (
size_t i = 0; i < newContactShapeTranslatesB.
size(); ++i )
675 newContactShapeTranslates.
push_back( newContactShapeTranslatesB[i] );
676 newTriangleIndices.
push_back( newTriangleIndicesB[i] );
677 newEdgeIndices.
push_back( newEdgeIndicesB[i] );
Class for more intuitive access to the Mesh's mesh data.
agx::Vec3 getVertex(uint_fast8_t localVertexIndex) const
size_t getGlobalVertexIndex(uint_fast8_t localVertexIndex) const
Returns the global index of the vertex.
agx::Vec3 getNormal() const
This function returns the triangle normal (as stored in the collision mesh data).
bool hasHalfEdgePartner(uint_fast8_t localEdgeIndex) const
size_t getTriangleIndex() const
Implementations.
const Triangle getHalfEdgePartner(uint_fast8_t localEdgeIndex) const
Class in order to circulate over the edges connected to a Triangle's vertex.
const Triangle getTriangle() const
uint_fast8_t getLocalEdgeIndex() const
Mesh is a common base class for triangle meshes, such as Mesh or HeightField.
VertexEdgeCirculator createVertexEdgeCirculator(size_t triangleIndex, uint_fast8_t localVertexIndex) const
Creates an VertexEdgeCirculator pointing to this Triangle and a Voronoi region.
const Triangle getTriangle(size_t triangleIndex) const
agx::Vec3 getTriangleVertex(size_t triangleIndex, uint_fast8_t localVertexIndex) const
Returns one of the three vertices in a triangle.
AffineMatrix4x4T< T > & setRotate(const QuatT< T > &q)
Set the rotational part of the matrix using the specified quaternion leaving the translational part u...
AffineMatrix4x4T< T > & setTranslate(const Vec3T< T > &t)
Set the translational part of the matrix using the vector t.
Real normalize()
Normalize the vector so that it has length unity.
Real distance2(const Vec3T &v2) const
Squared distance to another vector.
static Vec3T mul(const Vec3T &lhs, const Vec3T &rhs)
Element-wise-multiplication.
Real distance(const Vec3T &v2) const
Distance to another vector.
Real length2() const
Length squared of the vector = vec .
A class holding 4 dimensional vectors and providing basic arithmetic.
void push_back(const T &value)
void push_back(const T2 &value)
The agxSDK namespace contain classes to bridge the collision detection system and the dynamical simul...
static uint8_t getEdgeStartLocalVertexIndex(const uint8_t localEdgeIndex, const bool atBegin)
static bool pointInsideCircle(const agx::Vec3 &point, const agx::Vec3 &circleOrigin, agx::Real radius)
static void copyVectors(agx::Vec3Vector &newContactShapeTranslates, const agx::Vec3Vector &newContactShapeTranslatesB, agx::Vector< size_t > &newTriangleIndices, const agx::Vector< size_t > &newTriangleIndicesB, agx::Vector< size_t > &newEdgeIndices, const agx::Vector< size_t > &newEdgeIndicesB)
static bool findPlaneLineSegmentIntersection(const agx::Vec3 &A, const agx::Vec3 &B, const agx::Vec3 &planeOrigin, const agx::Vec3 &planeNormal, agx::Real nearEndsThreshold, agx::Vec3 &Q)
static agx::AffineMatrix4x4 getFuturePosition(const agx::Vec3 &velocity, const agx::Vec3 &angularVelocity, const agx::Vec3 &position, const agx::Quat &rotation, agx::Real time)
static bool inBound(agx::Real val, agx::Real boundLower, agx::Real boundUpper, agx::Real threshold=agx::Real(1E-6))
static bool findSegmentCircleIntersection3D(const agx::Vec3 &A, const agx::Vec3 &B, const agx::Vec3 &circleOrigin, const agx::Vec3 &circleNormal, agx::Real circleRadius, agx::Real nearEndsThreshold, agx::Vec3 &intersectionPoint)
static uint8_t getLocalEdgeIndexFromVertexIndices(const size_t iteratedVertexIndex, const size_t oppositeVertexIndex)
static agx::Vec3 calculateCylinderOffset(const agx::Vec3 &shapeEdge, const agx::Vec3 &shapeContactPosition, agx::Real radius)
static agx::Real findAdjustmentForMeshEdge(const agx::Vec3 &lineEndW, const agx::Vec3 &lineStartW, const agx::Vec3 &edgeStart, const agx::Vec3 &edgeEnd, agx::Real lineRadius)
Shorten the movement range due to neighboring triangles.
static agx::Vec3 calculateMeshOffset(const agxCollide::Mesh *mesh, const size_t triangleIndex, const uint8_t edgeIndex, const agx::Vec3 &, const agx::Real radius)
static bool findSegmentCircleIntersections2D(const agx::Vec3 &A, const agx::Vec3 &B, const agx::Vec3 &circlePos, agx::Real radius, agx::Vec3 &Q1, agx::Vec3 &Q2, bool &Q1Found, bool &Q2Found, const agx::Real epsilon=agx::AGX_EQUIVALENT_EPSILON)
static uint8_t getEdgeEndLocalVertexIndex(const uint8_t localEdgeIndex, const bool atBegin)
static agx::Real scalarTripleProduct(const agx::Vec3 &p, const agx::Vec3 &q, const agx::Vec3 &r)
static void fillEdgeVector(agx::Vector< std::pair< agx::Vec3, agx::Vec3 > > &v, const agx::Vec3 &halfExtent)
static agx::Vec3 getProjection(const agx::Vec3 contactPoint, agx::Vec3 edge, bool normalizedEdge=false)
static agx::Real getTotalAngleShapeCoordinates(agx::Vec3 edge, agx::Vec3 contactToCenter, const agx::Vec3 &pos1, const agx::Vec3 &pos2, const agx::Vec3 &pos3, bool &onSameEdge)
static agx::Vec3 calculateBoxOffset(const agx::Vec3 &shapeEdge, const agx::Vec3 &shapeContactPosition, agx::Real radius)
static agx::Vec3 getSigned(const agx::Vec3 &v)
static agx::Real findDistanceFromPointToLine(const agx::Vec3 &L1, const agx::Vec3 &L2, const agx::Vec3 &P)
static void findMostParallelEdgeAmongNeighboringTriangles(const agxCollide::Mesh *mesh, const agx::Vec3 &, const size_t triangleIndex, const uint8_t edgeIndex, size_t &tempNewTriangleStartIndex, size_t &tempNewEdgeLocalStartIndex, const bool atBegin)
Vec3T< Real > Vec3
The object holding 3 dimensional vectors and providing basic arithmetic.
bool geq(double a, double b, double eps=(double) AGX_EQUIVALENT_EPSILON)
T1 clamp(T1 v, T2 minimum, T3 maximum)
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)