world.cpp
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 #include "world.h"
21 #include "phyobject.h"
22 #include "phyjoint.h"
23 #include "private/phyobjectprivate.h"
24 #include "private/worldprivate.h"
25 #include "motorcontrollers.h"
26 #include <QMutex>
27 #include <QMutexLocker>
28 #include <QThread>
29 
30 #include <QPair>
31 
32 namespace farsa {
33 
34 MaterialDB::MaterialDB( World* w ) : mats(), pmap() {
35  this->worldv = w;
36  createMaterial( "nonCollidable" );
37  createMaterial( "default" );
38 }
39 
40 bool MaterialDB::createMaterial( QString name ) {
41  if ( mats.contains( name ) ) {
42  return false;
43  }
44 #ifdef WORLDSIM_USE_NEWTON
45  NewtonWorld* ngdWorld = worldv->priv->world;
46  int newm;
47  if ( name == "default" ) {
48  newm = NewtonMaterialGetDefaultGroupID( ngdWorld );
49  } else {
50  newm = NewtonMaterialCreateGroupID( ngdWorld );
51  }
52  worldv->priv->matIDs[name] = newm;
53  NewtonMaterialSetCollisionCallback( ngdWorld, newm, newm, (void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
54  // --- setting callbacks
55  foreach( QString k, mats.values() ) {
56  int kid = worldv->priv->matIDs[k];
57  NewtonMaterialSetCollisionCallback( ngdWorld, newm, kid, (void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
58  }
59  // --- setting nonCollidable material
60  NewtonMaterialSetDefaultCollidable( ngdWorld, worldv->priv->matIDs["nonCollidable"], newm, 0 );
61 #endif
62  mats.insert( name );
63  return true;
64 }
65 
66 void MaterialDB::setFrictions( QString mat1, QString mat2, real st, real kn ) {
67  if ( !mats.contains( mat1 ) ) return;
68  if ( !mats.contains( mat2 ) ) return;
69  QString pkey = createKey( mat1, mat2 );
70  pmap[pkey].staticFriction = st;
71  pmap[pkey].dynamicFriction = kn;
72 #ifdef WORLDSIM_USE_NEWTON
73  int id1 = worldv->priv->matIDs[mat1];
74  int id2 = worldv->priv->matIDs[mat2];
75  NewtonMaterialSetDefaultFriction( worldv->priv->world, id1, id2, st, kn );
76 #endif
77  return;
78 }
79 
80 void MaterialDB::setElasticity( QString mat1, QString mat2, real el ) {
81  if ( !mats.contains( mat1 ) ) return;
82  if ( !mats.contains( mat2 ) ) return;
83  QString pkey = createKey( mat1, mat2 );
84  pmap[pkey].elasticity = el;
85 #ifdef WORLDSIM_USE_NEWTON
86  int id1 = worldv->priv->matIDs[mat1];
87  int id2 = worldv->priv->matIDs[mat2];
88  NewtonMaterialSetDefaultElasticity( worldv->priv->world, id1, id2, el );
89 #endif
90  return;
91 }
92 
93 void MaterialDB::setSoftness( QString mat1, QString mat2, real sf ) {
94  if ( !mats.contains( mat1 ) ) return;
95  if ( !mats.contains( mat2 ) ) return;
96  QString pkey = createKey( mat1, mat2 );
97  pmap[pkey].softness = sf;
98 #ifdef WORLDSIM_USE_NEWTON
99  int id1 = worldv->priv->matIDs[mat1];
100  int id2 = worldv->priv->matIDs[mat2];
101  NewtonMaterialSetDefaultSoftness( worldv->priv->world, id1, id2, sf );
102 #endif
103  return;
104 }
105 
106 void MaterialDB::setGravityForce( QString mat, real force ) {
107  gravities[mat] = force;
108 }
109 
111  if ( gravities.contains( mat ) ) {
112  return gravities[mat];
113  } else {
114  return worldv->gravityForce();
115  }
116 }
117 
118 
119 void MaterialDB::enableCollision( QString mat1, QString mat2, bool enable ) {
120  if ( !mats.contains( mat1 ) ) return;
121  if ( !mats.contains( mat2 ) ) return;
122  QString pkey = createKey( mat1, mat2 );
123  pmap[pkey].collisions = enable;
124 #ifdef WORLDSIM_USE_NEWTON
125  int id1 = worldv->priv->matIDs[mat1];
126  int id2 = worldv->priv->matIDs[mat2];
127  NewtonMaterialSetDefaultCollidable( worldv->priv->world, id1, id2, enable );
128 #endif
129 }
130 
131 void MaterialDB::setProperties( QString mat1, QString mat2, real fs, real fk, real el, real sf, bool en ) {
132  setFrictions( mat1, mat2, fs, fk );
133  setElasticity( mat1, mat2, el );
134  setSoftness( mat1, mat2, sf );
135  enableCollision( mat1, mat2, en );
136 }
137 
138 QString MaterialDB::createKey( QString mat1, QString mat2 ) {
139  if ( mat1 < mat2 ) {
140  return mat1 + ":" + mat2;
141  } else {
142  return mat2 + ":" + mat1;
143  }
144 }
145 
146 World::World( QString name )
147  : QObject(), minP(-100,-100,-100), maxP(100,100,100), objs(), jointsv(), mapObjJoints(),
148  cmap(), nobjs() {
149  timerId = 0;
150  state = stoppedS;
151  namev = name;
152  time = 0.0;
153  timestepv = 0.0150f; //--- about 66.66666 frame per second
154  isrealtimev = false;
155  isInit = false;
156  isFinish = true;
157  gforce = -9.8f;
158  priv = new WorldPrivate();
159 
160 #ifdef WORLDSIM_USE_NEWTON
161  priv->world = NewtonCreate();
162  NewtonInvalidateCache( priv->world );
163  NewtonSetWorldSize( priv->world, &minP[0], &maxP[0] );
164  // keep at least to 100 for stability
165  NewtonSetMinimumFrameRate( priv->world, 100 );
166  // exact model as default
167  NewtonSetSolverModel( priv->world, 0 );
168  NewtonSetFrictionModel( priv->world, 0 );
169  // enable multi-thread
170  //--- for works we before check that all callbacks implementation are thread-safe
171  //--- REMEMBER: connect, signal-slot of non-QT data needs to register the type with
172  //--- qRegisterMetaType
173  //NewtonSetThreadsCount( priv->world, 2 );
174 #endif
175 
176  mats = new MaterialDB( this );
177  return;
178 }
179 
181  // Here we can't use foreach because lists could be modified while we are iterating on them
182  // by the popObject(), popJoint() or popMotorController() functions. See the comment in the
183  // declaration of objs for more information
184  while ( !jointsv.isEmpty() ) {
185  PhyJoint* js = jointsv.takeFirst();
186  if ( js->owner() == NULL ) {
187  delete js;
188  }
189  }
190  while ( !objs.isEmpty() ) {
191  WObject* obj = objs.takeFirst();
192  if ( obj->owner() == NULL ) {
193  delete obj;
194  }
195  }
196 #ifdef WORLDSIM_USE_NEWTON
197  NewtonDestroy( priv->world );
198 #endif
199  delete priv;
200 }
201 
202 QString World::name() const {
203  return namev;
204 }
205 
207  if ( isInit ) return;
208  if ( !isFinish ) {
209  finalize();
210  }
211  time = 0.0;
212  timer.tic();
213  state = stoppedS;
214  isInit = true;
215  isFinish = false;
216  emit initialized();
217 }
218 
220  if ( !isInit ) {
221  initialize();
222  }
223  while( isrealtimev && timer.tac()/1000000.0 < timestepv ) { };
224 
225  timer.tic();
226  //--- preUpdate Objects
227  for( QLinkedList<WObject*>::iterator it = objs.begin(); it != objs.end(); it++ ) {
228  (*it)->preUpdate();
229  }
230  //--- preUpdate Joints
231  for( QLinkedList<PhyJoint*>::iterator it = jointsv.begin(); it != jointsv.end(); it++ ) {
232  (*it)->preUpdate();
233  }
234  // Simulate physic. Before doing the actual simulation step, clearing the map of contacts
235  // (we do it here so that calls to preUpdate() can access the old map of contacts)
236  cmap.clear();
237 #ifdef WORLDSIM_USE_NEWTON
238  NewtonUpdate( priv->world, timestepv );
239 #endif
240  //--- postUpdate Objects
241  for( QLinkedList<WObject*>::iterator it = objs.begin(); it != objs.end(); it++ ) {
242  (*it)->postUpdate();
243  }
244  //--- postUpdate Joints
245  for( QLinkedList<PhyJoint*>::iterator it = jointsv.begin(); it != jointsv.end(); it++ ) {
246  (*it)->postUpdate();
247  }
248  time += timestepv;
249 
250  emit advanced();
251 }
252 
254  if ( isFinish ) return;
255  /* nothing else to do ?!?! */
256  isFinish = true;
257  isInit = false;
258  emit finished();
259 }
260 
261 int World::play() {
262  if ( state == playingS ) return timerId;
263  if ( timerId != 0 ) return timerId;
264  state = playingS;
265  timerId = startTimer( 0 );
266  return timerId;
267 }
268 
269 void World::pause() {
270  state = pausedS;
271  if ( timerId != 0 ) killTimer( timerId );
272  timerId = 0;
273  emit paused();
274  return;
275 }
276 
277 void World::stop() {
278  finalize();
279  state = stoppedS;
280  if ( timerId != 0 ) killTimer( timerId );
281  timerId = 0;
282  emit stopped();
283  return;
284 }
285 
286 void World::timerEvent( QTimerEvent* ) {
287  advance();
288  return;
289 }
290 
291 void World::customEvent( QEvent* e ) {
292  switch( e->type() ) {
293  case E_Advance:
294  advance();
295  e->accept();
296  break;
297  case E_Play:
298  play();
299  e->accept();
300  break;
301  case E_Stop:
302  stop();
303  e->accept();
304  break;
305  case E_Pause:
306  pause();
307  e->accept();
308  break;
309  default:
310  e->ignore();
311  break;
312  }
313  return;
314 }
315 
317  return time;
318 }
319 
321  time = 0.0;
322 }
323 
324 void World::setIsRealTime( bool b ) {
325  isrealtimev = b;
326 }
327 
328 bool World::isRealTime() const {
329  return isrealtimev;
330 }
331 
333  timestepv = ts;
334 }
335 
336 void World::setMinimumFrameRate( unsigned int frames ) {
337 #ifdef WORLDSIM_USE_NEWTON
338  NewtonSetMinimumFrameRate( priv->world, frames );
339 #endif
340 }
341 
343  return timestepv;
344 }
345 
347  gforce = g;
348 }
349 
351  return gforce;
352 }
353 
355  blockSignals( true );
356  bool b = isrealtimev;
357  isrealtimev = false;
358  while ( time < t ) {
359  advance();
360  }
361  isrealtimev = b;
362  blockSignals( false );
363 }
364 
365 const QLinkedList<WObject*> World::objects() {
366  return objs;
367 }
368 
369 WObject* World::getObject( QString name ) {
370  //--- not very efficient, FIX adding a QMap
371  foreach( WObject* obj, objs ) {
372  if ( obj->name() == name ) return obj;
373  }
374  return NULL;
375 }
376 
377 const QLinkedList<PhyJoint*> World::joints() {
378  return jointsv;
379 }
380 
381 const QHash<WObject*, QList<PhyJoint*> > World::mapObjectsToJoints() {
382  return mapObjJoints;
383 }
384 
386  nobjs.insert( qMakePair( obj1, obj2 ) );
387  nobjs.insert( qMakePair( obj2, obj1 ) );
388 }
389 
391  nobjs.remove( qMakePair( obj1, obj2 ) );
392  nobjs.remove( qMakePair( obj2, obj1 ) );
393 }
394 
395 void World::setSolverModel( QString model ) {
396 #ifdef WORLDSIM_USE_NEWTON
397  if ( model =="exact" ) {
398  NewtonSetSolverModel( priv->world, 0 );
399  } else if ( model == "linear" ) {
400  NewtonSetSolverModel( priv->world, 1 );
401  }
402 #endif
403 }
404 
405 void World::setFrictionModel( QString model ) {
406 #ifdef WORLDSIM_USE_NEWTON
407  if ( model =="exact" ) {
408  NewtonSetFrictionModel( priv->world, 0 );
409  } else if ( model == "linear" ) {
410  NewtonSetFrictionModel( priv->world, 1 );
411  }
412 #endif
413 }
414 
415 void World::setMultiThread( int numThreads ) {
416 #ifdef WORLDSIM_USE_NEWTON
417  numThreads = max( 1, numThreads );
418  NewtonSetThreadsCount( priv->world, numThreads );
419 #endif
420 }
421 
422 void World::setSize( const wVector& minPoint, const wVector& maxPoint ) {
423  minP = minPoint;
424  maxP = maxPoint;
425 #ifdef WORLDSIM_USE_NEWTON
426  NewtonSetWorldSize( priv->world, &minP[0], &maxP[0] );
427 #endif
428  emit resized();
429 }
430 
431 void World::size( wVector &minPoint, wVector &maxPoint ) {
432  minPoint = minP;
433  maxPoint = maxP;
434 }
435 
436 void World::pushObject( WObject* phy ) {
437  objs.push_back( phy );
438  emit addedObject( phy );
439 }
440 
441 void World::popObject( WObject* phy ) {
442  const int numRemoved = objs.removeAll( phy );
443  if ( numRemoved == 1 ) {
444  // Also removing all collisions for the phy (if it is a PhyObject) object. We also have to manipulate the list
445  // of all objects colliding with phy
446  PhyObject* const phyObject = dynamic_cast<PhyObject*>(phy);
447  if ( ( phyObject != NULL ) && ( cmap.contains( phyObject ) ) ) {
448  const contactVec &cvec = cmap[ phyObject ];
449  foreach ( Contact c, cvec ) {
450  contactVec &otherCVec = cmap[ c.collide ];
451  contactVec::iterator it = otherCVec.begin();
452  while ( it != otherCVec.end() ) {
453  if ( it->collide == phyObject ) {
454  it = otherCVec.erase( it );
455  } else {
456  ++it;
457  }
458  }
459  if ( otherCVec.isEmpty() ) {
460  // Removing collisions if the list is empty
461  cmap.remove( c.collide );
462  }
463  }
464  cmap.remove( phyObject );
465  }
466  emit removedObject( phy );
467  }
468 #ifdef FARSA_DEBUG
469  else if (numRemoved > 1) {
470  qDebug( "INTERNAL ERROR: more than one object with the same address found in the World::objs list" );
471  }
472 #endif
473 }
474 
475 void World::pushJoint( PhyJoint* phy ) {
476  jointsv.push_back( phy );
477  mapObjJoints[ phy->child() ].push_back( phy );
478  if ( phy->parent() ) {
479  mapObjJoints[ phy->parent() ].push_back( phy );
480  }
481  emit addedJoint( phy );
482 }
483 
484 void World::popJoint( PhyJoint* phy ) {
485  const int numRemoved = jointsv.removeAll( phy );
486  if ( numRemoved == 1 ) {
487  mapObjJoints[ phy->child() ].removeAll( phy );
488  mapObjJoints.remove( phy->child() );
489  if ( phy->parent() ) {
490  mapObjJoints[ phy->parent() ].removeAll( phy );
491  mapObjJoints.remove( phy->parent() );
492  }
493  emit removedJoint( phy );
494  }
495 #ifdef FARSA_DEBUG
496  else if (numRemoved > 1) {
497  qDebug( "INTERNAL ERROR: more than one joint with the same address found in the World::jointsv list" );
498  }
499 #endif
500 }
501 
503 #ifdef WORLDSIM_USE_NEWTON
504  //qDebug() << "Memory Used by" << name() << NewtonGetMemoryUsed();
505  NewtonInvalidateCache( priv->world );
506  cmap.clear();
507  /*
508  qDebug() << "Objects: " << objs.size();
509  qDebug() << "Joints: " << jointsv.size();
510  qDebug() << "Map Obj-Joints: " << mapObjJoints.size();
511  qDebug() << "Contacts: " << cmap.size();
512  qDebug() << "Non-Collidable Objs: " << nobjs.size();
513  */
514  /*
515  qDebug() << "Materials: " << mats->mats.size();
516  qDebug() << "Gravities: " << mats->gravities.size();
517  qDebug() << "Material Infos: " << mats->pmap.size();
518  */
519 #endif
520 }
521 
522 const contactMap& World::contacts() {
523  return cmap;
524 }
525 
526 bool World::checkContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts, QVector<wVector>* contacts, QVector<wVector>* normals, QVector<real>* penetra ) {
527 #ifdef WORLDSIM_USE_NEWTON
528  // Allocating the vector we use to get data from NewtonCollisionCollide
529  real *const tmp_data = new real[2 * 3 * maxContacts + maxContacts];
530  real *const tmp_contacts = &tmp_data[0 * 3 * maxContacts];
531  real *const tmp_normals = &tmp_data[1 * 3 * maxContacts];
532  real *const tmp_penetra = &tmp_data[2 * 3 * maxContacts];
533 
534  // Computing contacts
535  wMatrix t1 = obj1->matrix();
536  wMatrix t2 = obj2->matrix();
537  const int numContacts = NewtonCollisionCollide( priv->world, maxContacts, obj1->priv->collision, &t1[0][0], obj2->priv->collision, &t2[0][0], tmp_contacts, tmp_normals, tmp_penetra, 0 );
538 
539  // Now copying contacts information into user vectors
540  if (contacts != NULL) {
541  contacts->resize(numContacts);
542  for (int i = 0; i < numContacts; i++) {
543  (*contacts)[i].x = tmp_contacts[0 + i * 3];
544  (*contacts)[i].y = tmp_contacts[1 + i * 3];
545  (*contacts)[i].z = tmp_contacts[2 + i * 3];
546  }
547  }
548  if (normals != NULL) {
549  normals->resize(numContacts);
550  for (int i = 0; i < numContacts; i++) {
551  (*normals)[i].x = tmp_normals[0 + i * 3];
552  (*normals)[i].y = tmp_normals[1 + i * 3];
553  (*normals)[i].z = tmp_normals[2 + i * 3];
554  }
555  }
556  if (penetra != NULL) {
557  penetra->resize(numContacts);
558  for (int i = 0; i < numContacts; i++) {
559  (*penetra)[i] = tmp_penetra[i];
560  }
561  }
562 
563  delete[] tmp_data;
564  return (numContacts != 0);
565 #endif
566 }
567 
568 bool World::smartCheckContacts( PhyObject* obj1, PhyObject* obj2, int maxContacts, QVector<wVector>* contacts )
569 {
570  if (obj1->getKinematic() || obj2->getKinematic() || (obj1->getStatic() && obj2->getStatic())) {
571  return checkContacts( obj1, obj2, maxContacts, contacts, NULL, NULL);
572  } else {
573  if (!cmap.contains(obj1)) {
574  return false;
575  }
576 
577  // Taking the vector of contacts
578  const contactVec& c = cmap[obj1];
579  bool collision = false;
580  if (contacts != NULL) {
581  contacts->clear();
582  }
583 
584  // Now extracting all collisions between obj1 and obj2
585  for (int i = 0; i < c.size(); i++) {
586  if (c[i].collide == obj2) {
587  collision = true;
588  if ((contacts != NULL) && (contacts->size() < maxContacts)) {
589  // Adding contact point
590  contacts->append(c[i].worldPos);
591  }
592  }
593  }
594 
595  return collision;
596  }
597 }
598 
600 {
601 #ifdef WORLDSIM_USE_NEWTON
602  // The vector storing the normal to the contact point and the attribute (unused)
603  dFloat n[3];
604  int attribute;
605  wVector localStart = obj->matrix().inverse().transformVector(start);
606  wVector localEnd = obj->matrix().inverse().transformVector(end);
607 
608  // Computing the contact
609  const real contact = NewtonCollisionRayCast(obj->priv->collision, &localStart[0], &localEnd[0], n, &attribute);
610 
611  if (normal != NULL) {
612  (*normal)[0] = n[0];
613  (*normal)[1] = n[1];
614  (*normal)[2] = n[2];
615  }
616 
617  return contact;
618 #else
619  return 2.0;
620 #endif
621 }
622 
623 rayCastHitVector World::worldRayCast( wVector start, wVector end, bool onlyClosest, const QSet<PhyObject*>& ignoredObjs )
624 {
625 #ifdef WORLDSIM_USE_NEWTON
626  WorldPrivate::WorldRayCastCallbackUserData data(start, end, onlyClosest, ignoredObjs);
627 
628  // Casting the ray
629  NewtonWorldRayCast(priv->world, &start[0], &end[0], WorldPrivate::worldRayFilterCallback, &data, NULL);
630 
631  return data.vector;
632 #else
633  return rayCastHitVector();
634 #endif
635 }
636 
637 // bool World::checkContacts( PhyObject* obj1, PhyObject* obj2 ) {
638 // #ifdef WORLDSIM_USE_NEWTON
639 // const int maxsize = 4;
640 // real contacts[3*maxsize];
641 // real normals[3*maxsize];
642 // real penetra[3*maxsize];
643 // wMatrix t1 = obj1->matrix();
644 // wMatrix t2 = obj2->matrix();
645 // bool ret = ( NewtonCollisionCollide( priv->world, maxsize, obj1->priv->collision, &t1[0][0], obj2->priv->collision, &t2[0][0], contacts, normals, penetra, 0 ) != 0 );
646 // return ret;
647 // #endif
648 // }
649 
650 bool World::closestPoints( PhyObject* objA, PhyObject* objB, wVector& pointA, wVector& pointB ) {
651 #ifdef WORLDSIM_USE_NEWTON
652  wVector normal;
653  wMatrix t1 = objA->matrix();
654  wMatrix t2 = objB->matrix();
655  int ret = NewtonCollisionClosestPoint( priv->world,
656  objA->priv->collision, &t1[0][0],
657  objB->priv->collision, &t2[0][0],
658  &pointA[0], &pointB[0], &normal[0], 0 );
659  if ( ret == 0 ) {
660  pointA = wVector(0,0,0);
661  pointB = wVector(0,0,0);
662  return false;
663  }
664  return true;
665 #endif
666 }
667 
668 } // end namespace farsa
bool getKinematic() const
Returns true if the object has kinematic behaviour.
Definition: phyobject.h:72
void advanceUntil(real time)
Advance the World until the time passed is reached (approx.
Definition: world.cpp:354
void enableCollision(QString mat1, QString mat2, bool enable=true)
Enable/Disable the collision between materials passed.
Definition: world.cpp:119
the MaterialDB class managea the material properties
Definition: world.h:63
World's Object class.
Definition: wobject.h:39
void size(wVector &minPoint, wVector &maxPoint)
Get the bounding box of the world.
Definition: world.cpp:431
void setGravityForce(QString mat, real force)
configure the force gravity that will be applied to object of material specified
Definition: world.cpp:106
void addedObject(WObject *)
emitted when an WObject has been added
void setFrictionModel(QString model)
See Physic Engine Documentation.
Definition: world.cpp:405
void advance()
Do a step of the World.
Definition: world.cpp:219
void setGravityForce(real g)
Set the gravity force.
Definition: world.cpp:346
void resized()
emitted when the World change its size
rayCastHitVector worldRayCast(wVector start, wVector end, bool onlyClosest, const QSet< PhyObject * > &ignoredObjs=QSet< PhyObject * >())
Returns the bodyes which intersect the ray from start to end.
Definition: world.cpp:623
void setSize(const wVector &minPoint, const wVector &maxPoint)
See Physic Engine Documentation.
Definition: world.cpp:422
void removedObject(WObject *)
emitted when an WObject has been removed
QHash< WObject *, QList< PhyJoint * > > mapObjJoints
Map object -> joints.
Definition: world.h:441
real timestepv
The time step.
Definition: world.h:421
bool getStatic() const
Returns true if the object is static.
Definition: phyobject.h:97
void finished()
When exit from finalize method.
real time
The elapsed simulation-time from last calls of initialize()
Definition: world.h:419
void setFrictions(QString mat1, QString mat2, real st, real kn)
configure the default Friction between materials specified
Definition: world.cpp:66
void initialize()
Initialize the World, it doesn't do anything if it's already initialized.
Definition: world.cpp:206
void setIsRealTime(bool b)
Enable/Disable Real-time advance.
Definition: world.cpp:324
real gforce
Gravity Force.
Definition: world.h:423
const QHash< WObject *, QList< PhyJoint * > > mapObjectsToJoints()
Map object -> joints.
Definition: world.cpp:381
void cleanUpMemory()
Clean up memory.
Definition: world.cpp:502
wMatrix inverse() const
calculate the inverse of transformation matrix
Definition: wmatrix.h:258
FARSA_UTIL_TEMPLATE const T max(const T &t1, const U &t2)
QLinkedList< WObject * > objs
Vector of WObject inside the World.
Definition: world.h:435
const QLinkedList< WObject * > objects()
Return the vector of objects present in this world.
Definition: world.cpp:365
void pause()
Pause the World.
Definition: world.cpp:269
bool checkContacts(PhyObject *obj1, PhyObject *obj2, int maxContacts=4, QVector< wVector > *contacts=NULL, QVector< wVector > *normals=NULL, QVector< real > *penetra=NULL)
Checks whether two objects collide or not.
Definition: world.cpp:526
PhyObjectPrivate * priv
Engine encapsulation.
Definition: phyobject.h:159
void setElasticity(QString mat1, QString mat2, real)
configure the default Elasticity between materials specified the order doesn't matter ...
Definition: world.cpp:80
void addedJoint(PhyJoint *)
emitted when an PhyJoint has been added
PhyJoint class.
Definition: phyjoint.h:359
wVector minP
Size of the Newton world.
Definition: world.h:425
wMatrix class
Definition: wmatrix.h:48
World * worldv
World.
Definition: wobject.h:191
void finalize()
Operation performed at the end of the simulation.
Definition: world.cpp:253
const wMatrix & matrix() const
return a reference to the transformation matrix
Definition: wobject.cpp:47
void paused()
When the stop method is called.
const QLinkedList< PhyJoint * > joints()
Return the vector of joints present in this world.
Definition: world.cpp:377
void timerEvent(QTimerEvent *e)
Event for handling play/stop in order to stay syncronized with QT main thread.
Definition: world.cpp:286
void setSoftness(QString mat1, QString mat2, real)
configure the default Softness between materials specified the order doesn't matter ...
Definition: world.cpp:93
int play()
run the World calling advance as fast as possibile (return the timerId)
Definition: world.cpp:261
void stop()
Stop the World.
Definition: world.cpp:277
real gravityForce(QString mat)
Return the corresponding gravity force setted If no setted, that World::gravityForce will be returned...
Definition: world.cpp:110
void setTimeStep(real)
Set the time step.
Definition: world.cpp:332
void resetElapsedTime()
Reset the time counter and restart from zero seconds.
Definition: world.cpp:320
real timeStep() const
get the time step setted
Definition: world.cpp:342
void enableCollision(PhyObject *obj1, PhyObject *obj2)
Enable collision.
Definition: world.cpp:390
WObject * getObject(QString name)
Return the WObject with name specified, otherwise return NULL.
Definition: world.cpp:369
void initialized()
When exit from initialize method.
real elapsedTime() const
Get the elapsed time.
Definition: world.cpp:316
bool createMaterial(QString name)
Create a new material It return false if already exists a material with name passed.
Definition: world.cpp:40
const contactMap & contacts()
return the contact map
Definition: world.cpp:522
bool smartCheckContacts(PhyObject *obj1, PhyObject *obj2, int maxContacts=4, QVector< wVector > *contacts=NULL)
Checks whether two objects collide or not.
Definition: world.cpp:568
float real
real collisionRayCast(PhyObject *obj, wVector start, wVector end, wVector *normal=NULL)
Checks whether the ray from start to end intersects obj.
Definition: world.cpp:599
void setMultiThread(int numThreads)
Set the multi-thread functionality.
Definition: world.cpp:415
real gravityForce() const
Return the gravity force.
Definition: world.cpp:350
virtual ~World()
Destructor.
Definition: world.cpp:180
World(QString worldname)
Constructor.
Definition: world.cpp:146
void setProperties(QString mat1, QString mat2, real fs, real fk, real el, real sf, bool en=true)
set Frictions, Elasticity, Softness and Enabled/Disable collision between materials ...
Definition: world.cpp:131
bool closestPoints(PhyObject *objA, PhyObject *objB, wVector &pointA, wVector &pointB)
calculate the two closest points between the two objects;
Definition: world.cpp:650
QString name() const
Return the name of this object.
Definition: wobject.cpp:69
void stopped()
When the stopped method is called.
void setMinimumFrameRate(unsigned int frames)
Set the minimum frame rate; in other word the number of integration steps per seconds regardless the ...
Definition: world.cpp:336
Ownable * owner() const
Returns the owner of this object.
Definition: ownable.h:115
wVector transformVector(const wVector &v) const
apply both rotation and translation to the vector v
Definition: wmatrix.h:364
QString name() const
Return the name.
Definition: world.cpp:202
void setSolverModel(QString model)
See Physic Engine Documentation.
Definition: world.cpp:395
void advanced()
When exit from advance method.
bool isRealTime() const
return true is real-time is enabled ; false otherwise
Definition: world.cpp:328
QLinkedList< PhyJoint * > jointsv
Vector of Joints inside the World.
Definition: world.h:439
void disableCollision(PhyObject *obj1, PhyObject *obj2)
Disable collision between bodies.
Definition: world.cpp:385
void removedJoint(PhyJoint *)
emitted when an PhyJoint has been removed
void customEvent(QEvent *e)
Custom Events.
Definition: world.cpp:291
PhyObject class.
Definition: phyobject.h:46