AGX Dynamics 2.41.3.0
Loading...
Searching...
No Matches
MergeSplitUtils.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#pragma once
18
21
22#define REPORT_SYSTEM_JOB_ENABLE 1
23#if REPORT_SYSTEM_JOB_ENABLE
24#include <agxUtil/TimerBlock.h>
25#include <agx/Thread.h>
26#include <agx/macros.h>
27
28// Since winbase.h defines an IGNORE macro, but we like to define an ENUM with a IGNORE value
29#ifdef WIN32
30#ifdef IGNORE
31#undef IGNORE
32#endif
33#endif
34
35#define REPORT_SYSTEM_JOB_EX( str )\
36 auto sjrtb = agxUtil::TimerBlock( []( agx::UInt64 start, agx::UInt64 stop )\
37 {\
38 agx::Thread::getCurrentThread()->reportSystemJob( start, stop, str );\
39 } )
40
41#define REPORT_SYSTEM_JOB\
42 const char* AGX_CONCAT(agx_functionName,__LINE__) = __FUNCTION__; \
43 auto sjrtb = agxUtil::TimerBlock( [AGX_CONCAT(agx_functionName,__LINE__)]( agx::UInt64 start, agx::UInt64 stop )\
44 {\
45 agx::Thread::getCurrentThread()->reportSystemJob( start, stop, AGX_CONCAT(agx_functionName,__LINE__) );\
46 } )
47#else
48#define REPORT_SYSTEM_JOB_EX( str )
49#define REPORT_SYSTEM_JOB
50#endif
51
52#include <agxWire/Node.h>
53
54namespace agxWire
55{
56 class WireDistanceCompositeConstraint;
57}
58
59namespace agxSDK
60{
61 namespace MergeSplitUtils
62 {
72 const agx::Vec3& cmPos,
73 const agx::Vec3& linVel,
74 const agx::Vec3& angVel )
75 {
76 return ( linVel + ( angVel ^ ( point - cmPos ) ) );
77 }
78
90 const agx::Vec3f& normal,
91 const agx::Vec3& cmPos,
92 const agx::Vec3& linVel,
93 const agx::Vec3& angVel )
94 {
95 return -( agx::Vec3( normal ) * calculateRelativePointVelocity( point, cmPos, linVel, angVel ) );
96 }
97
109 const agx::Vec3& relVel,
110 const agx::Vec3& cmPos1,
111 const agx::Vec3& angVel1,
112 const agx::Vec3& cmPos2,
113 const agx::Vec3& angVel2 )
114 {
115 return ( relVel + ( angVel1 ^ ( point - cmPos1 ) ) + ( ( point - cmPos2 ) ^ angVel2 ) );
116 }
117
130 const agx::Vec3f& normal,
131 const agx::Vec3& relVel,
132 const agx::Vec3& cmPos1,
133 const agx::Vec3& angVel1,
134 const agx::Vec3& cmPos2,
135 const agx::Vec3& angVel2 )
136 {
137 return -( agx::Vec3( normal ) * calculateRelativePointVelocity( point, relVel, cmPos1, angVel1, cmPos2, angVel2 ) );
138 }
139
150 const MergeSplitHandler* handler = nullptr );
151
153 {
155 : shouldSplit( false ), rbTop( nullptr ), rbBottom( nullptr ) {}
159 };
160
173 const agx::RigidBody* rb,
174 const agx::RigidBody* otherRb,
175 const agx::Vec3& externalForces,
176 const agx::Vec3& externalTorques,
177 const agx::Vec3& gravity,
178 const agxSDK::MergeSplitHandler& handler );
179
180 template<typename T>
182
197 template<typename T>
198 void collectConnectingEdges( const T& referenceEdge,
199 agx::MergedBody::EdgeInteraction::InteractionTag edgeTag,
200 agx::Bool bounceAtNonSplittableBodies,
201 const agx::MergedBody& mergedBody,
202 const MergeSplitHandler& handler,
204 {
205 using VisitedContainer = agx::HashSet<const agx::RigidBody*>;
206 using SymmetricRigidBodyPtrPair = agx::SymmetricPair<const agx::RigidBody*>;
207 using VisitedPairContainer = agx::HashSet<SymmetricRigidBodyPtrPair>;
208 using BfsQueueContainer = std::queue<const agx::RigidBody*>;
209
210 VisitedContainer visited;
211 VisitedPairContainer visitedPairs;
212 BfsQueueContainer bfsQueue;
213
214 const auto visit = [&visited, &bfsQueue]( const agx::RigidBody* rb )
215 {
216 agxAssert( !visited.contains( rb ) );
217 visited.insert( rb );
218 bfsQueue.push( rb );
219 };
220
221 const auto visitedPair = [&visitedPairs]( const agx::RigidBody* rb1, const agx::RigidBody* rb2 ) -> agx::Bool
222 {
223 SymmetricRigidBodyPtrPair rb1Rb2Pair( rb1, rb2 );
224 if ( visitedPairs.contains( rb1Rb2Pair ) )
225 return true;
226
227 visitedPairs.insert( rb1Rb2Pair );
228
229 return false;
230 };
231
232 const auto pop = [&bfsQueue]() -> const agx::RigidBody*
233 {
234 agxAssert( !bfsQueue.empty() );
235 auto front = bfsQueue.front();
236 bfsQueue.pop();
237 return front;
238 };
239
240 visit( referenceEdge.getRigidBody1() );
241 while ( !bfsQueue.empty() ) {
242 const auto rb = pop();
243 const auto neighbors = mergedBody.getNeighbors( rb );
244
245 agxAssert( neighbors != nullptr );
246 for ( const auto neighbor : *neighbors ) {
247 if ( visitedPair( neighbor, rb ) )
248 continue;
249
250 const auto edges = mergedBody.getEdges( neighbor, rb );
251 agxAssert( edges != nullptr );
252 auto oneHasEdgeTag = false;
253 for ( const auto& edge : *edges ) {
254 const auto edgeHasTag = edge->isTagged( edgeTag );
255 oneHasEdgeTag = oneHasEdgeTag || edgeHasTag;
256 if ( edge != &referenceEdge && edgeHasTag ) {
257 agxAssert( !result.contains( edge ) );
258 result.push_back( edge->template as<T>() );
259 }
260 }
261
262 // Continue search if rb<->neighbor has the given tag and hasn't already
263 // been visited. Stop if:
264 // bounceAtNonSplittableBodies && !handler.maySplit( neighbor )
265 const auto visitThisNeighbor = neighbor != nullptr &&
266 oneHasEdgeTag &&
267 ( !bounceAtNonSplittableBodies || handler.maySplit( neighbor ) ) &&
268 !visited.contains( neighbor );
269 if ( visitThisNeighbor )
270 visit( neighbor );
271 }
272 }
273 }
274
275 class WireSegmentMergedState;
277
294 {
295 public:
304
305 public:
307 {
308 FREE = 1 << 0,
309 MERGED = 1 << 1,
310 IGNORE = 1 << 2
311 };
312 using State = agx::BitState<EState, agx::UInt32>;
313
314 public:
319 WireSegmentMergedState( const agxWire::WireDistanceCompositeConstraint* wire );
320
327
332
337
342
347
352
357
362
363 private:
364 const agxWire::WireDistanceCompositeConstraint* m_wire;
365 agx::MergedBody* m_mergedBody;
366 State m_state;
370 };
371 }
372}
#define AGXPHYSICS_EXPORT
#define m_size
Definition: agx/Vector.h:429
Base class for a merge split algorithm handling a set of merged bodies.
agx::Bool maySplit(const agx::RigidBody *rb) const
Wire merged state segment along a wire.
WireSegmentMergedState(const agxWire::WireDistanceCompositeConstraint *wire)
Construct given wire constraint.
agxWire::NodeConstIterator begin() const
agxWire::NodeConstIterator construct(agxWire::NodeConstIterator it)
Initialize using iterator to first node (end of previous segment).
static WireSegmentMergedStateContainer create(const agxWire::Wire *wire)
Creates vector of WireMergedState segments along the wire starting from first lumped node to (and inc...
agxWire::BodyFixedNode * front() const
agxWire::NodeConstIterator end() const
agx::BitState< EState, agx::UInt32 > State
The body fixed node is attached to a body at a given offset.
Class defining a node that is part of a wire.
Definition: agxWire/Node.h:512
Interface and placeholder of controllers/helpers for wires.
Definition: Wire.h:62
Inheritance with partial specialization due to bug with ref_ptr containers.
Definition: agx/HashSet.h:670
Structure holding several "normal" rigid bodies.
Definition: MergedBody.h:56
const EdgeInteractionRefContainer * getEdges(const agx::RigidBody *rb1, const agx::RigidBody *rb2) const
const agx::RigidBodyPtrVector * getNeighbors(const agx::RigidBody *rb) const
GeometryContactEdgeInteraction()
Default constructor used by serialization.
The rigid body class, combining a geometric model and a frame of reference.
Definition: RigidBody.h:52
A std::pair, with both elements of the same type, and symmetric so (a, b) == (b, a)
Definition: SymmetricPair.h:32
Vector containing 'raw' data.
Definition: agx/Vector.h:246
void push_back(const T2 &value)
Definition: agx/Vector.h:715
bool contains(const T2 &element) const
Test if the vector contains a certain element.
Definition: agx/Vector.h:843
#define agxAssert(expr)
Definition: debug.h:143
#define AGX_FORCE_INLINE
Definition: macros.h:58
AGXPHYSICS_EXPORT ExternalForceSplitResult shouldSplitGivenExternalForce(agxSDK::MergedBodySolverData::ForceFrame edgeStrength, const agx::RigidBody *rb, const agx::RigidBody *otherRb, const agx::Vec3 &externalForces, const agx::Vec3 &externalTorques, const agx::Vec3 &gravity, const agxSDK::MergeSplitHandler &handler)
Checks if two bodies should split given edge strength force frame and external forces.
void collectConnectingEdges(const T &referenceEdge, agx::MergedBody::EdgeInteraction::InteractionTag edgeTag, agx::Bool bounceAtNonSplittableBodies, const agx::MergedBody &mergedBody, const MergeSplitHandler &handler, CollectConnectingEdgesPtrContainer< T > &result)
Collects edges of given type/tag that are connected within a merged body.
AGXPHYSICS_EXPORT agxSDK::MergedBodySolverData::ForceFrame calculateContactForceFrame(const agx::RigidBody *refRb, const agx::MergedBody::GeometryContactEdgeInteraction *contactEdge, const MergeSplitHandler *handler=nullptr)
Calculates force frame (edge strength) given reference rigid body, contact edge and optionally an mer...
agx::Vec3 calculateRelativePointVelocity(const agx::Vec3 &point, const agx::Vec3 &cmPos, const agx::Vec3 &linVel, const agx::Vec3 &angVel)
Calculates velocity at a given point given center of mass position, linear- and angular velocity.
agx::Real calculateImpactSpeed(const agx::Vec3 &point, const agx::Vec3f &normal, const agx::Vec3 &cmPos, const agx::Vec3 &linVel, const agx::Vec3 &angVel)
Calculates impact speed of one body given contact point and normal.
The agxSDK namespace contain classes to bridge the collision detection system and the dynamical simul...
Definition: Constraint.h:31
Implements a Wire model with adaptive resolution.
Definition: MergedBody.h:40
NodeContainer::const_iterator NodeConstIterator
Definition: agxWire/Node.h:57
uint32_t UInt32
Definition: Integer.h:32
Vec3T< Real > Vec3
The object holding 3 dimensional vectors and providing basic arithmetic.
Definition: agx/Vec3.h:36
bool Bool
Definition: Integer.h:40
uint64_t UInt
Definition: Integer.h:27
double Real
Definition: Real.h:42
Force frame where the resultant force is u + v + n.