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:
171 };
172 
174 typedef QVector<Contact> contactVec;
176 typedef QHash<PhyObject*, contactVec> contactMap;
178 typedef QHashIterator<PhyObject*, contactVec> contactMapIterator;
179 
180 
192 class FARSA_WSIM_TEMPLATE RayCastHit {
193 public:
199  real distance;
205 };
206 
208 typedef QVector<RayCastHit> rayCastHitVector;
209 
220 class FARSA_WSIM_API World : public QObject {
221  Q_OBJECT
222 public:
228  World( QString worldname, bool LocalYarpPorts=false );
230  virtual ~World();
232  QString name() const;
234  real elapsedTime() const;
236  void resetElapsedTime();
238  void setTimeStep( real );
241  void setMinimumFrameRate( unsigned int frames );
243  void setIsRealTime( bool b );
245  bool isRealTime() const;
247  real timeStep() const;
249  void setGravityForce( real g );
251  real gravityForce() const;
253  const QLinkedList<WObject*> objects();
255  WObject* getObject( QString name );
257  const QLinkedList<PhyJoint*> joints();
259  const QHash<WObject*, QList<PhyJoint*> > mapObjectsToJoints();
260 
265  void advanceUntil( real time );
266 
272  void disableCollision( PhyObject* obj1, PhyObject* obj2 );
274  void enableCollision( PhyObject* obj1, PhyObject* obj2 );
276  const contactMap& contacts();
285  bool closestPoints( PhyObject* objA, PhyObject* objB, wVector& pointA, wVector& pointB );
295  bool checkContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL, QVector<wVector>* normals = NULL, QVector<real>* penetra = NULL );
306  bool smartCheckContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL );
317  real collisionRayCast( PhyObject* obj, wVector start, wVector end, wVector* normal = NULL );
330  rayCastHitVector worldRayCast( wVector start, wVector end, bool onlyClosest, const QSet<PhyObject*>& ignoredObjs = QSet<PhyObject*>() );
331 
334  return (*mats);
335  };
336 
338  void setSolverModel( QString model );
340  void setFrictionModel( QString model );
342  void setMultiThread( int numThreads );
344  void setSize( const wVector& minPoint, const wVector& maxPoint );
346  void size( wVector &minPoint, wVector &maxPoint );
347 
352  void pushObject( WObject* );
357  void popObject( WObject* );
358 
363  void pushJoint( PhyJoint* );
368  void popJoint( PhyJoint* );
370  enum w_state { playingS, pausedS, stoppedS };
373  return state;
374  };
376  void cleanUpMemory();
377 public slots:
379  void initialize();
386  void advance();
388  void finalize();
390  int play();
392  void pause();
394  void stop();
395 signals:
397  void initialized();
399  void finished();
401  void advanced();
403  void paused();
405  void stopped();
407  void addedObject( WObject* );
409  void addedJoint( PhyJoint* );
411  void removedObject( WObject* );
413  void removedJoint( PhyJoint* );
415  void resized();
416 protected:
418  real time;
420  real timestepv;
422  real gforce;
424  wVector minP, maxP;
434  QLinkedList<WObject*> objs;
435 
438  QLinkedList<PhyJoint*> jointsv;
440  QHash<WObject*, QList<PhyJoint*> > mapObjJoints;
441 
443  void timerEvent( QTimerEvent* e );
445  void customEvent( QEvent* e );
446 public:
448  enum { E_Advance = 1200, E_Play = 1201, E_Stop = 1202, E_Pause = 1203 };
449 private:
451  QString namev;
452 
454  contactMap cmap;
455 
457  typedef QPair<PhyObject*, PhyObject*> NObj;
459  QSet<NObj> nobjs;
460 
462  MaterialDB* mats;
463  friend class MaterialDB;
464 
466  SimpleTimer timer;
468  bool isrealtimev;
470  bool isInit;
472  bool isFinish;
474  w_state state;
476  unsigned int timerId;
477 
479  WorldPrivate* priv;
480  friend class PhyObject;
481  friend class PhyJoint;
482  friend class WorldPrivate;
483 };
484 
485 } // end namespace farsa
486 
487 #endif