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 "wvector.h"
25 #include "wmatrix.h"
26 #include "wquaternion.h"
27 #include "ownable.h"
28 #include <QString>
29 #include <QHash>
30 #include <QSet>
31 #include <QList>
32 #include <QLinkedList>
33 #include <QVector>
34 #include <QPair>
35 #include <QEvent>
36 #include <QTimerEvent>
37 #include <QColor>
38 
39 namespace farsa {
40 
41 class World;
42 class WorldPrivate;
43 class PhyObject;
44 class PhyJoint;
45 class MotorController;
46 
47 //--- this function is required by QSet<NObj> attribute of World class
48 inline uint qHash( const QPair<PhyObject*, PhyObject*>& pair ) {
49 #ifdef _LP64
50  return ( ::qHash( (long int)(pair.first) ) );
51 #else
52  return ( ::qHash( (int)(pair.first) ) );
53 #endif
54 }
55 
64 class FARSA_WSIM_API WObject : public QObject, public Ownable {
65  Q_OBJECT
66 public:
78  WObject( World* world, QString name="unamed", const wMatrix& tm = wMatrix::identity(), bool addToWorld = true );
80  virtual ~WObject();
82  const wMatrix& matrix() const {
83  return tm;
84  };
86  void setPosition( const wVector& newpos ) {
87  tm.w_pos = newpos;
88  changedMatrix();
89  };
91  void setPosition( real x, real y, real z ) {
92  tm.w_pos = wVector(x,y,z);
93  changedMatrix();
94  };
96  World* world() {
97  return worldv;
98  };
100  const World* world() const {
101  return worldv;
102  };
104  QString name() const {
105  return namev;
106  };
108  void setTexture( QString textureName ) {
109  texturev = textureName;
110  };
112  QString texture() const {
113  return texturev;
114  };
115  void setColor( QColor c ) {
116  colorv = c;
117  };
118  void setAlpha( int alpha ) {
119  colorv.setAlpha( alpha );
120  };
121  QColor color() const {
122  return colorv;
123  };
125  bool useColorTextureOfOwner() const {
126  return usecolortextureofowner;
127  };
129  void setUseColorTextureOfOwner( bool b ) {
130  usecolortextureofowner = b;
131  };
136  virtual void preUpdate() {
137  /* nothing to do */
138  };
143  virtual void postUpdate() {
144  /* nothing to do */
145  };
147  void setMatrix( const wMatrix& newm ) {
148  tm = newm;
149  changedMatrix();
150  };
152  bool isInvisible() {
153  return invisible;
154  };
156  void setInvisible( bool b ) {
157  invisible = b;
158  };
159 protected:
161  virtual void changedMatrix() {
162  /* nothing to do here */;
163  };
165  World* worldv;
169  QString namev;
171  QString texturev;
173  QColor colorv;
175  bool invisible;
178 };
179 
193 class FARSA_WSIM_API MaterialDB {
194 public:
197  return worldv;
198  };
199 
203  bool createMaterial( QString name );
204 
210  void setFrictions( QString mat1, QString mat2, real st, real kn );
211 
215  void setElasticity( QString mat1, QString mat2, real );
216 
220  void setSoftness( QString mat1, QString mat2, real );
224  void setGravityForce( QString mat, real force );
227  real gravityForce( QString mat );
228 
233  void enableCollision( QString mat1, QString mat2, bool enable = true );
234 
242  void setProperties( QString mat1, QString mat2, real fs, real fk, real el, real sf, bool en = true );
243 
244 private:
246  MaterialDB( World* );
248  class materialPairInfo {
249  public:
250  real staticFriction;
251  real dynamicFriction;
252  real elasticity;
253  real softness;
254  bool collisions;
255  };
257  QSet<QString> mats;
259  QMap<QString, real> gravities;
260 
271  QHash<QString, materialPairInfo> pmap;
272 
274  QString createKey( QString mat1, QString mat2 );
275 
277  World* worldv;
278  friend class World;
279 };
280 
281 
292 class FARSA_WSIM_TEMPLATE Contact {
293 public:
302 };
303 
305 typedef QVector<Contact> contactVec;
307 typedef QHash<PhyObject*, contactVec> contactMap;
309 typedef QHashIterator<PhyObject*, contactVec> contactMapIterator;
310 
311 
323 class FARSA_WSIM_TEMPLATE RayCastHit {
324 public:
330  real distance;
336 };
337 
339 typedef QVector<RayCastHit> rayCastHitVector;
340 
351 class FARSA_WSIM_API World : public QObject {
352  Q_OBJECT
353 public:
359  World( QString worldname, bool LocalYarpPorts=false );
361  virtual ~World();
363  QString name() const;
365  real elapsedTime() const;
367  void resetElapsedTime();
369  void setTimeStep( real );
372  void setMinimumFrameRate( unsigned int frames );
374  void setIsRealTime( bool b );
376  bool isRealTime() const;
378  real timeStep() const;
380  void setGravityForce( real g );
382  real gravityForce() const;
384  const QLinkedList<WObject*> objects();
386  WObject* getObject( QString name );
388  const QLinkedList<PhyJoint*> joints();
390  const QHash<WObject*, QList<PhyJoint*> > mapObjectsToJoints();
391 
396  void advanceUntil( real time );
397 
403  void disableCollision( PhyObject* obj1, PhyObject* obj2 );
405  void enableCollision( PhyObject* obj1, PhyObject* obj2 );
407  const contactMap& contacts();
416  bool closestPoints( PhyObject* objA, PhyObject* objB, wVector& pointA, wVector& pointB );
426  bool checkContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL, QVector<wVector>* normals = NULL, QVector<real>* penetra = NULL );
437  bool smartCheckContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL );
448  real collisionRayCast( PhyObject* obj, wVector start, wVector end, wVector* normal = NULL );
461  rayCastHitVector worldRayCast( wVector start, wVector end, bool onlyClosest, const QSet<PhyObject*>& ignoredObjs = QSet<PhyObject*>() );
462 
465  return (*mats);
466  };
467 
469  void setSolverModel( QString model );
471  void setFrictionModel( QString model );
473  void setMultiThread( int numThreads );
475  void setSize( const wVector& minPoint, const wVector& maxPoint );
477  void size( wVector &minPoint, wVector &maxPoint );
478 
483  void pushObject( WObject* );
488  void popObject( WObject* );
489 
494  void pushJoint( PhyJoint* );
499  void popJoint( PhyJoint* );
501  enum w_state { playingS, pausedS, stoppedS };
504  return state;
505  };
507  void cleanUpMemory();
508 public slots:
510  void initialize();
517  void advance();
519  void finalize();
521  int play();
523  void pause();
525  void stop();
526 signals:
528  void initialized();
530  void finished();
532  void advanced();
534  void paused();
536  void stopped();
538  void addedObject( WObject* );
540  void addedJoint( PhyJoint* );
542  void removedObject( WObject* );
544  void removedJoint( PhyJoint* );
546  void resized();
547 protected:
549  real time;
551  real timestepv;
553  real gforce;
555  wVector minP, maxP;
565  QLinkedList<WObject*> objs;
566 
569  QLinkedList<PhyJoint*> jointsv;
571  QHash<WObject*, QList<PhyJoint*> > mapObjJoints;
572 
574  void timerEvent( QTimerEvent* e );
576  void customEvent( QEvent* e );
577 public:
579  enum { E_Advance = 1200, E_Play = 1201, E_Stop = 1202, E_Pause = 1203 };
580 private:
582  QString namev;
583 
585  contactMap cmap;
586 
588  typedef QPair<PhyObject*, PhyObject*> NObj;
590  QSet<NObj> nobjs;
591 
593  MaterialDB* mats;
594  friend class MaterialDB;
595 
597  SimpleTimer timer;
599  bool isrealtimev;
601  bool isInit;
603  bool isFinish;
605  w_state state;
607  unsigned int timerId;
608 
610  WorldPrivate* priv;
611  friend class PhyObject;
612  friend class PhyJoint;
613  friend class WorldPrivate;
614 };
615 
616 } // end namespace farsa
617 
618 #endif