21 #include "phyobject.h"
23 #include "private/phyobjectprivate.h"
24 #include "private/worldprivate.h"
25 #include "motorcontrollers.h"
28 #pragma GCC diagnostic ignored "-Wunused-parameter"
30 #ifdef FARSA_USE_YARP_AND_ICUB
31 #include "yarp/os/Network.h"
34 #pragma GCC diagnostic warning "-Wunused-parameter"
50 worldv->pushObject(
this );
58 MaterialDB::MaterialDB(
World* w ) : mats(), pmap() {
60 createMaterial(
"nonCollidable" );
61 createMaterial(
"default" );
65 if ( mats.contains( name ) ) {
68 #ifdef WORLDSIM_USE_NEWTON
69 NewtonWorld* ngdWorld = worldv->priv->world;
71 if ( name ==
"default" ) {
72 newm = NewtonMaterialGetDefaultGroupID( ngdWorld );
74 newm = NewtonMaterialCreateGroupID( ngdWorld );
76 worldv->priv->matIDs[name] = newm;
77 NewtonMaterialSetCollisionCallback( ngdWorld, newm, newm, (
void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
79 foreach( QString k, mats.values() ) {
80 int kid = worldv->priv->matIDs[k];
81 NewtonMaterialSetCollisionCallback( ngdWorld, newm, kid, (
void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
84 NewtonMaterialSetDefaultCollidable( ngdWorld, worldv->priv->matIDs[
"nonCollidable"], newm, 0 );
91 if ( !mats.contains( mat1 ) )
return;
92 if ( !mats.contains( mat2 ) )
return;
93 QString pkey = createKey( mat1, mat2 );
94 pmap[pkey].staticFriction = st;
95 pmap[pkey].dynamicFriction = kn;
96 #ifdef WORLDSIM_USE_NEWTON
97 int id1 = worldv->priv->matIDs[mat1];
98 int id2 = worldv->priv->matIDs[mat2];
99 NewtonMaterialSetDefaultFriction( worldv->priv->world, id1, id2, st, kn );
105 if ( !mats.contains( mat1 ) )
return;
106 if ( !mats.contains( mat2 ) )
return;
107 QString pkey = createKey( mat1, mat2 );
108 pmap[pkey].elasticity = el;
109 #ifdef WORLDSIM_USE_NEWTON
110 int id1 = worldv->priv->matIDs[mat1];
111 int id2 = worldv->priv->matIDs[mat2];
112 NewtonMaterialSetDefaultElasticity( worldv->priv->world, id1, id2, el );
118 if ( !mats.contains( mat1 ) )
return;
119 if ( !mats.contains( mat2 ) )
return;
120 QString pkey = createKey( mat1, mat2 );
121 pmap[pkey].softness = sf;
122 #ifdef WORLDSIM_USE_NEWTON
123 int id1 = worldv->priv->matIDs[mat1];
124 int id2 = worldv->priv->matIDs[mat2];
125 NewtonMaterialSetDefaultSoftness( worldv->priv->world, id1, id2, sf );
131 gravities[mat] = force;
135 if ( gravities.contains( mat ) ) {
136 return gravities[mat];
144 if ( !mats.contains( mat1 ) )
return;
145 if ( !mats.contains( mat2 ) )
return;
146 QString pkey = createKey( mat1, mat2 );
147 pmap[pkey].collisions = enable;
148 #ifdef WORLDSIM_USE_NEWTON
149 int id1 = worldv->priv->matIDs[mat1];
150 int id2 = worldv->priv->matIDs[mat2];
151 NewtonMaterialSetDefaultCollidable( worldv->priv->world, id1, id2, enable );
162 QString MaterialDB::createKey( QString mat1, QString mat2 ) {
164 return mat1 +
":" + mat2;
166 return mat1 +
":" + mat2;
171 : QObject(), minP(-100,-100,-100), maxP(100,100,100), objs(), jointsv(), mapObjJoints(),
173 #ifdef FARSA_USE_YARP_AND_ICUB
174 static yarp::os::Network networkYarp;
175 if ( LocalYarpPorts ) {
176 networkYarp.setLocalMode( LocalYarpPorts );
177 networkYarp.setVerbosity( -1 );
181 Q_UNUSED( LocalYarpPorts )
192 priv =
new WorldPrivate();
194 #ifdef WORLDSIM_USE_NEWTON
195 priv->world = NewtonCreate();
196 NewtonInvalidateCache( priv->world );
197 NewtonSetWorldSize( priv->world, &
minP[0], &maxP[0] );
199 NewtonSetMinimumFrameRate( priv->world, 100 );
201 NewtonSetSolverModel( priv->world, 0 );
202 NewtonSetFrictionModel( priv->world, 0 );
220 if ( js->
owner() == NULL ) {
224 while ( !
objs.isEmpty() ) {
226 if ( obj->
owner() == NULL ) {
230 #ifdef WORLDSIM_USE_NEWTON
231 NewtonDestroy( priv->world );
241 if ( isInit )
return;
257 while( isrealtimev && timer.
tac()/1000000.0 <
timestepv ) { };
262 for( QLinkedList<WObject*>::iterator it =
objs.begin(); it !=
objs.end(); it++ ) {
266 for( QLinkedList<PhyJoint*>::iterator it =
jointsv.begin(); it !=
jointsv.end(); it++ ) {
270 #ifdef WORLDSIM_USE_NEWTON
274 for( QLinkedList<WObject*>::iterator it =
objs.begin(); it !=
objs.end(); it++ ) {
278 for( QLinkedList<PhyJoint*>::iterator it =
jointsv.begin(); it !=
jointsv.end(); it++ ) {
286 if ( isFinish )
return;
294 if ( state == playingS )
return timerId;
295 if ( timerId != 0 )
return timerId;
297 timerId = startTimer( 0 );
303 if ( timerId != 0 ) killTimer( timerId );
312 if ( timerId != 0 ) killTimer( timerId );
324 switch( e->type() ) {
369 #ifdef WORLDSIM_USE_NEWTON
370 NewtonSetMinimumFrameRate( priv->world, frames );
387 blockSignals(
true );
388 bool b = isrealtimev;
394 blockSignals(
false );
404 if ( obj->
name() ==
name )
return obj;
418 nobjs.insert( qMakePair( obj1, obj2 ) );
419 nobjs.insert( qMakePair( obj2, obj1 ) );
423 nobjs.remove( qMakePair( obj1, obj2 ) );
424 nobjs.remove( qMakePair( obj2, obj1 ) );
428 #ifdef WORLDSIM_USE_NEWTON
429 if ( model ==
"exact" ) {
430 NewtonSetSolverModel( priv->world, 0 );
431 }
else if ( model ==
"linear" ) {
432 NewtonSetSolverModel( priv->world, 1 );
438 #ifdef WORLDSIM_USE_NEWTON
439 if ( model ==
"exact" ) {
440 NewtonSetFrictionModel( priv->world, 0 );
441 }
else if ( model ==
"linear" ) {
442 NewtonSetFrictionModel( priv->world, 1 );
448 #ifdef WORLDSIM_USE_NEWTON
449 numThreads =
max( 1, numThreads );
450 NewtonSetThreadsCount( priv->world, numThreads );
457 #ifdef WORLDSIM_USE_NEWTON
458 NewtonSetWorldSize( priv->world, &
minP[0], &maxP[0] );
468 void World::pushObject(
WObject* phy ) {
469 objs.push_back( phy );
473 void World::popObject( WObject* phy ) {
474 const int numRemoved =
objs.removeAll( phy );
475 if ( numRemoved == 1 ) {
479 else if (numRemoved > 1) {
480 qDebug(
"INTERNAL ERROR: more than one object with the same address found in the World::objs list" );
485 void World::pushJoint( PhyJoint* phy ) {
488 if ( phy->parent() ) {
494 void World::popJoint( PhyJoint* phy ) {
495 const int numRemoved =
jointsv.removeAll( phy );
496 if ( numRemoved == 1 ) {
499 if ( phy->parent() ) {
506 else if (numRemoved > 1) {
507 qDebug(
"INTERNAL ERROR: more than one joint with the same address found in the World::jointsv list" );
513 #ifdef WORLDSIM_USE_NEWTON
515 NewtonInvalidateCache( priv->world );
537 #ifdef WORLDSIM_USE_NEWTON
539 real *
const tmp_data =
new real[2 * 3 * maxContacts + maxContacts];
540 real *
const tmp_contacts = &tmp_data[0 * 3 * maxContacts];
541 real *
const tmp_normals = &tmp_data[1 * 3 * maxContacts];
542 real *
const tmp_penetra = &tmp_data[2 * 3 * maxContacts];
547 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 );
550 if (contacts != NULL) {
551 contacts->resize(numContacts);
552 for (
int i = 0; i < numContacts; i++) {
553 (*contacts)[i].x = tmp_contacts[0 + i * 3];
554 (*contacts)[i].y = tmp_contacts[1 + i * 3];
555 (*contacts)[i].z = tmp_contacts[2 + i * 3];
558 if (normals != NULL) {
559 normals->resize(numContacts);
560 for (
int i = 0; i < numContacts; i++) {
561 (*normals)[i].x = tmp_normals[0 + i * 3];
562 (*normals)[i].y = tmp_normals[1 + i * 3];
563 (*normals)[i].z = tmp_normals[2 + i * 3];
566 if (penetra != NULL) {
567 penetra->resize(numContacts);
568 for (
int i = 0; i < numContacts; i++) {
569 (*penetra)[i] = tmp_penetra[i];
574 return (numContacts != 0);
581 return checkContacts( obj1, obj2, maxContacts, contacts, NULL, NULL);
583 if (!cmap.contains(obj1)) {
588 const contactVec& c = cmap[obj1];
589 bool collision =
false;
590 if (contacts != NULL) {
595 for (
int i = 0; i < c.size(); i++) {
596 if (c[i].collide == obj2) {
598 if ((contacts != NULL) && (contacts->size() < maxContacts)) {
600 contacts->append(c[i].worldPos);
611 #ifdef WORLDSIM_USE_NEWTON
619 const real contact = NewtonCollisionRayCast(obj->
priv->collision, &localStart[0], &localEnd[0], n, &attribute);
621 if (normal != NULL) {
635 #ifdef WORLDSIM_USE_NEWTON
636 WorldPrivate::WorldRayCastCallbackUserData data(start, end, onlyClosest, ignoredObjs);
639 NewtonWorldRayCast(priv->world, &start[0], &end[0], WorldPrivate::worldRayFilterCallback, &data, NULL);
643 return rayCastHitVector();
661 #ifdef WORLDSIM_USE_NEWTON
665 int ret = NewtonCollisionClosestPoint( priv->world,
666 objA->
priv->collision, &t1[0][0],
667 objB->
priv->collision, &t2[0][0],
668 &pointA[0], &pointB[0], &normal[0], 0 );