00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00138 };
00143 virtual void postUpdate() {
00144
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 ;
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 }
00617
00618 #endif