world.h
1 /********************************************************************************
2  * WorldSim -- library for robot simulations *
3  * Copyright (C) 2008-2011 Gianluca Massera <emmegian@yahoo.it> *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
18  ********************************************************************************/
19 
20 #ifndef WORLD_H
21 #define WORLD_H
22 
23 #include "worldsimconfig.h"
24 #include "wobject.h"
25 #include "wquaternion.h"
26 #include <QString>
27 #include <QHash>
28 #include <QSet>
29 #include <QList>
30 #include <QLinkedList>
31 #include <QVector>
32 #include <QPair>
33 #include <QEvent>
34 #include <QTimerEvent>
35 #include <QColor>
36 
37 namespace farsa {
38 
39 class World;
40 class WorldPrivate;
41 class PhyObject;
42 class PhyJoint;
43 class MotorController;
44 
45 //--- this function is required by QSet<NObj> attribute of World class
46 inline uint qHash( const QPair<PhyObject*, PhyObject*>& pair ) {
47 #ifdef _LP64
48  return ( ::qHash( (long int)(pair.first) ) );
49 #else
50  return ( ::qHash( (int)(pair.first) ) );
51 #endif
52 }
53 
62 class FARSA_WSIM_API MaterialDB {
63 public:
65  World* world() {
66  return worldv;
67  };
68 
72  bool createMaterial( QString name );
73 
79  void setFrictions( QString mat1, QString mat2, real st, real kn );
80 
84  void setElasticity( QString mat1, QString mat2, real );
85 
89  void setSoftness( QString mat1, QString mat2, real );
93  void setGravityForce( QString mat, real force );
96  real gravityForce( QString mat );
97 
102  void enableCollision( QString mat1, QString mat2, bool enable = true );
103 
111  void setProperties( QString mat1, QString mat2, real fs, real fk, real el, real sf, bool en = true );
112 
113 private:
115  MaterialDB( World* );
117  class materialPairInfo {
118  public:
119  real staticFriction;
120  real dynamicFriction;
121  real elasticity;
122  real softness;
123  bool collisions;
124  };
126  QSet<QString> mats;
128  QMap<QString, real> gravities;
129 
140  QHash<QString, materialPairInfo> pmap;
141 
143  QString createKey( QString mat1, QString mat2 );
144 
146  World* worldv;
147  friend class World;
148 };
149 
150 
161 class FARSA_WSIM_TEMPLATE Contact {
162 public:
173 };
174 
176 typedef QVector<Contact> contactVec;
178 typedef QHash<PhyObject*, contactVec> contactMap;
180 typedef QHashIterator<PhyObject*, contactVec> contactMapIterator;
181 
182 
194 class FARSA_WSIM_TEMPLATE RayCastHit {
195 public:
201  real distance;
207 };
208 
210 typedef QVector<RayCastHit> rayCastHitVector;
211 
222 class FARSA_WSIM_API World : public QObject {
223  Q_OBJECT
224 public:
230  World( QString worldname, bool LocalYarpPorts=false );
232  virtual ~World();
234  QString name() const;
236  real elapsedTime() const;
238  void resetElapsedTime();
240  void setTimeStep( real );
243  void setMinimumFrameRate( unsigned int frames );
245  void setIsRealTime( bool b );
247  bool isRealTime() const;
249  real timeStep() const;
251  void setGravityForce( real g );
253  real gravityForce() const;
255  const QLinkedList<WObject*> objects();
257  WObject* getObject( QString name );
259  const QLinkedList<PhyJoint*> joints();
261  const QHash<WObject*, QList<PhyJoint*> > mapObjectsToJoints();
262 
267  void advanceUntil( real time );
268 
274  void disableCollision( PhyObject* obj1, PhyObject* obj2 );
276  void enableCollision( PhyObject* obj1, PhyObject* obj2 );
278  const contactMap& contacts();
287  bool closestPoints( PhyObject* objA, PhyObject* objB, wVector& pointA, wVector& pointB );
297  bool checkContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL, QVector<wVector>* normals = NULL, QVector<real>* penetra = NULL );
308  bool smartCheckContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL );
319  real collisionRayCast( PhyObject* obj, wVector start, wVector end, wVector* normal = NULL );
332  rayCastHitVector worldRayCast( wVector start, wVector end, bool onlyClosest, const QSet<PhyObject*>& ignoredObjs = QSet<PhyObject*>() );
333 
336  return (*mats);
337  };
338 
340  void setSolverModel( QString model );
342  void setFrictionModel( QString model );
344  void setMultiThread( int numThreads );
346  void setSize( const wVector& minPoint, const wVector& maxPoint );
348  void size( wVector &minPoint, wVector &maxPoint );
349 
354  void pushObject( WObject* );
359  void popObject( WObject* );
360 
365  void pushJoint( PhyJoint* );
370  void popJoint( PhyJoint* );
372  enum w_state { playingS, pausedS, stoppedS };
375  return state;
376  };
378  void cleanUpMemory();
379 public slots:
381  void initialize();
388  void advance();
390  void finalize();
392  int play();
394  void pause();
396  void stop();
397 signals:
399  void initialized();
401  void finished();
403  void advanced();
405  void paused();
407  void stopped();
409  void addedObject( WObject* );
411  void addedJoint( PhyJoint* );
413  void removedObject( WObject* );
415  void removedJoint( PhyJoint* );
417  void resized();
418 protected:
420  real time;
422  real timestepv;
424  real gforce;
426  wVector minP, maxP;
436  QLinkedList<WObject*> objs;
437 
440  QLinkedList<PhyJoint*> jointsv;
442  QHash<WObject*, QList<PhyJoint*> > mapObjJoints;
443 
445  void timerEvent( QTimerEvent* e );
447  void customEvent( QEvent* e );
448 public:
450  enum { E_Advance = 1200, E_Play = 1201, E_Stop = 1202, E_Pause = 1203 };
451 private:
453  QString namev;
454 
456  contactMap cmap;
457 
459  typedef QPair<PhyObject*, PhyObject*> NObj;
461  QSet<NObj> nobjs;
462 
464  MaterialDB* mats;
465  friend class MaterialDB;
466 
468  SimpleTimer timer;
470  bool isrealtimev;
472  bool isInit;
474  bool isFinish;
476  w_state state;
478  unsigned int timerId;
479 
481  WorldPrivate* priv;
482  friend class PhyObject;
483  friend class PhyJoint;
484  friend class WorldPrivate;
485 };
486 
487 } // end namespace farsa
488 
489 #endif