1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 
19 /*! \file SiconosBulletCollisionManager.hpp
20   \brief Definition of a Bullet-based interaction handler for contact
21   detection.
22 */
23 
24 #ifndef SiconosBulletCollisionManager_h
25 #define SiconosBulletCollisionManager_h
26 
27 #include <MechanicsFwd.hpp>
28 #include <BulletSiconosFwd.hpp>
29 
30 #include <SiconosCollisionManager.hpp>
31 #include <SiconosShape.hpp>
32 #include <SiconosContactor.hpp>
33 
34 #include <map>
35 
36 DEFINE_SPTR(SiconosBulletCollisionManager_impl);
37 
38 
39 enum SiconosBulletDimension
40 {
41   SICONOS_BULLET_3D=0,
42   SICONOS_BULLET_2D=1
43 };
44 
45 struct SiconosBulletOptions
46 {
47 protected:
48   /** serialization hooks
49    */
50   ACCEPT_SERIALIZATION(SiconosBulletOptions);
51 
52 public:
53   SiconosBulletOptions();
54 
55   int dimension;
56   double contactBreakingThreshold;
57   double contactProcessingThreshold;
58   double worldScale;
59   bool useAxisSweep3;
60   bool clearOverlappingPairCache;
61   unsigned int perturbationIterations;
62   unsigned int minimumPointsPerturbationThreshold;
63   bool enableSatConvex;
64   bool enablePolyhedralContactClipping;
65   double Depth2D;
66 };
67 
68 struct SiconosBulletStatistics
69 {
70 protected:
71   /** serialization hooks
72    */
73   ACCEPT_SERIALIZATION(SiconosBulletStatistics);
74 
75 public:
SiconosBulletStatisticsSiconosBulletStatistics76   SiconosBulletStatistics()
77     : new_interactions_created(0)
78     , existing_interactions_processed(0)
79     , interaction_warnings(0)
80     {}
81   int new_interactions_created;
82   int existing_interactions_processed;
83   int interaction_warnings;
84 };
85 
86 class SiconosBulletCollisionManager : public SiconosCollisionManager
87 {
88 protected:
89   /** serialization hooks
90    */
91   ACCEPT_SERIALIZATION(SiconosBulletCollisionManager);
92 
93 protected:
94   SP::SiconosBulletCollisionManager_impl _impl;
95 
96   void initialize_impl();
97 
98   // callback for contact point removal, and a global for context
99   static bool bulletContactClear(void* userPersistentData);
100   static Simulation *gSimulation;
101 
102 public:
103   SiconosBulletCollisionManager();
104   SiconosBulletCollisionManager(const SiconosBulletOptions &options);
105   virtual ~SiconosBulletCollisionManager();
106 
107 protected:
108   bool _with_equality_constraints;
109   SiconosBulletOptions _options;
110   SiconosBulletStatistics _stats;
111 
112   /** Provided so that creation of collision points can be overridden.
113    * See modify_normals.py in examples/Mechanics/Hacks */
114   virtual SP::BulletR makeBulletR(SP::RigidBodyDS ds1, SP::SiconosShape shape1,
115                                   SP::RigidBodyDS ds2, SP::SiconosShape shape2,
116                                   const btManifoldPoint &);
117 
118   /** Provided so that creation of collision points can be overridden.
119    * See modify_normals.py in examples/Mechanics/Hacks */
120   virtual SP::Bullet5DR makeBullet5DR(SP::RigidBodyDS ds1, SP::SiconosShape shape1,
121                                       SP::RigidBodyDS ds2, SP::SiconosShape shape2,
122                                       const btManifoldPoint &);
123 
124   /** Provided so that creation of collision points can be overridden.
125    * See modify_normals.py in examples/Mechanics/Hacks */
126   virtual SP::Bullet2dR makeBullet2dR(SP::RigidBody2dDS ds1, SP::SiconosShape shape1,
127                                       SP::RigidBody2dDS ds2, SP::SiconosShape shape2,
128                                       const btManifoldPoint &);
129 
130   /** Provided so that creation of collision points can be overridden.
131    * See modify_normals.py in examples/Mechanics/Hacks */
132   virtual SP::Bullet2d3DR makeBullet2d3DR(SP::RigidBody2dDS ds1, SP::SiconosShape shape1,
133                                           SP::RigidBody2dDS ds2, SP::SiconosShape shape2,
134                                           const btManifoldPoint &);
135 
136 public:
137   StaticContactorSetID insertStaticContactorSet(
138     SP::SiconosContactorSet cs, SP::SiconosVector position = SP::SiconosVector());
139 
140   bool removeStaticContactorSet(StaticContactorSetID id);
141 
142   void removeBody(const SP::SecondOrderDS& body);
143 
144   void updateInteractions(SP::Simulation simulation);
145 
146   std::vector<SP::SiconosCollisionQueryResult>
147   lineIntersectionQuery(const SiconosVector& start, const SiconosVector& end,
148                         bool closestOnly=false, bool sorted=true);
149 
150   void clearOverlappingPairCache();
151 
options() const152   const SiconosBulletOptions &options() const { return _options; }
statistics() const153   const SiconosBulletStatistics &statistics() const { return _stats; }
resetStatistics()154   void resetStatistics() { _stats = SiconosBulletStatistics(); }
155 
156   /** Set the usage of equality constraints. When the number
157       of objects is huge as in granular material, the usage
158       of equality constraint breaks scalability.
159       This have to be fixed.
160    * \param choice a boolean, default is True.
161    */
useEqualityConstraints(bool choice=true)162   void useEqualityConstraints(bool choice=true)
163   { _with_equality_constraints = choice; };
164 };
165 
166 #endif /* SiconosBulletCollisionManager.hpp */
167