21 #include "phyobject.h"
23 #include "private/phyobjectprivate.h"
24 #include "private/worldprivate.h"
25 #include "motorcontrollers.h"
27 #include <QMutexLocker>
31 #pragma GCC diagnostic ignored "-Wunused-parameter"
33 #ifdef FARSA_USE_YARP_AND_ICUB
34 #include "yarp/os/Network.h"
37 #pragma GCC diagnostic warning "-Wunused-parameter"
44 MaterialDB::MaterialDB( World* w ) : mats(), pmap() {
46 createMaterial(
"nonCollidable" );
47 createMaterial(
"default" );
51 if ( mats.contains( name ) ) {
54 #ifdef WORLDSIM_USE_NEWTON
55 NewtonWorld* ngdWorld = worldv->priv->world;
57 if ( name ==
"default" ) {
58 newm = NewtonMaterialGetDefaultGroupID( ngdWorld );
60 newm = NewtonMaterialCreateGroupID( ngdWorld );
62 worldv->priv->matIDs[name] = newm;
63 NewtonMaterialSetCollisionCallback( ngdWorld, newm, newm, (
void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
65 foreach( QString k, mats.values() ) {
66 int kid = worldv->priv->matIDs[k];
67 NewtonMaterialSetCollisionCallback( ngdWorld, newm, kid, (
void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
70 NewtonMaterialSetDefaultCollidable( ngdWorld, worldv->priv->matIDs[
"nonCollidable"], newm, 0 );
77 if ( !mats.contains( mat1 ) )
return;
78 if ( !mats.contains( mat2 ) )
return;
79 QString pkey = createKey( mat1, mat2 );
80 pmap[pkey].staticFriction = st;
81 pmap[pkey].dynamicFriction = kn;
82 #ifdef WORLDSIM_USE_NEWTON
83 int id1 = worldv->priv->matIDs[mat1];
84 int id2 = worldv->priv->matIDs[mat2];
85 NewtonMaterialSetDefaultFriction( worldv->priv->world, id1, id2, st, kn );
91 if ( !mats.contains( mat1 ) )
return;
92 if ( !mats.contains( mat2 ) )
return;
93 QString pkey = createKey( mat1, mat2 );
94 pmap[pkey].elasticity = el;
95 #ifdef WORLDSIM_USE_NEWTON
96 int id1 = worldv->priv->matIDs[mat1];
97 int id2 = worldv->priv->matIDs[mat2];
98 NewtonMaterialSetDefaultElasticity( worldv->priv->world, id1, id2, el );
104 if ( !mats.contains( mat1 ) )
return;
105 if ( !mats.contains( mat2 ) )
return;
106 QString pkey = createKey( mat1, mat2 );
107 pmap[pkey].softness = sf;
108 #ifdef WORLDSIM_USE_NEWTON
109 int id1 = worldv->priv->matIDs[mat1];
110 int id2 = worldv->priv->matIDs[mat2];
111 NewtonMaterialSetDefaultSoftness( worldv->priv->world, id1, id2, sf );
117 gravities[mat] = force;
121 if ( gravities.contains( mat ) ) {
122 return gravities[mat];
130 if ( !mats.contains( mat1 ) )
return;
131 if ( !mats.contains( mat2 ) )
return;
132 QString pkey = createKey( mat1, mat2 );
133 pmap[pkey].collisions = enable;
134 #ifdef WORLDSIM_USE_NEWTON
135 int id1 = worldv->priv->matIDs[mat1];
136 int id2 = worldv->priv->matIDs[mat2];
137 NewtonMaterialSetDefaultCollidable( worldv->priv->world, id1, id2, enable );
148 QString MaterialDB::createKey( QString mat1, QString mat2 ) {
150 return mat1 +
":" + mat2;
152 return mat1 +
":" + mat2;
157 : QObject(), minP(-100,-100,-100), maxP(100,100,100), objs(), jointsv(), mapObjJoints(),
159 #ifdef FARSA_USE_YARP_AND_ICUB
160 static QMutex yarpStuffsMutex;
161 static yarp::os::Network networkYarp;
162 if ( LocalYarpPorts ) {
163 QMutexLocker locker(&yarpStuffsMutex);
165 networkYarp.setLocalMode( LocalYarpPorts );
166 networkYarp.setVerbosity( -1 );
170 Q_UNUSED( LocalYarpPorts )
181 priv =
new WorldPrivate();
183 #ifdef WORLDSIM_USE_NEWTON
184 priv->world = NewtonCreate();
185 NewtonInvalidateCache( priv->world );
186 NewtonSetWorldSize( priv->world, &
minP[0], &maxP[0] );
188 NewtonSetMinimumFrameRate( priv->world, 100 );
190 NewtonSetSolverModel( priv->world, 0 );
191 NewtonSetFrictionModel( priv->world, 0 );
209 if ( js->
owner() == NULL ) {
213 while ( !
objs.isEmpty() ) {
215 if ( obj->
owner() == NULL ) {
219 #ifdef WORLDSIM_USE_NEWTON
220 NewtonDestroy( priv->world );
230 if ( isInit )
return;
246 while( isrealtimev && timer.
tac()/1000000.0 <
timestepv ) { };
250 for( QLinkedList<WObject*>::iterator it =
objs.begin(); it !=
objs.end(); it++ ) {
254 for( QLinkedList<PhyJoint*>::iterator it =
jointsv.begin(); it !=
jointsv.end(); it++ ) {
260 #ifdef WORLDSIM_USE_NEWTON
264 for( QLinkedList<WObject*>::iterator it =
objs.begin(); it !=
objs.end(); it++ ) {
268 for( QLinkedList<PhyJoint*>::iterator it =
jointsv.begin(); it !=
jointsv.end(); it++ ) {
277 if ( isFinish )
return;
285 if ( state == playingS )
return timerId;
286 if ( timerId != 0 )
return timerId;
288 timerId = startTimer( 0 );
294 if ( timerId != 0 ) killTimer( timerId );
303 if ( timerId != 0 ) killTimer( timerId );
315 switch( e->type() ) {
360 #ifdef WORLDSIM_USE_NEWTON
361 NewtonSetMinimumFrameRate( priv->world, frames );
378 blockSignals(
true );
379 bool b = isrealtimev;
385 blockSignals(
false );
395 if ( obj->
name() ==
name )
return obj;
409 nobjs.insert( qMakePair( obj1, obj2 ) );
410 nobjs.insert( qMakePair( obj2, obj1 ) );
414 nobjs.remove( qMakePair( obj1, obj2 ) );
415 nobjs.remove( qMakePair( obj2, obj1 ) );
419 #ifdef WORLDSIM_USE_NEWTON
420 if ( model ==
"exact" ) {
421 NewtonSetSolverModel( priv->world, 0 );
422 }
else if ( model ==
"linear" ) {
423 NewtonSetSolverModel( priv->world, 1 );
429 #ifdef WORLDSIM_USE_NEWTON
430 if ( model ==
"exact" ) {
431 NewtonSetFrictionModel( priv->world, 0 );
432 }
else if ( model ==
"linear" ) {
433 NewtonSetFrictionModel( priv->world, 1 );
439 #ifdef WORLDSIM_USE_NEWTON
440 numThreads =
max( 1, numThreads );
441 NewtonSetThreadsCount( priv->world, numThreads );
448 #ifdef WORLDSIM_USE_NEWTON
449 NewtonSetWorldSize( priv->world, &
minP[0], &maxP[0] );
459 void World::pushObject(
WObject* phy ) {
460 objs.push_back( phy );
464 void World::popObject( WObject* phy ) {
465 const int numRemoved =
objs.removeAll( phy );
466 if ( numRemoved == 1 ) {
469 PhyObject*
const phyObject =
dynamic_cast<PhyObject*
>(phy);
470 if ( ( phyObject != NULL ) && ( cmap.contains( phyObject ) ) ) {
471 const contactVec &cvec = cmap[ phyObject ];
472 foreach ( Contact c, cvec ) {
473 contactVec &otherCVec = cmap[ c.collide ];
474 contactVec::iterator it = otherCVec.begin();
475 while ( it != otherCVec.end() ) {
476 if ( it->collide == phyObject ) {
477 it = otherCVec.erase( it );
482 if ( otherCVec.isEmpty() ) {
484 cmap.remove( c.collide );
487 cmap.remove( phyObject );
492 else if (numRemoved > 1) {
493 qDebug(
"INTERNAL ERROR: more than one object with the same address found in the World::objs list" );
498 void World::pushJoint( PhyJoint* phy ) {
501 if ( phy->parent() ) {
507 void World::popJoint( PhyJoint* phy ) {
508 const int numRemoved =
jointsv.removeAll( phy );
509 if ( numRemoved == 1 ) {
512 if ( phy->parent() ) {
519 else if (numRemoved > 1) {
520 qDebug(
"INTERNAL ERROR: more than one joint with the same address found in the World::jointsv list" );
526 #ifdef WORLDSIM_USE_NEWTON
528 NewtonInvalidateCache( priv->world );
550 #ifdef WORLDSIM_USE_NEWTON
552 real *
const tmp_data =
new real[2 * 3 * maxContacts + maxContacts];
553 real *
const tmp_contacts = &tmp_data[0 * 3 * maxContacts];
554 real *
const tmp_normals = &tmp_data[1 * 3 * maxContacts];
555 real *
const tmp_penetra = &tmp_data[2 * 3 * maxContacts];
560 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 );
563 if (contacts != NULL) {
564 contacts->resize(numContacts);
565 for (
int i = 0; i < numContacts; i++) {
566 (*contacts)[i].x = tmp_contacts[0 + i * 3];
567 (*contacts)[i].y = tmp_contacts[1 + i * 3];
568 (*contacts)[i].z = tmp_contacts[2 + i * 3];
571 if (normals != NULL) {
572 normals->resize(numContacts);
573 for (
int i = 0; i < numContacts; i++) {
574 (*normals)[i].x = tmp_normals[0 + i * 3];
575 (*normals)[i].y = tmp_normals[1 + i * 3];
576 (*normals)[i].z = tmp_normals[2 + i * 3];
579 if (penetra != NULL) {
580 penetra->resize(numContacts);
581 for (
int i = 0; i < numContacts; i++) {
582 (*penetra)[i] = tmp_penetra[i];
587 return (numContacts != 0);
594 return checkContacts( obj1, obj2, maxContacts, contacts, NULL, NULL);
596 if (!cmap.contains(obj1)) {
601 const contactVec& c = cmap[obj1];
602 bool collision =
false;
603 if (contacts != NULL) {
608 for (
int i = 0; i < c.size(); i++) {
609 if (c[i].collide == obj2) {
611 if ((contacts != NULL) && (contacts->size() < maxContacts)) {
613 contacts->append(c[i].worldPos);
624 #ifdef WORLDSIM_USE_NEWTON
632 const real contact = NewtonCollisionRayCast(obj->
priv->collision, &localStart[0], &localEnd[0], n, &attribute);
634 if (normal != NULL) {
648 #ifdef WORLDSIM_USE_NEWTON
649 WorldPrivate::WorldRayCastCallbackUserData data(start, end, onlyClosest, ignoredObjs);
652 NewtonWorldRayCast(priv->world, &start[0], &end[0], WorldPrivate::worldRayFilterCallback, &data, NULL);
656 return rayCastHitVector();
674 #ifdef WORLDSIM_USE_NEWTON
678 int ret = NewtonCollisionClosestPoint( priv->world,
679 objA->
priv->collision, &t1[0][0],
680 objB->
priv->collision, &t2[0][0],
681 &pointA[0], &pointB[0], &normal[0], 0 );