worldsim/include/world.h

00001 /********************************************************************************
00002  *  WorldSim -- library for robot simulations                                   *
00003  *  Copyright (C) 2008-2011 Gianluca Massera <emmegian@yahoo.it>                *
00004  *                                                                              *
00005  *  This program is free software; you can redistribute it and/or modify        *
00006  *  it under the terms of the GNU General Public License as published by        *
00007  *  the Free Software Foundation; either version 2 of the License, or           *
00008  *  (at your option) any later version.                                         *
00009  *                                                                              *
00010  *  This program is distributed in the hope that it will be useful,             *
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00013  *  GNU General Public License for more details.                                *
00014  *                                                                              *
00015  *  You should have received a copy of the GNU General Public License           *
00016  *  along with this program; if not, write to the Free Software                 *
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00018  ********************************************************************************/
00019 
00020 #ifndef WORLD_H
00021 #define WORLD_H
00022 
00023 #include "worldsimconfig.h"
00024 #include "wvector.h"
00025 #include "wmatrix.h"
00026 #include "wquaternion.h"
00027 #include "ownable.h"
00028 #include <QString>
00029 #include <QHash>
00030 #include <QSet>
00031 #include <QList>
00032 #include <QLinkedList>
00033 #include <QVector>
00034 #include <QPair>
00035 #include <QEvent>
00036 #include <QTimerEvent>
00037 #include <QColor>
00038 
00039 namespace farsa {
00040 
00041 class World;
00042 class WorldPrivate;
00043 class PhyObject;
00044 class PhyJoint;
00045 class MotorController;
00046 
00047 //--- this function is required by QSet<NObj> attribute of World class
00048 inline uint qHash( const QPair<PhyObject*, PhyObject*>& pair ) {
00049 #ifdef _LP64
00050     return ( ::qHash( (long int)(pair.first) ) );
00051 #else
00052     return ( ::qHash( (int)(pair.first) ) );
00053 #endif
00054 }
00055 
00064 class FARSA_WSIM_API WObject : public QObject, public Ownable {
00065     Q_OBJECT
00066 public:
00078     WObject( World* world, QString name="unamed", const wMatrix& tm = wMatrix::identity(), bool addToWorld = true );
00080     virtual ~WObject();
00082     const wMatrix& matrix() const {
00083         return tm;
00084     };
00086     void setPosition( const wVector& newpos ) {
00087         tm.w_pos = newpos;
00088         changedMatrix();
00089     };
00091     void setPosition( real x, real y, real z ) {
00092         tm.w_pos = wVector(x,y,z);
00093         changedMatrix();
00094     };
00096     World* world() {
00097         return worldv;
00098     };
00100     const World* world() const {
00101         return worldv;
00102     };
00104     QString name() const {
00105         return namev;
00106     };
00108     void setTexture( QString textureName ) {
00109         texturev = textureName;
00110     };
00112     QString texture() const {
00113         return texturev;
00114     };
00115     void setColor( QColor c ) {
00116         colorv = c;
00117     };
00118     void setAlpha( int alpha ) {
00119         colorv.setAlpha( alpha );
00120     };
00121     QColor color() const {
00122         return colorv;
00123     };
00125     bool useColorTextureOfOwner() {
00126         return usecolortextureofowner;
00127     };
00129     void setUseColorTextureOfOwner( bool b ) {
00130         usecolortextureofowner = b;
00131     };
00136     virtual void preUpdate() {
00137         /* nothing to do */
00138     };
00143     virtual void postUpdate() {
00144         /* nothing to do */
00145     };
00147     void setMatrix( const wMatrix& newm ) {
00148         tm = newm;
00149         changedMatrix();
00150     };
00152     bool isInvisible() {
00153         return invisible;
00154     };
00156     void setInvisible( bool b ) {
00157         invisible = b;
00158     };
00159 protected:
00161     virtual void changedMatrix() {
00162         /* nothing to do here */;
00163     };
00165     World* worldv;
00167     wMatrix tm;
00169     QString namev;
00171     QString texturev;
00173     QColor colorv;
00175     bool invisible;
00177     bool usecolortextureofowner;
00178 };
00179 
00193 class FARSA_WSIM_API MaterialDB {
00194 public:
00196     World* world() {
00197         return worldv;
00198     };
00199 
00203     bool createMaterial( QString name );
00204     
00210     void setFrictions( QString mat1, QString mat2, real st, real kn );
00211 
00215     void setElasticity( QString mat1, QString mat2, real );
00216 
00220     void setSoftness( QString mat1, QString mat2, real );
00224     void setGravityForce( QString mat, real force );
00227     real gravityForce( QString mat );
00228 
00233     void enableCollision( QString mat1, QString mat2, bool enable = true );
00234 
00242     void setProperties( QString mat1, QString mat2, real fs, real fk, real el, real sf, bool en = true );
00243 
00244 private:
00246     MaterialDB( World* );
00248     class materialPairInfo {
00249     public:
00250         real staticFriction;
00251         real dynamicFriction;
00252         real elasticity;
00253         real softness;
00254         bool collisions;
00255     };
00257     QSet<QString> mats;
00259     QMap<QString, real> gravities;
00260 
00271     QHash<QString, materialPairInfo> pmap;
00272 
00274     QString createKey( QString mat1, QString mat2 );
00275 
00277     World* worldv;
00278     friend class World;
00279 };
00280 
00281 
00292 class FARSA_WSIM_TEMPLATE Contact {
00293 public:
00295     PhyObject* object;
00297     PhyObject* collide;
00299     wVector pos;
00301     wVector worldPos;
00302 };
00303 
00305 typedef QVector<Contact> contactVec;
00307 typedef QHash<PhyObject*, contactVec> contactMap;
00309 typedef QHashIterator<PhyObject*, contactVec> contactMapIterator;
00310 
00311 
00323 class FARSA_WSIM_TEMPLATE RayCastHit {
00324 public:
00326     PhyObject* object;
00330     real distance;
00333     wVector position;
00335     wVector normal;
00336 };
00337 
00339 typedef QVector<RayCastHit> rayCastHitVector;
00340 
00351 class FARSA_WSIM_API World : public QObject {
00352     Q_OBJECT
00353 public:
00359     World( QString worldname, bool LocalYarpPorts=false );
00361     virtual ~World();
00363     QString name() const;
00365     real elapsedTime() const;
00367     void resetElapsedTime();
00369     void setTimeStep( real );
00372     void setMinimumFrameRate( unsigned int frames );
00374     void setIsRealTime( bool b );
00376     bool isRealTime() const;
00378     real timeStep() const;
00380     void setGravityForce( real g );
00382     real gravityForce() const;
00384     const QLinkedList<WObject*> objects();
00386     WObject* getObject( QString name );
00388     const QLinkedList<PhyJoint*> joints();
00390     const QHash<WObject*, QList<PhyJoint*> > mapObjectsToJoints();
00391 
00396     void advanceUntil( real time );
00397 
00403     void disableCollision( PhyObject* obj1, PhyObject* obj2 );
00405     void enableCollision( PhyObject* obj1, PhyObject* obj2 );
00407     const contactMap& contacts();
00416     bool closestPoints( PhyObject* objA, PhyObject* objB, wVector& pointA, wVector& pointB );
00426     bool checkContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL, QVector<wVector>* normals = NULL, QVector<real>* penetra = NULL );
00437     bool smartCheckContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts = 4, QVector<wVector>* contacts = NULL );
00448     real collisionRayCast( PhyObject* obj, wVector start, wVector end, wVector* normal = NULL );
00461     rayCastHitVector worldRayCast( wVector start, wVector end, bool onlyClosest, const QSet<PhyObject*>& ignoredObjs = QSet<PhyObject*>() );
00462 
00464     MaterialDB& materials() {
00465         return (*mats);
00466     };
00467 
00469     void setSolverModel( QString model );
00471     void setFrictionModel( QString model );
00473     void setMultiThread( int numThreads );
00475     void setSize( const wVector& minPoint, const wVector& maxPoint );
00477     void size( wVector &minPoint, wVector &maxPoint );
00478 
00483     void pushObject( WObject* );
00488     void popObject( WObject* );
00489 
00494     void pushJoint( PhyJoint* );
00499     void popJoint( PhyJoint* );
00501     enum w_state { playingS, pausedS, stoppedS };
00503     w_state status() {
00504         return state;
00505     };
00507     void cleanUpMemory();
00508 public slots:
00510     void initialize();
00517     void advance();
00519     void finalize();
00521     int play();
00523     void pause();
00525     void stop();
00526 signals:
00528     void initialized();
00530     void finished();
00532     void advanced();
00534     void paused();
00536     void stopped();
00538     void addedObject( WObject* );
00540     void addedJoint( PhyJoint* );
00542     void removedObject( WObject* );
00544     void removedJoint( PhyJoint* );
00546     void resized();
00547 protected:
00549     real time;
00551     real timestepv;
00553     real gforce;
00555     wVector minP, maxP;
00565     QLinkedList<WObject*> objs;
00566 
00569     QLinkedList<PhyJoint*> jointsv;
00571     QHash<WObject*, QList<PhyJoint*> > mapObjJoints;
00572 
00574     void timerEvent( QTimerEvent* e );
00576     void customEvent( QEvent* e );
00577 public:
00579     enum { E_Advance = 1200, E_Play = 1201, E_Stop = 1202, E_Pause = 1203 };
00580 private:
00582     QString namev;
00583 
00585     contactMap cmap;
00586 
00588     typedef QPair<PhyObject*, PhyObject*> NObj;
00590     QSet<NObj> nobjs;
00591 
00593     MaterialDB* mats;
00594     friend class MaterialDB;
00595 
00597     SimpleTimer timer;
00599     bool isrealtimev;
00601     bool isInit;
00603     bool isFinish;
00605     w_state state;
00607     unsigned int timerId;
00608 
00610     WorldPrivate* priv;
00611     friend class PhyObject;
00612     friend class PhyJoint;
00613     friend class WorldPrivate;
00614 };
00615 
00616 } // end namespace farsa
00617 
00618 #endif