AGX Dynamics 2.42.1.1
Loading...
Searching...
No Matches
LinkedStructure.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
19#include <agxSDK/Assembly.h>
23
24#include <agx/BitState.h>
25
26namespace agx
27{
28 class InternalData;
29}
30
31namespace agxSDK
32{
34
41 {
42 public:
47
51 static const LinkedStructure* get(const agxCollide::Geometry* geometry);
52
57
61 static const LinkedStructure* get(const agx::RigidBody* body);
62
63 public:
68 virtual void setMaterial( agx::Material* material );
69
73 virtual agx::Material* getMaterial() const;
74
78 virtual agx::UInt32 getUniqueId() const;
79
84
90 virtual void setEnableCollisions( agx::RigidBody* rb, agx::Bool enable );
91
95 virtual agx::Bool getEnableCollisions( const agx::RigidBody* rb ) const;
96
102 virtual void setEnableCollisions( agxCollide::Geometry* geometry, agx::Bool enable );
103
107 virtual agx::Bool getEnableCollisions( const agxCollide::Geometry* geometry ) const;
108
113 virtual void addGroup( agx::UInt32 id );
114
119 virtual void removeGroup( agx::UInt32 id );
120
124 virtual agx::Bool hasGroup( agx::UInt32 id ) const;
125
130 virtual void addGroup( const agx::Name& name );
131
136 virtual void removeGroup( const agx::Name& name );
137
141 virtual agx::Bool hasGroup( const agx::Name& name ) const;
142
147
155 virtual void setLinearVelocityDamping( const agx::Vec3& linearVelocityDamping );
156
161
169 virtual void setAngularVelocityDamping( const agx::Vec3& angularVelocityDamping );
170
175
180 virtual agx::Real getRestLength() const;
181
187
193 virtual agx::Real getMass() const;
194
199 virtual agx::Real getRestVolume() const;
200
207 virtual agx::Vec3 findPoint( agx::Real restLengthFromStart ) const;
208
215 virtual agx::Vec3 findPoint( const agx::Vec3& worldPoint ) const;
216
224 virtual agx::Real findCurrentLength( agx::Real restLengthFromStart ) const;
225
231 virtual agx::Real findRestLength( agx::Real currentLengthFromStart ) const;
232
239 virtual agx::Real findRestLengthTo( const agx::Vec3& worldPoint ) const;
240
246 virtual agx::Real findRestLengthTo( const agxSDK::LinkedSegment* segment ) const;
247
253 virtual agx::Bool rebind();
254
263
270
274 template<typename T>
275 T* getComponent() const;
276
281
282
287
291 agx::UInt getSegmentIndex( const agx::RigidBody* rb ) const;
292
296 const agxSDK::LinkedSegmentContainer& getSegmentsContainer() const;
297
298 public:
300
306 void addNotification( agxSDK::Simulation* simulation ) final override;
307
313 void removeNotification( agxSDK::Simulation* simulation ) final override;
314
315 using Assembly::addNotification;
316 using Assembly::removeNotification;
317
318 public:
324 struct IdData
325 {
329 IdData() : id( agx::InvalidIndex ), name( "" ) {}
330
334 IdData( agx::UInt32 id ) : id( id ), name( "" ) {}
335
339 IdData( const agx::Name& name ) : id( agx::InvalidIndex ), name( name ) {}
340
344 agx::Bool operator== ( const IdData& other ) const { return id == other.id && name == other.name; }
345
349 agx::Bool operator!= ( const IdData& other ) const { return !(*this == other); }
350
353 };
354
355 protected:
360 virtual void onAddNotification( agxSDK::Simulation* simulation );
361
366 virtual void onRemoveNotification( agxSDK::Simulation* simulation );
367
371 virtual void onMaterialNew();
372
376 virtual void onGroupAdd( const IdData& group );
377
381 virtual void onGroupRemove( const IdData& group );
382
386 virtual void onSetEnableCollisions( agxCollide::Geometry* geometry, agx::Bool enable );
387
391 virtual void onPreCollideStep();
392
396 virtual void onPreStep();
397
401 virtual void onPostStep();
402
406 virtual void onLastStep();
407
413 virtual void onPostIntegrate();
414
415 protected:
419 template<typename T>
420 static T* getT( agx::RigidBody* rb );
421
425 template<typename T>
426 static const T* getT( const agx::RigidBody* rb );
427
428 protected:
433
438
445 void add( LinkedSegment* segment );
446
450 agx::UInt getNumSegments() const;
451
456 template<typename T>
457 LinkedSegmentRange<T> getSegments() const;
458
465 template<typename T>
466 LinkedSegmentRange<T> getSegments( agx::UInt beginIndex, agx::UInt endIndex ) const;
467
471 LinkedSegment* getSegment( agx::UInt index ) const;
472
476 template<typename T>
477 T* getSegment( agx::Real restLengthFromStart ) const;
478
483 template<typename T>
484 T* findSegment( const agx::Vec3& worldPoint ) const;
485
489 template<typename ObjT>
490 LinkedSegment* getSegment( const ObjT* rb ) const;
491
495 template<typename T>
496 LinkedSegmentIterator<T> getSegmentIterator( agx::UInt index, agx::Bool boundaryless = false ) const;
497
501 template<typename T, typename ObjT>
502 LinkedSegmentIterator<T> getSegmentIterator( const ObjT* rb, agx::Bool boundaryless = false ) const;
503
507 LinkedStructureObjectData* getData( const agx::RigidBody* rb ) const;
508
512 std::tuple<agx::Vec3, LinkedSegment*> findPointAndSegment( const agx::Vec3& worldPoint ) const;
513
514 private:
515 // Events from the simulation.
516 friend class Simulation;
517
518 enum SimulationEvent
519 {
520 PRE_COLLIDE_STEP,
521 PRE_STEP,
522 POST_STEP,
523 LAST_STEP,
524 POST_INTEGRATE,
525 };
526
527 using IdDataContainer = agx::Vector<IdData>;
528
529 private:
530 void trigger( SimulationEvent simulationEvent );
531 void addGroup( const IdData& group );
532 void removeGroup( const IdData& group );
533 agx::Bool hasGroup( const IdData& group ) const;
534
536 friend class agx::InternalData;
540 agx::Referenced* getInternalData() const;
541
545 void setInternalData( agx::Referenced* data );
547
548 private:
549 agx::Uuid m_uniqueId;
550 agx::Uuid m_disabledCollisionsId;
551 LinkedSegmentContainer m_segments;
552 agx::MaterialRef m_material;
553 IdDataContainer m_externallyAddedGroups;
555 agx::Vec3 m_linearVelocityDamping;
556 agx::Vec3 m_angularVelocityDamping;
557 agx::ref_ptr<agx::Referenced> m_internalData;
558 };
559
560 template<typename T>
561 T* LinkedStructure::getT( agx::RigidBody* rb )
562 {
563 auto data = LinkedStructureObjectData::get<LinkedStructureObjectData>( rb );
564 return data != nullptr && data->linkedStructure != nullptr ? data->linkedStructure->template asSafe<T>() : nullptr;
565 }
566
567 template<typename T>
568 const T* LinkedStructure::getT( const agx::RigidBody* rb )
569 {
570 return LinkedStructure::getT<T>( const_cast<agx::RigidBody*>( rb ) );
571 }
572
573 template<typename T>
574 T* LinkedStructure::getComponent() const
575 {
576 for ( auto component : m_components ) {
577 auto typed = component->template asSafe<T>();
578 if ( typed != nullptr )
579 return typed;
580 }
581
582 return nullptr;
583 }
584
585 inline const LinkedSegmentContainer& LinkedStructure::getSegmentsContainer() const
586 {
587 return m_segments;
588 }
589
590 inline agx::UInt LinkedStructure::getNumSegments() const
591 {
592 return m_segments.size();
593 }
594
595 template<typename T>
596 LinkedSegmentRange<T> LinkedStructure::getSegments() const
597 {
599 LinkedSegmentIterator<T>::end( m_segments ) );
600 }
601
602 template<typename T>
603 LinkedSegmentRange<T> LinkedStructure::getSegments( agx::UInt beginIndex, agx::UInt endIndex ) const
604 {
605 return LinkedSegmentRange<T>( getSegmentIterator<T>( beginIndex ),
606 getSegmentIterator<T>( endIndex ) );
607 }
608
609 inline LinkedSegment* LinkedStructure::getSegment( agx::UInt index ) const
610 {
611 agxAssert( index < m_segments.size() );
612 return m_segments[ index ];
613 }
614
615 template<typename T>
616 T* LinkedStructure::getSegment( agx::Real restLengthFromStart ) const
617 {
618 if ( m_segments.empty() )
619 return nullptr;
620
621 if ( restLengthFromStart <= 0.0 )
622 return m_segments.front()->template as<T>();
623
624 agx::Real restLengthAlongStructure = 0.0;
625 for ( auto segment : this->template getSegments<T>() ) {
626 if ( restLengthAlongStructure + segment->getLength() < restLengthFromStart )
627 restLengthAlongStructure += segment->getLength();
628 else
629 return segment->template as<T>();
630 }
631
632 return m_segments.back()->template as<T>();
633 }
634
635 template<typename T>
636 T* LinkedStructure::findSegment( const agx::Vec3 &worldPoint ) const
637 {
638 auto [point, segment] = findPointAndSegment( worldPoint );
639 return segment->template as<T>();
640 }
641
642 template<>
643 inline LinkedSegment* LinkedStructure::getSegment( const agx::RigidBody* rb ) const
644 {
645 auto index = getSegmentIndex( rb );
646 return index != agx::InvalidIndex ?
647 m_segments[ index ] :
648 nullptr;
649 }
650
651 inline agx::UInt LinkedStructure::getSegmentIndex( const agx::RigidBody* rb ) const
652 {
653 auto data = getData( rb );
654 return data != nullptr && data->segment != nullptr && data->linkedStructure == this ?
655 data->segment->getIndex() :
657 }
658
659 template<typename T>
660 LinkedSegmentIterator<T> LinkedStructure::getSegmentIterator( agx::UInt index, agx::Bool boundaryless /* = false */ ) const
661 {
662 return LinkedSegmentIterator<T>( index, boundaryless, m_segments );
663 }
664
665 template<typename T, typename ObjT>
666 LinkedSegmentIterator<T> LinkedStructure::getSegmentIterator( const ObjT* rb, agx::Bool boundaryless /* = false */ ) const
667 {
668 auto segment = this->getSegment( rb );
669 if ( segment == nullptr )
670 return LinkedSegmentIterator<T>::end( m_segments );
671 return getSegmentIterator<T>( segment->getIndex(), boundaryless );
672 }
673
674 inline LinkedStructureObjectData* LinkedStructure::getData( const agx::RigidBody* rb ) const
675 {
676 auto data = LinkedStructureObjectData::get<LinkedStructureObjectData>( rb );
677 // Accepting data when linkedStructure == null since it can be considered implicitly
678 // related to this linked structure (data->linkedStructure = this to be made).
679 return data != nullptr && ( data->linkedStructure == this || data->linkedStructure == nullptr ) ?
680 data :
681 nullptr;
682 }
683
684 inline agx::Referenced* LinkedStructure::getInternalData() const
685 {
686 return m_internalData;
687 }
688}
#define AGX_DECLARE_POINTER_TYPES(type)
Definition: Referenced.h:254
#define AGXSTREAM_DECLARE_SERIALIZABLE(T)
Use this in a Serializable class to add the required methods Important: Use full namespace in the dec...
Definition: Serializable.h:207
#define AGXPHYSICS_EXPORT
The geometry representation used by the collision detection engine.
Definition: Geometry.h:92
Collection of geometry group names and id's.
An assembly is a collection of basic simulation objects, such as rigid bodies, constraints,...
Definition: Assembly.h:70
Optionally unbounded linked structure segment iterator object to iterate segments in a SegmentStructu...
Segment range object for linked structure.
Segment object in a linked structure.
Definition: LinkedSegment.h:39
Base implementation of a component (e.g., specific functionality) in linked structures.
Basic implementation of any structure where bodies are linked/constrained together in a well defined ...
LinkedStructure()
Hidden default constructor.
virtual void setMaterial(agx::Material *material)
Assign material to all segments in this linked structure.
virtual void removeGroup(agx::UInt32 id)
Remove group id from all segments in this linked structure.
virtual agx::Real findRestLengthTo(const agx::Vec3 &worldPoint) const
Given any world point, find a center point on this structure that is closest to the given worldPoint ...
virtual agxCollide::GroupIdCollection findGroupIdCollection() const
static const LinkedStructure * get(const agx::RigidBody *body)
virtual void onSetEnableCollisions(agxCollide::Geometry *geometry, agx::Bool enable)
Called when collision state changed for given geometry.
virtual void setLinearVelocityDamping(const agx::Vec3 &linearVelocityDamping)
Assigns linear velocity damping to all segments in this linked structure.
virtual void onLastStep()
Called on simulation last step event - after user lastStep.
virtual agx::Bool getEnableCollisions(const agxCollide::Geometry *geometry) const
virtual void removeGroup(const agx::Name &name)
Remove group name from all segments in this linked structure.
virtual void addGroup(agx::UInt32 id)
Add group id to all segments in this linked structure.
virtual agx::Bool rebind()
Make the current relative positions of all nodes the rest state.
virtual agx::Bool removeComponent(agxSDK::LinkedStructureComponent *component)
Remove an added component from this linked structure.
virtual agx::Bool getEnableCollisions(const agx::RigidBody *rb) const
virtual void onAddNotification(agxSDK::Simulation *simulation)
Called when addNotification is executed when this linked structure is added to the simulation.
virtual void onPreStep()
Called on simulation pre step event - after user preStep.
static const LinkedStructure * get(const agxCollide::Geometry *geometry)
virtual agx::Vec3 findPoint(agx::Real restLengthFromStart) const
Finds center point on this structure given rest length from the start.
virtual void onGroupRemove(const IdData &group)
Called when an existing group has been removed.
virtual void onRemoveNotification(agxSDK::Simulation *simulation)
Called when removeNotification is executed when this linked structure is removed from the simulation.
virtual agx::Bool addComponent(agxSDK::LinkedStructureComponent *component)
Add new component to this linked structure.
virtual void setEnableCollisions(agxCollide::Geometry *geometry, agx::Bool enable)
Enable/disable collisions between the geometry and all segments of this linked structure.
virtual agx::Real getCurrentLength() const
Calculates and returns the total length of this linked structure, at current state.
void removeNotification(agxSDK::Simulation *simulation) final override
Called when this linked structure is added to the simulation.
agxSDK::LinkedStructureComponent * getComponent(const agx::Name &name) const
static LinkedStructure * get(agx::RigidBody *body)
virtual agx::Real getRestLength() const
Calculates and returns the total length of this linked structure, at rest.
virtual agx::Real findCurrentLength(agx::Real restLengthFromStart) const
Calculates the current length of a given rest length.
virtual ~LinkedStructure()
Reference counted object - protected destructor.
virtual void setEnableCollisions(agx::RigidBody *rb, agx::Bool enable)
Enable/disable collisions between the rigid body and all segments of this linked structure.
virtual void onPostStep()
Called on simulation post step event - after user postStep.
std::tuple< agx::Vec3, LinkedSegment * > findPointAndSegment(const agx::Vec3 &worldPoint) const
virtual agx::UInt32 getDisabledCollisionGroupId() const
virtual agx::Real getRestVolume() const
Calculates and returns the total volume of this linked structure, at rest.
agxSDK::LinkedSegmentRange< agxSDK::LinkedSegment > segments()
void add(LinkedSegment *segment)
Add segment to this linked structure.
virtual agx::Bool hasGroup(agx::UInt32 id) const
virtual agx::Real findRestLength(agx::Real currentLengthFromStart) const
Calculates the rest length of a given current length from start.
virtual void addGroup(const agx::Name &name)
Add group name to all segments in this linked structure.
virtual void onPostIntegrate()
Called on simulation post integrate event - when transforms has been updated given current velocities...
virtual agx::Real findRestLengthTo(const agxSDK::LinkedSegment *segment) const
Finds rest length to the start of the given segment.
virtual agx::Bool hasGroup(const agx::Name &name) const
virtual void onPreCollideStep()
Called on simulation pre-collide step event - after user preCollide.
virtual agx::UInt32 getUniqueId() const
virtual agx::Vec3 getAngularVelocityDamping() const
static LinkedStructure * get(agxCollide::Geometry *geometry)
virtual void setAngularVelocityDamping(const agx::Vec3 &angularVelocityDamping)
Assigns angular velocity damping to all segments in this linked structure.
virtual agx::Material * getMaterial() const
virtual agx::Vec3 findPoint(const agx::Vec3 &worldPoint) const
Given any world point, find a center point on this structure that is closest to the given worldPoint.
virtual void onGroupAdd(const IdData &group)
Called when a new group has been added.
LinkedSegment * getSegment(const ObjT *rb) const
void addNotification(agxSDK::Simulation *simulation) final override
Called when this linked structure is added to the simulation.
virtual void onMaterialNew()
Called when a new material has been assigned.
virtual agx::Real getMass() const
Calculates and returns the total mass of this linked structure.
virtual agx::Vec3 getLinearVelocityDamping() const
Simulation is a class that bridges the collision space agxCollide::Space and the dynamic simulation s...
Definition: Simulation.h:131
size_t size() const
Definition: Container.h:134
Main material class which acts as a holder of a Surface Material and a Bulk material.
Definition: Material.h:378
Representation of a name string.
Definition: Name.h:33
Base class providing referencing counted objects.
Definition: Referenced.h:120
The rigid body class, combining a geometric model and a frame of reference.
Definition: RigidBody.h:49
#define agxAssert(expr)
Definition: debug.h:143
#define DOXYGEN_END_INTERNAL_BLOCK()
Definition: macros.h:89
#define DOXYGEN_START_INTERNAL_BLOCK()
Definition: macros.h:88
The agxSDK namespace contain classes to bridge the collision detection system and the dynamical simul...
Definition: Constraint.h:31
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
uint32_t UInt32
Definition: Integer.h:32
bool Bool
Definition: Integer.h:40
uint64_t UInt
Definition: Integer.h:27
double Real
Definition: Real.h:41
AGXCORE_EXPORT const InvalidIndexStruct InvalidIndex
Connection back from bodies, constraints etc.
Group id 'union' of int id and name id.
IdData(agx::UInt32 id)
Construct group given int id where name == "".
IdData(const agx::Name &name)
Construct group given name where id == agx::InvalidIndex.
IdData()
Default constructor, group id is invalid with id == agx::InvalidIndex and name == "".