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"
41 MaterialDB::MaterialDB( World* w ) : mats(), pmap() {
43 createMaterial(
"nonCollidable" );
44 createMaterial(
"default" );
48 if ( mats.contains( name ) ) {
51 #ifdef WORLDSIM_USE_NEWTON
52 NewtonWorld* ngdWorld = worldv->priv->world;
54 if ( name ==
"default" ) {
55 newm = NewtonMaterialGetDefaultGroupID( ngdWorld );
57 newm = NewtonMaterialCreateGroupID( ngdWorld );
59 worldv->priv->matIDs[name] = newm;
60 NewtonMaterialSetCollisionCallback( ngdWorld, newm, newm, (
void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
62 foreach( QString k, mats.values() ) {
63 int kid = worldv->priv->matIDs[k];
64 NewtonMaterialSetCollisionCallback( ngdWorld, newm, kid, (
void*)worldv, NULL, (WorldPrivate::processCollisionHandler) );
67 NewtonMaterialSetDefaultCollidable( ngdWorld, worldv->priv->matIDs[
"nonCollidable"], newm, 0 );
74 if ( !mats.contains( mat1 ) )
return;
75 if ( !mats.contains( mat2 ) )
return;
76 QString pkey = createKey( mat1, mat2 );
77 pmap[pkey].staticFriction = st;
78 pmap[pkey].dynamicFriction = kn;
79 #ifdef WORLDSIM_USE_NEWTON
80 int id1 = worldv->priv->matIDs[mat1];
81 int id2 = worldv->priv->matIDs[mat2];
82 NewtonMaterialSetDefaultFriction( worldv->priv->world, id1, id2, st, kn );
88 if ( !mats.contains( mat1 ) )
return;
89 if ( !mats.contains( mat2 ) )
return;
90 QString pkey = createKey( mat1, mat2 );
91 pmap[pkey].elasticity = el;
92 #ifdef WORLDSIM_USE_NEWTON
93 int id1 = worldv->priv->matIDs[mat1];
94 int id2 = worldv->priv->matIDs[mat2];
95 NewtonMaterialSetDefaultElasticity( worldv->priv->world, id1, id2, el );
101 if ( !mats.contains( mat1 ) )
return;
102 if ( !mats.contains( mat2 ) )
return;
103 QString pkey = createKey( mat1, mat2 );
104 pmap[pkey].softness = sf;
105 #ifdef WORLDSIM_USE_NEWTON
106 int id1 = worldv->priv->matIDs[mat1];
107 int id2 = worldv->priv->matIDs[mat2];
108 NewtonMaterialSetDefaultSoftness( worldv->priv->world, id1, id2, sf );
114 gravities[mat] = force;
118 if ( gravities.contains( mat ) ) {
119 return gravities[mat];
127 if ( !mats.contains( mat1 ) )
return;
128 if ( !mats.contains( mat2 ) )
return;
129 QString pkey = createKey( mat1, mat2 );
130 pmap[pkey].collisions = enable;
131 #ifdef WORLDSIM_USE_NEWTON
132 int id1 = worldv->priv->matIDs[mat1];
133 int id2 = worldv->priv->matIDs[mat2];
134 NewtonMaterialSetDefaultCollidable( worldv->priv->world, id1, id2, enable );
145 QString MaterialDB::createKey( QString mat1, QString mat2 ) {
147 return mat1 +
":" + mat2;
149 return mat1 +
":" + mat2;
154 : QObject(), minP(-100,-100,-100), maxP(100,100,100), objs(), jointsv(), mapObjJoints(),
156 #ifdef FARSA_USE_YARP_AND_ICUB
157 static yarp::os::Network networkYarp;
158 if ( LocalYarpPorts ) {
159 networkYarp.setLocalMode( LocalYarpPorts );
160 networkYarp.setVerbosity( -1 );
164 Q_UNUSED( LocalYarpPorts )
175 priv =
new WorldPrivate();
177 #ifdef WORLDSIM_USE_NEWTON
178 priv->world = NewtonCreate();
179 NewtonInvalidateCache( priv->world );
180 NewtonSetWorldSize( priv->world, &
minP[0], &maxP[0] );
182 NewtonSetMinimumFrameRate( priv->world, 100 );
184 NewtonSetSolverModel( priv->world, 0 );
185 NewtonSetFrictionModel( priv->world, 0 );
203 if ( js->
owner() == NULL ) {
207 while ( !
objs.isEmpty() ) {
209 if ( obj->
owner() == NULL ) {
213 #ifdef WORLDSIM_USE_NEWTON
214 NewtonDestroy( priv->world );
224 if ( isInit )
return;
240 while( isrealtimev && timer.
tac()/1000000.0 <
timestepv ) { };
245 for( QLinkedList<WObject*>::iterator it =
objs.begin(); it !=
objs.end(); it++ ) {
249 for( QLinkedList<PhyJoint*>::iterator it =
jointsv.begin(); it !=
jointsv.end(); it++ ) {
253 #ifdef WORLDSIM_USE_NEWTON
257 for( QLinkedList<WObject*>::iterator it =
objs.begin(); it !=
objs.end(); it++ ) {
261 for( QLinkedList<PhyJoint*>::iterator it =
jointsv.begin(); it !=
jointsv.end(); it++ ) {
269 if ( isFinish )
return;
277 if ( state == playingS )
return timerId;
278 if ( timerId != 0 )
return timerId;
280 timerId = startTimer( 0 );
286 if ( timerId != 0 ) killTimer( timerId );
295 if ( timerId != 0 ) killTimer( timerId );
307 switch( e->type() ) {
352 #ifdef WORLDSIM_USE_NEWTON
353 NewtonSetMinimumFrameRate( priv->world, frames );
370 blockSignals(
true );
371 bool b = isrealtimev;
377 blockSignals(
false );
387 if ( obj->
name() ==
name )
return obj;
401 nobjs.insert( qMakePair( obj1, obj2 ) );
402 nobjs.insert( qMakePair( obj2, obj1 ) );
406 nobjs.remove( qMakePair( obj1, obj2 ) );
407 nobjs.remove( qMakePair( obj2, obj1 ) );
411 #ifdef WORLDSIM_USE_NEWTON
412 if ( model ==
"exact" ) {
413 NewtonSetSolverModel( priv->world, 0 );
414 }
else if ( model ==
"linear" ) {
415 NewtonSetSolverModel( priv->world, 1 );
421 #ifdef WORLDSIM_USE_NEWTON
422 if ( model ==
"exact" ) {
423 NewtonSetFrictionModel( priv->world, 0 );
424 }
else if ( model ==
"linear" ) {
425 NewtonSetFrictionModel( priv->world, 1 );
431 #ifdef WORLDSIM_USE_NEWTON
432 numThreads =
max( 1, numThreads );
433 NewtonSetThreadsCount( priv->world, numThreads );
440 #ifdef WORLDSIM_USE_NEWTON
441 NewtonSetWorldSize( priv->world, &
minP[0], &maxP[0] );
451 void World::pushObject(
WObject* phy ) {
452 objs.push_back( phy );
456 void World::popObject( WObject* phy ) {
457 const int numRemoved =
objs.removeAll( phy );
458 if ( numRemoved == 1 ) {
462 else if (numRemoved > 1) {
463 qDebug(
"INTERNAL ERROR: more than one object with the same address found in the World::objs list" );
468 void World::pushJoint( PhyJoint* phy ) {
471 if ( phy->parent() ) {
477 void World::popJoint( PhyJoint* phy ) {
478 const int numRemoved =
jointsv.removeAll( phy );
479 if ( numRemoved == 1 ) {
482 if ( phy->parent() ) {
489 else if (numRemoved > 1) {
490 qDebug(
"INTERNAL ERROR: more than one joint with the same address found in the World::jointsv list" );
496 #ifdef WORLDSIM_USE_NEWTON
498 NewtonInvalidateCache( priv->world );
520 #ifdef WORLDSIM_USE_NEWTON
522 real *
const tmp_data =
new real[2 * 3 * maxContacts + maxContacts];
523 real *
const tmp_contacts = &tmp_data[0 * 3 * maxContacts];
524 real *
const tmp_normals = &tmp_data[1 * 3 * maxContacts];
525 real *
const tmp_penetra = &tmp_data[2 * 3 * maxContacts];
530 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 );
533 if (contacts != NULL) {
534 contacts->resize(numContacts);
535 for (
int i = 0; i < numContacts; i++) {
536 (*contacts)[i].x = tmp_contacts[0 + i * 3];
537 (*contacts)[i].y = tmp_contacts[1 + i * 3];
538 (*contacts)[i].z = tmp_contacts[2 + i * 3];
541 if (normals != NULL) {
542 normals->resize(numContacts);
543 for (
int i = 0; i < numContacts; i++) {
544 (*normals)[i].x = tmp_normals[0 + i * 3];
545 (*normals)[i].y = tmp_normals[1 + i * 3];
546 (*normals)[i].z = tmp_normals[2 + i * 3];
549 if (penetra != NULL) {
550 penetra->resize(numContacts);
551 for (
int i = 0; i < numContacts; i++) {
552 (*penetra)[i] = tmp_penetra[i];
557 return (numContacts != 0);
564 return checkContacts( obj1, obj2, maxContacts, contacts, NULL, NULL);
566 if (!cmap.contains(obj1)) {
571 const contactVec& c = cmap[obj1];
572 bool collision =
false;
573 if (contacts != NULL) {
578 for (
int i = 0; i < c.size(); i++) {
579 if (c[i].collide == obj2) {
581 if ((contacts != NULL) && (contacts->size() < maxContacts)) {
583 contacts->append(c[i].worldPos);
594 #ifdef WORLDSIM_USE_NEWTON
602 const real contact = NewtonCollisionRayCast(obj->
priv->collision, &localStart[0], &localEnd[0], n, &attribute);
604 if (normal != NULL) {
618 #ifdef WORLDSIM_USE_NEWTON
619 WorldPrivate::WorldRayCastCallbackUserData data(start, end, onlyClosest, ignoredObjs);
622 NewtonWorldRayCast(priv->world, &start[0], &end[0], WorldPrivate::worldRayFilterCallback, &data, NULL);
626 return rayCastHitVector();
644 #ifdef WORLDSIM_USE_NEWTON
648 int ret = NewtonCollisionClosestPoint( priv->world,
649 objA->
priv->collision, &t1[0][0],
650 objB->
priv->collision, &t2[0][0],
651 &pointA[0], &pointB[0], &normal[0], 0 );