Esempio n. 1
0
void CProtoHapticDoc::nearCallback(dGeomID o1, dGeomID o2)
{
	int index1= (int)dGeomGetData(o1);
	int index2= (int)dGeomGetData(o2);

	if(m_shapes[index1]->isCollisionDynamic() || 
	   m_shapes[index2]->isCollisionDynamic()) {

		int n, i;
		const int N = 50;
		dContact contact[N];
		n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
		if (n > 0) {
			OutputDebugString("Collision\n");
			for (i=0; i<n; i++) {
				contact[i].surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1;
				if (dGeomGetClass(o1) == dSphereClass || dGeomGetClass(o2) == dSphereClass)
					contact[i].surface.mu = 20;
				else
					contact[i].surface.mu = 0.5;
				contact[i].surface.slip1 = 1.0 - (m_shapes[index1]->getSurfaceFriction());
				contact[i].surface.slip2 = 1.0 - (m_shapes[index2]->getSurfaceFriction());
				contact[i].surface.soft_erp = 0.8;
				contact[i].surface.soft_cfm = 0.01;
				dJointID c = dJointCreateContact (m_worldID,m_jointGroup,contact+i);
				dJointAttach (c,dGeomGetBody(o1),dGeomGetBody(o2));
			}
		}
	}

}
Esempio n. 2
0
void PWorld::initAllObjects()
{
    objects_count = objects.count();
    int c = objects_count;
    bool flag = false;
    if (sur_matrix!=NULL)
    {
        for (int i=0;i<c;i++)
        {
          if(sur_matrix[i]!=NULL)
            delete sur_matrix[i];
        }
        delete sur_matrix;
        flag = true;
    }    
    sur_matrix = new int* [c];
    for (int i=0;i<c;i++)
    {
        sur_matrix[i] = new int [c];    
        for (int j=0;j<c;j++)
            sur_matrix[i][j] = -1;
    }
    if (flag)
    {
        for (int i=0;i<surfaces.count();i++)
            sur_matrix[(*(int*)(dGeomGetData(surfaces[i]->id1)))][*((int*)(dGeomGetData(surfaces[i]->id2)))] =
            sur_matrix[(*(int*)(dGeomGetData(surfaces[i]->id2)))][*((int*)(dGeomGetData(surfaces[i]->id1)))] = i;
    }
}
Esempio n. 3
0
int Geoms_Can_Interpenetrate(dGeomID o1, dGeomID o2) {

	int object1IsPartOfRobot = false;

	if ( o1!=ground ) {
		OBJECT *obj1 = (OBJECT *)dGeomGetData(o1);
		object1IsPartOfRobot = obj1->Is_Part_Of_Robot();
	}

	int object2IsPartOfRobot = false;

	if ( o2!=ground ) {
		OBJECT *obj2 = (OBJECT *)dGeomGetData(o2);
		object2IsPartOfRobot = obj2->Is_Part_Of_Robot();
	}

	// Robot body parts can interpenetrate; don't compute 
	// contacts between them. 
	// Don't bother computing contacts between different
	// parts of the environment, because they do not move.
	// TBD: Last statement not necessarily true; could have hinged parts
	// in environment. 

	// return true if both objects are part of a robot
	// or both objects are part of the environment

	return !(object1IsPartOfRobot ^ object2IsPartOfRobot);
}
Esempio n. 4
0
File: M3.cpp Progetto: jbongard/ISCS
int Geoms_Can_Interpenetrate(dGeomID o1, dGeomID o2) {

	int object1IsPartOfRobot = false;

	if ( o1!=ground ) {
		OBJECT *obj1 = (OBJECT *)dGeomGetData(o1);
		object1IsPartOfRobot = obj1->Is_Part_Of_Robot();
	}

	int object2IsPartOfRobot = false;

	if ( o2!=ground ) {
		OBJECT *obj2 = (OBJECT *)dGeomGetData(o2);
		object2IsPartOfRobot = obj2->Is_Part_Of_Robot();
	}

	int bothArePartOfRobot =	object1IsPartOfRobot && 					object2IsPartOfRobot;
	// Robot body parts can interpenetrate

	int bothArePartOfEnvironment =	(!object1IsPartOfRobot) &&
					(!object2IsPartOfRobot);
	// Don't bother computing contacts between different
	// parts of the environment, because they do not move.

	return( bothArePartOfRobot || bothArePartOfEnvironment );
}
void PhysWorld::mCallback(void * data, dGeomID g1, dGeomID g2)
{
	//Get our CollidableObjects and tell them that a collision
	//has occured
	CollidableObject* colObj1 = (CollidableObject*)dGeomGetData(g1);
	CollidableObject* colObj2 = (CollidableObject*)dGeomGetData(g2);
	colObj1->OnCollide(colObj2);
	colObj2->OnCollide(colObj1);
}
Esempio n. 6
0
void ODEEngine::near_callback(dGeomID o1, dGeomID o2) {
    ODECollidable* c1 = (ODECollidable*) dGeomGetData(o1);
    ODECollidable* c2 = (ODECollidable*) dGeomGetData(o2);

    dContact contact[MAX_CONTACTS];

    int collision_count = dCollide(o1, o2, MAX_CONTACTS, &contact[0].geom, sizeof(dContact));

    for(int32_t i = 0; i < collision_count; ++i) {
        //Calculate combined surface values to build contact joints

        contact[i].surface.mode = dContactBounce;
        contact[i].surface.bounce = c1->bounciness() * c2->bounciness();

        if(c1->has_infinite_friction() || c2->has_infinite_friction()) {
            contact[i].surface.mu = dInfinity;
        } else {
            contact[i].surface.mu = c1->friction() * c2->friction();
        }

        dBodyID body1 = dGeomGetBody(contact[i].geom.g1);
        dBodyID body2 = dGeomGetBody(contact[i].geom.g2);

        if(body1 == body2) {
            //Don't collide the same body against itself
            continue;
        }

        if(i == 0) {
            //Fire the collision signal on the first loop only
            c1->signal_collided_(*c2);
            c2->signal_collided_(*c1);

            //Fire any combined signals
            fire_collision_signals_for(*c1, *c2);
        }

        //Check to see if we should create response joints, or just ignore the collision

        if(c1->is_ghost() || c2->is_ghost()) {
            //Don't respond if we're not supposed to (e.g. we're a hit zone or something)
            continue;
        }

        if(c1->should_respond_callback_ && !c1->should_respond_callback_(*c2)) {
            continue;
        }

        if(c2->should_respond_callback_ && !c2->should_respond_callback_(*c1)) {
            continue;
        }

        dJointID c = dJointCreateContact(world(), contact_group_, &contact[i]);
        dJointAttach(c, body1, body2);
    }
}
Esempio n. 7
0
// main collision handling function
void PhysicsServer::checkCollision(void *data, dGeomID o1, dGeomID o2)
{
	int i,n;
    if( dGeomIsSpace( o1 ) || dGeomIsSpace( o2 ) )
	{
		dSpaceCollide2( o1, o2, data, &collisionCallback );
	}
	else
	{
		int		mode	= 0;
		double	slip1	= 0;
		double	slip2	= 0;

		// get bodies
		dBodyID body1 = dGeomGetBody(o1);
		dBodyID body2 = dGeomGetBody(o2);

		// get geom data
		PhysGeomData* pData1 = (PhysGeomData*)dGeomGetData(o1);
		PhysGeomData* pData2 = (PhysGeomData*)dGeomGetData(o2);

		// set contact params according to geom data
		if (pData1 != NULL)
			slip1 = pData1->slip;
	
		if (pData2 != NULL)
			slip2 = pData2->slip;
	
		// set mode
		if (slip1 != 0)
			mode |= dContactSlip1;

		if (slip2 != 0)
			mode |= dContactSlip2;

		static const int N = 8; // max number of contact points
		dContact contact[N];
		n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
		if (n > 0) 
		{
			for (i=0; i<n; i++) 
			{
			  contact[i].surface.mode = mode; /*dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM;*/
			  contact[i].surface.mu = dInfinity;
			  contact[i].surface.slip1 = slip1;
			  contact[i].surface.slip2 = slip2;
//			  contact[i].surface.soft_erp = 0.7;
//			  contact[i].surface.soft_cfm = 0.1;
			  dJointID c = dJointCreateContact (_world, _contactgroup, &contact[i]);
			  dJointAttach (c, body1, body2);
			}
		}
	}

}
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  size_t i,j;
  i = (size_t) dGeomGetData (o1);
  j = (size_t) dGeomGetData (o2);
  if (i==j)
    printf ("collision (%d,%d) is between the same object\n",i,j);
  if (!good_matrix[i][j] || !good_matrix[j][i])
    printf ("collision (%d,%d) is incorrect\n",i,j);
  if (test_matrix[i][j] || test_matrix[j][i])
    printf ("collision (%d,%d) reported more than once\n",i,j);
  test_matrix[i][j] = 1;
  test_matrix[j][i] = 1;
}
Esempio n. 9
0
void selfCollisionCallback(void *data, dGeomID o1, dGeomID o2)
{
  ODERobot* robot = reinterpret_cast<ODERobot*>(data);
  Assert(!dGeomIsSpace(o1) && !dGeomIsSpace(o2));
  intptr_t link1 = (intptr_t)dGeomGetData(o1);
  intptr_t link2 = (intptr_t)dGeomGetData(o2);
  Assert(link1 >= 0 && (int)link1 < (int)robot->robot.links.size());
  Assert(link2 >= 0 && (int)link2 < (int)robot->robot.links.size());
  if(robot->robot.selfCollisions(link1,link2)==NULL) {
    return;
  }
  
  int num = dCollide (o1,o2,max_contacts,gContactTemp,sizeof(dContactGeom));
  vector<dContactGeom> vcontact(num);
  int numOk = 0;
  for(int i=0;i<num;i++) {
    if(gContactTemp[i].g1 == o2 && gContactTemp[i].g2 == o1) {
      printf("Swapping contact\n");
      std::swap(gContactTemp[i].g1,gContactTemp[i].g2);
      for(int k=0;k<3;k++) gContactTemp[i].normal[k]*=-1.0;
      std::swap(gContactTemp[i].side1,gContactTemp[i].side2);
    }
    Assert(gContactTemp[i].g1 == o1);
    Assert(gContactTemp[i].g2 == o2);
    vcontact[numOk] = gContactTemp[i];
    const dReal* n=vcontact[numOk].normal;
    if(Sqr(n[0])+Sqr(n[1])+Sqr(n[2]) < 0.9 || Sqr(n[0])+Sqr(n[1])+Sqr(n[2]) > 1.2) {
      printf("Warning, degenerate contact with normal %f %f %f\n",vcontact[numOk].normal[0],vcontact[numOk].normal[1],vcontact[numOk].normal[2]);
      //continue;
    }
    numOk++;
  }
  if(numOk > 0) printf("%d self collision contacts between links %d and %d\n",numOk,(int)link1,(int)link2);
  vcontact.resize(numOk);
  
  if(kMergeContacts && numOk > 0) {
    MergeContacts(vcontact,kContactPosMergeTolerance,kContactOriMergeTolerance);
  }

  if(vcontact.size() > 0) {
    if(numOk != (int)vcontact.size())
    	//// The int type is not guaranteed to be big enough, use intptr_t
		//cout<<numOk<<" contacts between env "<<(int)dGeomGetData(o2)<<" and body "<<(int)dGeomGetData(o1)<<"  (clustered to "<<vcontact.size()<<")"<<endl;
		cout<<numOk<<" contacts between link "<<(intptr_t)dGeomGetData(o2)<<" and link "<<(intptr_t)dGeomGetData(o1)<<"  (clustered to "<<vcontact.size()<<")"<<endl;
    gContacts.push_back(ODEContactResult());
    gContacts.back().o1 = o1;
    gContacts.back().o2 = o2;
    swap(gContacts.back().contacts,vcontact);
  }
}
Esempio n. 10
0
void TurbulentDispersionScene::Collide(dGeomID g1, dGeomID g2)
{
    dBodyID b1 = dGeomGetBody(g1);
    dBodyID b2 = dGeomGetBody(g2);
    
    dContact contact[MAX_CONTACTS];
    int n = dCollide(g1, g2, MAX_CONTACTS, &contact[0].geom, sizeof(dContact));
     
    if(n>0)
    {
        //Particle g1 collides with ground g2
        if ((dGeomGetClass(g1) == dSphereClass)&&(g2==ground_wall))
        {                                                    
            unsigned int index=(size_t) dGeomGetData(g1);
            //bodies_prts_indexes_to_remove.push_back(FindPrtsIndexByGlobalId(index)); 
            Add_prts_body_index_to_remove(FindPrtsIndexByGlobalId(index));
            
            return;
        }

        //Particle g2 collides with ground g1
        if((dGeomGetClass(g2) == dSphereClass)&&(g1==ground_wall))
        {            
            unsigned int index=(size_t) dGeomGetData(g2);
            //bodies_prts_indexes_to_remove.push_back(FindPrtsIndexByGlobalId(index));                        
            Add_prts_body_index_to_remove(FindPrtsIndexByGlobalId(index));
            
            return;
        }
    }
    
    for (int i=0; i<n; ++i)
    {
        // contact[i].surface.mode = dContactBounce | dContactSoftCFM;
        contact[i].surface.mode = dContactBounce;        
        //contact[i].surface.mu = dInfinity;
        contact[i].surface.mu = 0.5;
        //contact[i].surface.mu2 = 0.5;
        contact[i].surface.bounce = 0.000999990;
        //contact[i].surface.bounce_vel = 0.1;
        //contact[i].surface.soft_cfm = 0.001;

        //contact[i].surface.mode = dContactBounce|dContactSoftERP|dContactSoftCFM;
        contact[i].surface.soft_erp = 1.0; //1.0;
        contact[i].surface.soft_cfm = 1e-10;
        dJointID j = dJointCreateContact (domain->getWorld(), domain->getContactGroup(), contact+i);
        dJointAttach(j, b1, b2);
    }
}
void ApproxDistanceSensor::DistanceSensor::updateValue()
{
  pose = physicalObject->pose;
  pose.conc(offset);
  invertedPose = pose.invert();
  Vector3<> boxPos = pose * Vector3<>(max * 0.5f, 0.f, 0.f);
  dGeomSetPosition(geom, boxPos.x, boxPos.y, boxPos.z);
  dMatrix3 matrix3;
  ODETools::convertMatrix(pose.rotation, matrix3);
  dGeomSetRotation(geom, matrix3);
  closestGeom = 0;
  closestSqrDistance = maxSqrDist;
  dSpaceCollide2(geom, (dGeomID)Simulation::simulation->movableSpace, this, (dNearCallback*)&staticCollisionWithSpaceCallback);
  dSpaceCollide2(geom, (dGeomID)Simulation::simulation->staticSpace, this, (dNearCallback*)&staticCollisionCallback);
  if(closestGeom)
  {
    const dReal* pos = dGeomGetPosition(closestGeom);
    Geometry* geometry = (Geometry*)dGeomGetData(closestGeom);
    data.floatValue = (Vector3<>((float) pos[0], (float) pos[1], (float) pos[2]) - pose.translation).abs() - geometry->innerRadius;
    if(data.floatValue < min)
      data.floatValue = min;
  }
  else
    data.floatValue = max;
}
Esempio n. 12
0
File: M3.cpp Progetto: jbongard/ISCS
void Set_Touch_Sensor(dGeomID o) {

	OBJECT* obj = (OBJECT *)dGeomGetData(o);

	if ( obj )

		obj->Sensor_Touch_Set();
}
Esempio n. 13
0
void ComponentBrainKamikaze::handleMessagePhysicsCollision(Message &message)
{
	dGeomID o2 = message.getField<dGeomID>("o2");
	Actor *a2 = reinterpret_cast<Actor*>(dGeomGetData(o2));

	if(a2)
	{
		dGeomID o1 = message.getField<dGeomID>("o1");
		Actor *a1 = reinterpret_cast<Actor*>(dGeomGetData(o1));

		OBJECT_ID uid = getActorPtr()->getUID();

		if(a1 && a1->getUID() == uid)
		{
			wanderTimer = 0.0f;
		}
	}
}
Esempio n. 14
0
File: geom.c Progetto: ADTSH/io
IoObject *IoODEGeom_geomFromId(void *state, dGeomID id)
{
	if (id == 0)
	{
		return ((IoState*)state)->ioNil;
	}
	else
	{
		return (IoObject*)dGeomGetData(id);
	}
}
Esempio n. 15
0
void PhysicsSim::ode_nearCallback (void *data, dGeomID o1, dGeomID o2)
{
    PhysicsSim *me = static_cast<PhysicsSim*>(data);

    int i;

    // exit without doing anything if the two bodies are connected by a joint
    dBodyID b1 = dGeomGetBody(o1);
    dBodyID b2 = dGeomGetBody(o2);
    if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return;

    dContact contact[MAX_CONTACTS];   // up to MAX_CONTACTS contacts per box-box
    for (i=0; i<MAX_CONTACTS; i++) {
        contact[i].surface.mode = dContactBounce | dContactSoftCFM;
        contact[i].surface.mu = dInfinity;
        contact[i].surface.mu2 = 0;
        contact[i].surface.bounce = 0.1;
        contact[i].surface.bounce_vel = 0.1;
        contact[i].surface.soft_cfm = 0.01;
    }

	if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,sizeof(dContact)))
	{
        OscObject *p1 = static_cast<OscObject*>(dGeomGetData(o1));
        OscObject *p2 = static_cast<OscObject*>(dGeomGetData(o2));
        if (p1 && p2) {
            bool co1 = p1->collidedWith(p2, me->m_counter);
            bool co2 = p2->collidedWith(p1, me->m_counter);
            if ( (co1 || co2) && me->m_collide.m_value ) {
                lo_send(address_send, "/world/collide", "ssf",
                        p1->c_name(), p2->c_name(),
                        (double)(p1->m_velocity - p2->m_velocity).length());
            }
            // TODO: this strategy will NOT work for multiple collisions between same objects!!
        }
		for (i=0; i<numc; i++) {
			dJointID c = dJointCreateContact (me->m_odeWorld, me->m_odeContactGroup, contact+i);
			dJointAttach (c,b1,b2);
		}
	}
}
Esempio n. 16
0
void PWorld::handleCollisions(dGeomID o1, dGeomID o2)
{   
    PSurface* sur;
    int j=sur_matrix[*((int*)(dGeomGetData(o1)))][*((int*)(dGeomGetData(o2)))];
    if (j!=-1)
    {
        const int N = 10;
        dContact contact[N];
        int n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
        if (n > 0) {
          sur = surfaces[j];
          sur->contactPos   [0] = contact[0].geom.pos[0];
          sur->contactPos   [1] = contact[0].geom.pos[1];
          sur->contactPos   [2] = contact[0].geom.pos[2];
          sur->contactNormal[0] = contact[0].geom.normal[0];
          sur->contactNormal[1] = contact[0].geom.normal[1];
          sur->contactNormal[2] = contact[0].geom.normal[2];
          bool flag=true;
          if (sur->callback!=NULL) flag = sur->callback(o1,o2,sur);
          if (flag)
          for (int i=0; i<n; i++) {
              contact[i].surface = sur->surface;
              if (sur->usefdir1)
              {
                  contact[i].fdir1[0] = sur->fdir1[0];
                  contact[i].fdir1[1] = sur->fdir1[1];
                  contact[i].fdir1[2] = sur->fdir1[2];
                  contact[i].fdir1[3] = sur->fdir1[3];
              }
              dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);

              dJointAttach (c,
                            dGeomGetBody(contact[i].geom.g1),
                            dGeomGetBody(contact[i].geom.g2));
            }
        }
    }

}
Esempio n. 17
0
void Update(dGeomID geom)
{
	union {
	 void *data;
	 Geom *obj;
	};
	data = dGeomGetData(geom);
	if (obj) obj->Update();

	if (dGeomIsSpace(geom))
	{
	 Update(dSpaceID(geom));
	}
}
Esempio n. 18
0
void setCurrentTransform(dGeomID geom)
{
    const dTriMeshDataID TriMeshData = static_cast<dTriMeshDataID>(dGeomGetData(geom));
    const dReal* Pos = dGeomGetPosition(geom);
    const dReal* Rot = dGeomGetRotation(geom);

    const double Transform[16] = 
    {
        Rot[0], Rot[4], Rot[8],  0,
            Rot[1], Rot[5], Rot[9],  0,
            Rot[2], Rot[6], Rot[10], 0,
            Pos[0], Pos[1], Pos[2],  1
    };
    dGeomTriMeshDataSet(TriMeshData, TRIMESH_LAST_TRANSFORMATION, (void *)Transform);
}
Esempio n. 19
0
int dcTriListCollider::dSortedTriSphere(const dReal*	/**v1/**/,const dReal*	/**v2/**/,
					 const dReal* triAx,
					 CDB::TRI* T,
					 dReal dist,
					 dxGeom* Sphere,
					 dxGeom* Geometry, 
					 int Flags, 
					 dContactGeom* Contacts,
					 int			skip
					 ){


						 //const dReal* v1=(dReal*)T->verts[1];
						 //const dReal* v2=(dReal*)T->verts[2];
						 const dReal* SphereCenter=dGeomGetPosition(Sphere);
						 const float SphereRadius = dGeomSphereGetRadius(Sphere);



						 //	dNormalize3(triAx);
						 const dReal *ContactNormal=triAx;//{triAx[0],triAx[1],triAx[2]};
						 dVector3 ContactPos={SphereCenter[0]-triAx[0]* SphereRadius,SphereCenter[1]-triAx[1]* SphereRadius,SphereCenter[2]-triAx[2]* SphereRadius};

						 float ContactDepth= -dist + SphereRadius;
						 if (ContactDepth >= 0){

							 Contacts->normal[0] =-ContactNormal[0];
							 Contacts->normal[1] =-ContactNormal[1];
							 Contacts->normal[2] =-ContactNormal[2];
							 Contacts->depth = ContactDepth;
							 ////////////////////

							 Contacts->pos[0]=ContactPos[0];
							 Contacts->pos[1]=ContactPos[1];
							 Contacts->pos[2]=ContactPos[2];
							 Contacts->g1 = Geometry;
							 Contacts->g2 = Sphere;
							 ((dxGeomUserData*)dGeomGetData(Sphere))->tri_material=T->material;
							 if(dGeomGetUserData(Sphere)->callback)dGeomGetUserData(Sphere)->callback(T,Contacts);
							 SURFACE(Contacts,0)->mode=T->material;
							 //////////////////////////////////
							 return 1;

						 }

						 return 0;
					 }
Esempio n. 20
0
dGeomID set_phys_geom_type(dGeomID geom, dBodyID body,
                           int i, int t, const float *v)
{
    /* Destroy the old geom and its data. */

    if (geom)
    {
        free(dGeomGetData(geom));
        dGeomDestroy(geom);
        geom = 0;
    }

    /* Create a new geom of the required type. */

    switch (t)
    {
    case dSphereClass:
        geom = dCreateSphere(space, v[0]);
        break;
    case dCapsuleClass:
        geom = dCreateCapsule(space, v[0], v[1]);
        break;
    case dBoxClass:
        geom = dCreateBox(space, v[0], v[1], v[2]);
        break;
    case dPlaneClass:
        geom = dCreatePlane(space, v[0], v[1], v[2], v[3]);
        break;
    case dRayClass:
        geom = dCreateRay(space, (dReal) sqrt(v[3] * v[3] +
                                              v[4] * v[4] +
                                              v[5] * v[5]));
        dGeomRaySet(geom, v[0], v[1], v[2], v[3], v[4], v[5]);
        break;
    }

    /* Assign geom data and attach it to the body. */

    if (geom)
    {
        dGeomSetData(geom, create_data(i));
        dGeomSetBody(geom, body);
    }

    return geom;
}
void ApproxDistanceSensor::DistanceSensor::staticCollisionCallback(ApproxDistanceSensor::DistanceSensor* sensor, dGeomID geom1, dGeomID geom2)
{
  ASSERT(geom1 == sensor->geom);
  ASSERT(!dGeomIsSpace(geom2));

  Geometry* geometry = (Geometry*)dGeomGetData(geom2);
  if((::PhysicalObject*)geometry->parentBody == sensor->physicalObject)
    return; // avoid detecting the body on which the sensor is monted

  const dReal* pos = dGeomGetPosition(geom2);
  const Vector3<> geomPos((float) pos[0], (float) pos[1], (float) pos[2]);
  const float approxSqrDist = (geomPos - sensor->pose.translation).squareAbs() - geometry->innerRadiusSqr;
  if(approxSqrDist >= sensor->closestSqrDistance)
    return; // we already found another geometrie that was closer

  Vector3<> relPos = sensor->invertedPose * geomPos;
  if(relPos.x <= 0.f)
    return; // center of the geometry should be in front of the distance sensor

  float halfMaxY = sensor->tanHalfAngleX * relPos.x;
  float halfMaxZ = sensor->tanHalfAngleY * relPos.x;
  if(std::max(std::abs(relPos.y) - geometry->outerRadius, 0.f) >= halfMaxY || std::max(std::abs(relPos.z) - geometry->outerRadius, 0.f) >= halfMaxZ)
    return; // the sphere that covers the geometrie does not collide with the pyramid of the distance sensor

  if(std::max(std::abs(relPos.y) - geometry->innerRadius, 0.f) < halfMaxY && std::max(std::abs(relPos.z) - geometry->innerRadius, 0.f) < halfMaxZ)
    goto hit; // the sphere enclosed by the geometrie collides with the pyramid of the distance sensor

  // geom2 might collide with the pyramid of the distance sensor. let us perform a hit scan along one of the pyramid's sides to find out..
  {
    Vector3<> scanDir = sensor->pose.rotation * Vector3<>(relPos.x, std::max(std::min(relPos.y, halfMaxY), -halfMaxY), std::max(std::min(relPos.z, halfMaxZ), -halfMaxZ));
    const Vector3<>& sensorPos = sensor->pose.translation;
    dGeomRaySet(sensor->scanRayGeom, sensorPos.x, sensorPos.y, sensorPos.z, scanDir.x, scanDir.y, scanDir.z);
    dContactGeom contactGeom;
    if(dCollide(sensor->scanRayGeom, geom2, CONTACTS_UNIMPORTANT | 1, &contactGeom, sizeof(dContactGeom)) <= 0)
      return;
  }

hit:
  sensor->closestSqrDistance = approxSqrDist;
  sensor->closestGeom = geom2;
}
Esempio n. 22
0
void Simulator::CollisionChecking(dGeomID geom1, dGeomID geom2)
{	
    const bool isRobot1    = dGeomGetData(geom1) == NULL || dGeomGetData(geom1) == ((void *) &TYPE_ROBOT);
    const bool isObstacle1 = dGeomGetData(geom1) == ((void *) &TYPE_OBSTACLE);
    const bool isTerrain1  = dGeomGetData(geom1) == ((void *) &TYPE_TERRAIN);

    const bool isRobot2    = dGeomGetData(geom2) == NULL || dGeomGetData(geom2) == ((void *) &TYPE_ROBOT);
    const bool isObstacle2 = dGeomGetData(geom2) == ((void *) &TYPE_OBSTACLE);
    const bool isTerrain2  = dGeomGetData(geom2) == ((void *) &TYPE_TERRAIN);
    
    if((isObstacle1 && isObstacle2) || (isTerrain1 && isTerrain2))
	return;
    
    if(dGeomIsSpace(geom1) || dGeomIsSpace(geom2)) 
    { 		
	dSpaceCollide2(geom1, geom2, this, &CollisionCheckingCallbackFn); 
	return;
    } 
    
    const int NR_CONTACTS = 3;
    dContact contact[NR_CONTACTS]; 
    if(int numc = dCollide(geom1, geom2, NR_CONTACTS, &contact[0].geom, sizeof(dContact)))
    {
	if((isRobot1 && isObstacle2) || (isRobot2 && isObstacle1))
	    m_collision = true;

	for(int i = 0; i < numc; ++i) 
	{
	    contact[i].surface.mode     = dContactSoftCFM | dContactApprox1;
	    contact[i].surface.mu       = 0.6;
	    contact[i].surface.soft_cfm = 0.2;
	    
	    dJointAttach(dJointCreateContact(m_world, m_contacts, &contact[i]),
			 dGeomGetBody(contact[i].geom.g1),
			 dGeomGetBody(contact[i].geom.g2));
	}		
    }
}
Esempio n. 23
0
static struct geom_data *get_data(dGeomID geom)
{
    return (struct geom_data *) dGeomGetData(geom);
}
Esempio n. 24
0
		void internal_raycastCollisionCallback(void* data, dGeomID o0,
		                                        dGeomID o1)
		{
			if (dGeomIsSpace(o0) || dGeomIsSpace(o1))
			{
				// Colliding a space with either a geom or another space.
				dSpaceCollide2(o0, o1, data,
					&internal_raycastCollisionCallback);
			}
			else
			{
				// Colliding two geoms.

				// Sometimes we get a case where the ray geom is passed in
				// as both objects, which is stupid.
				if (o0 == o1)
				{
					return ;
				}

				// Get a pointer to the ODESimulator.
				ODESimulator* sim = (ODESimulator*) data;

				// Get pointers to the two geoms' GeomData structure.  One
				// of these (the one NOT belonging to the ray geom)
				// will always be non-NULL.
				GeomData* geomData0 = ((GeomData*) dGeomGetData(o0));
				GeomData* geomData1 = ((GeomData*) dGeomGetData(o1));

				// Find the contact group of the collided Solid.
				unsigned int geomContactGroup = defaults::shape::contactGroup;
				if (geomData0)
				{
					geomContactGroup = geomData0->shape->contactGroup;
				}
				else
				{
					geomContactGroup = geomData1->shape->contactGroup;
				}

				// Check if the two Solids' contact groups generate contacts
				// when they collide.
				bool makeContacts = sim->groupsMakeContacts(
					geomContactGroup, sim->internal_getRayContactGroup());
				if (!makeContacts)
				{
					return ;
				}

				// Now actually test for collision between the two geoms.
				// This is a fairly expensive operation.
				dContactGeom contactArray[defaults::ode::maxRaycastContacts];
				int numContacts = dCollide(o0, o1, 
					defaults::ode::maxRaycastContacts, contactArray,
					sizeof(dContactGeom));

				if (0 == numContacts)
				{
					return ;
				}
				else
				{
					// These two geoms must be intersecting.  We will store 
					// only the closest RaycastResult.
					int closest = 0;
					for (int i = 0; i < numContacts; ++i)
					{
						if (contactArray[i].depth < contactArray[closest].depth)
						{
							closest = i;
						}
					}

					// Only one of the geoms will be part of a Solid we 
					// want to store; the other is the ray.
					Solid* solid = NULL;
					if (geomData0)
					{
						solid = geomData0->solid;
					}
					else
					{
						solid = geomData1->solid;
					}

					Point3r intersection((real) contactArray[closest].pos[0],
						(real) contactArray[closest].pos[1],
						(real) contactArray[closest].pos[2]);
					Vec3r normal((real) contactArray[closest].normal[0],
						(real) contactArray[closest].normal[1],
						(real) contactArray[closest].normal[2]);

					sim->internal_addRaycastResult(solid, intersection, 
						normal, (real) contactArray[closest].depth);
				}
			}
		}
Esempio n. 25
0
int dcTriListCollider::dTriSphere(const dReal* v0,const dReal* v1,const dReal* v2,
	 Triangle* T,
	 dxGeom* Sphere,dxGeom* Geometry, int Flags, 
	 dContactGeom* Contacts,int /**skip/**/)
 {
 
 
	 const dVector3 &triSideAx0	=T->side0	;
	 const dVector3 &triSideAx1	=T->side1	;
	 const dVector3 &triAx		=T->norm	;

	 //if(!TriPlaneContainPoint(triAx,v0,SphereCenter)) return 0;


	 const dReal radius=dGeomSphereGetRadius(Sphere);
	 float Depth=-T->dist+radius;
	 if(Depth<0.f)	return 0;
	 const dReal* pos=dGeomGetPosition(Sphere);
	 dVector3 ContactNormal;
	 if(TriContainPoint(v0,v1,v2,triAx,triSideAx0,triSideAx1,pos))
	 {
		 ContactNormal[0]=triAx[0];ContactNormal[1]=triAx[1];ContactNormal[2]=triAx[2];
		 //dVector3 ContactPos={pos[0]-triAx[0]* radius,pos[1]-triAx[1]* radius,pos[2]-triAx[2]* radius};
	 }
	 else
	 {
		CDB::TRI*       T_array      = Level().ObjectSpace.GetStaticTris();
		flags8& gl_state=gl_cl_tries_state[I-B];
		if(gl_state.test(fl_engaged_s0)||gl_state.test(fl_engaged_s1)||gl_state.test(fl_engaged_s2))	
			return 0;
		if(FragmentonSphereTest(pos,radius,v0,v1,ContactNormal,Depth))
		{
			SideToGlClTriState(T->T->verts[0],T->T->verts[1],T_array);
		}
		else if(FragmentonSphereTest(pos,radius,v1,v2,ContactNormal,Depth))
		{
			SideToGlClTriState(T->T->verts[1],T->T->verts[2],T_array );
		}
		else if(FragmentonSphereTest(pos,radius,v2,v0,ContactNormal,Depth))
		{
			SideToGlClTriState(T->T->verts[2],T->T->verts[0],T_array );
		}
		else{
			if(gl_state.test(fl_engaged_v0)||gl_state.test(fl_engaged_v1)||gl_state.test(fl_engaged_v2))	
																									return 0;
			if(PointSphereTest(pos,radius,v0,ContactNormal,Depth))
			{
				VxToGlClTriState(T->T->verts[0],T_array );
			}
			else if(PointSphereTest(pos,radius,v1,ContactNormal,Depth))
			{
				VxToGlClTriState(T->T->verts[1],T_array );
			}
			else if(PointSphereTest(pos,radius,v2,ContactNormal,Depth))
			{
				VxToGlClTriState(T->T->verts[2],T_array );
			}
			else return 0;
		 }
	 }

	 Contacts->normal[0] =-ContactNormal[0];
	 Contacts->normal[1] =-ContactNormal[1];
	 Contacts->normal[2] =-ContactNormal[2];
	 Contacts->depth = Depth;
	 ////////////////////

	 Contacts->pos[0]=pos[0]-ContactNormal[0]*radius;
	 Contacts->pos[1]=pos[1]-ContactNormal[1]*radius;
	 Contacts->pos[2]=pos[2]-ContactNormal[2]*radius;
	 Contacts->g1 = Geometry;
	 Contacts->g2 = Sphere;
	 ((dxGeomUserData*)dGeomGetData(Sphere))->tri_material=T->T->material;
	 if(dGeomGetUserData(Sphere)->callback)dGeomGetUserData(Sphere)->callback(T->T,Contacts);
	 SURFACE(Contacts,0)->mode=T->T->material;
	 //////////////////////////////////
	 //	++OutTriCount;
	 return 1;
 }
Esempio n. 26
0
void PhysicsServer::ProcessCollision( void *data, dGeomID o1, dGeomID o2 )
{
    //  skip connected bodies
    dBodyID bodyID1 = dGeomGetBody( o1 );
    dBodyID bodyID2 = dGeomGetBody( o2 );
    if (bodyID1 && bodyID2 && dAreConnected( bodyID1, bodyID2 )) return;
    if (!bodyID1 && !bodyID2) return;

    //  do collision
    int nContacts = dCollide( o1, o2, c_MaxContacts, &m_Contacts[0].geom, sizeof( dContact ) );
    if (nContacts == 0) return;

    float scale = GetWorldScale();

    nContacts = tmin( nContacts, c_MaxContacts - m_NContacts );
    for (int i = 0; i < nContacts; i++) 
    {
        PhysMaterial* pSurf1 = GetGeomSurface( o1 );
        PhysMaterial* pSurf2 = GetGeomSurface( o2 );
        dContact& contact = m_Contacts[i];
        dSurfaceParameters& surface = contact.surface;
        
        //  TODO: proper flags setup
        m_Contacts[i].surface.mode = 
            //dContactApprox1 | 
            //dContactFDir1   | 
            dContactSoftERP | 
            dContactSoftCFM |
            //dContactSlip1   | 
            //dContactSlip2   | 
            dContactBounce;

        if (!pSurf1 && !pSurf2)
        {
            surface.mu          = 8.0f;
            surface.mu2         = 8.0f;
            surface.bounce      = 1.0f; 
            surface.bounce_vel  = 0.0f;
            surface.soft_erp    = 0.1f; 
            surface.soft_cfm    = 1e-3f;
            surface.motion1     = 0.0f; 
            surface.motion2     = 0.0f; 
            surface.slip1       = 0.1f;
            surface.slip2       = 0.1f;
        }
        else if (pSurf2 == pSurf1)
        {
            surface.mu          = pSurf1->m_Mu; 
            surface.mu2         = pSurf1->m_Mu2;
            surface.bounce      = pSurf1->m_Bounce;
            surface.bounce_vel  = pSurf1->m_BounceVel;
            surface.soft_erp    = pSurf1->m_SoftERP; 
            surface.soft_cfm    = pSurf1->m_SoftCFM;
            surface.motion1     = pSurf1->m_Motion1;
            surface.motion2     = pSurf1->m_Motion2; 
            surface.slip1       = pSurf1->m_Slip1;
            surface.slip2       = pSurf1->m_Slip2;
        }
        else
        {
            if (!pSurf1) pSurf1 = pSurf2;
            if (!pSurf2) pSurf2 = pSurf1;

            surface.mu          = sqrtf( pSurf1->m_Mu * pSurf2->m_Mu );
            surface.mu2         = sqrtf( pSurf1->m_Mu2 * pSurf2->m_Mu2 );
            surface.bounce      = 0.5f*( pSurf1->m_Bounce + pSurf2->m_Bounce );
            surface.bounce_vel  = tmin( pSurf1->m_BounceVel, pSurf2->m_BounceVel );
            surface.soft_erp    = sqrtf( pSurf1->m_SoftERP * pSurf2->m_SoftERP ); 
            surface.soft_cfm    = 0.5f*( pSurf1->m_SoftCFM + pSurf2->m_SoftCFM );
            surface.motion1     = sqrtf( pSurf1->m_Motion1 * pSurf2->m_Motion1 );
            surface.motion2     = sqrtf( pSurf1->m_Motion2 * pSurf2->m_Motion2 ); 
            surface.slip1       = sqrtf( pSurf1->m_Slip1 * pSurf2->m_Slip1 );
            surface.slip2       = sqrtf( pSurf1->m_Slip2 * pSurf2->m_Slip2 );
        }

        PhysObject* pObj1 = (PhysObject*)dGeomGetData( o1 );
        PhysObject* pObj2 = (PhysObject*)dGeomGetData( o2 );
        int obj1 = pObj1 ? pObj1->GetID() : -1;
        int obj2 = pObj2 ? pObj2->GetID() : -1;

        dContactGeom& geom = contact.geom;
        m_NContacts++;

        if (IsDrawBounds())
        {
            Vec3 pos = Vec3( geom.pos[0], geom.pos[1], geom.pos[2] ); 
            pos /= scale;
            Vec3 norm = Vec3( geom.normal[0], geom.normal[1], geom.normal[2] ); 
            const float c_HandleSize = 0.3f;
            g_pDrawServer->SetWorldTM( Mat4::identity );
            g_pDrawServer->DrawBox( AABox( pos, c_HandleSize*0.5f ), 0x5500FF00, 0x22FFFF00 );
            g_pDrawServer->DrawLine( pos, pos + norm*c_HandleSize, 0x5500FF00, 0x5500FF00 );
        }
        
        dJointID jID = dJointCreateContact( m_WorldID, m_ContactGroupID, &contact );
        dJointAttach( jID, bodyID1, bodyID2 ); 
    }
} // PhysicsServer::ProcessCollision
    /**
     * \brief This function handles the calculation of a step in the world.
     *
     * pre:
     *     - world_init = true
     *     - step_size > 0
     *
     * post:
     *     - handled the collisions
     *     - step the world for step_size seconds
     *     - the contactgroup should be empty
     */
    void WorldPhysics::stepTheWorld(void) {
      MutexLocker locker(&iMutex);
      std::vector<dJointFeedback*>::iterator iter;
      geom_data* data;
      int i;
      // if world_init = false or step_size <= 0 debug something
       if(world_init && step_size > 0) {
        if(old_gravity != world_gravity) {
          old_gravity = world_gravity;
          dWorldSetGravity(world, world_gravity.x(),
                           world_gravity.y(), world_gravity.z());
        }

        if(old_cfm != world_cfm) {
          old_cfm = world_cfm;
          dWorldSetCFM(world, (dReal)world_cfm);
        }

        if(old_erp != world_erp) {
          old_erp = world_erp;
          dWorldSetERP(world, (dReal)world_erp);
        }
	//	printf("now WorldPhysics.cpp..stepTheWorld(void)....1 : dSpaceGetNumGeoms: %d\n",dSpaceGetNumGeoms(space)); 
        /// first clear the collision counters of all geoms
        for(i=0; i<dSpaceGetNumGeoms(space); i++) {
          data = (geom_data*)dGeomGetData(dSpaceGetGeom(space, i));
          data->num_ground_collisions = 0;
          data->contact_ids.clear();
          data->contact_points.clear();
          data->ground_feedbacks.clear();
        
        }
        

        for(iter = contact_feedback_list.begin();
            iter != contact_feedback_list.end(); iter++) {
          free((*iter));
        }
 
        contact_feedback_list.clear();
        draw_intern.clear();
        /// then we have to clear the contacts
        dJointGroupEmpty(contactgroup);
        /// first check for collisions
        num_contacts = log_contacts = 0;
        create_contacts = 1;
        
        dSpaceCollide(space,this, &WorldPhysics::callbackForward);
        drawLock.lock();
        draw_extern.swap(draw_intern);
        drawLock.unlock();
        // then calculate the next state for a time of step_size seconds
        try {
          if(fast_step) dWorldQuickStep(world, step_size);
          else dWorldStep(world, step_size);

        } catch (...) {
          control->sim->handleError(PHYSICS_UNKNOWN);
        }
	if(WorldPhysics::error) {
          control->sim->handleError(WorldPhysics::error);
          WorldPhysics::error = PHYSICS_NO_ERROR;
	}
      }   
    }
    /**
     * \brief In this function the collision handling from ode is performed.
     *
     * pre:
     *     - world_init = true
     *     - o1 and o2 are regular geoms
     *
     * post:
     *     - if o1 or o2 was a Space, called SpaceCollide and exit
     *     - otherwise tested if the geoms collide and created a contact
     *       joint if so.
     *
     * A lot of the code is uncommented in this function. This
     * code maybe used later to handle sensors or other special cases
     * in the simulation.
     */
    void WorldPhysics::nearCallback (dGeomID o1, dGeomID o2) {
      int i;
      int numc;
      //up to MAX_CONTACTS contact per Box-box
      //dContact contact[MAX_CONTACTS];
      dVector3 v1, v;
      //dMatrix3 R;
      dReal dot;
  
      if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) {
        /// test if a space is colliding with something
        dSpaceCollide2(o1,o2,this,& WorldPhysics::callbackForward);
        return;
      }
      /// exit without doing anything if the two bodies are connected by a joint 
      dBodyID b1=dGeomGetBody(o1);
      dBodyID b2=dGeomGetBody(o2);

      geom_data* geom_data1 = (geom_data*)dGeomGetData(o1);
      geom_data* geom_data2 = (geom_data*)dGeomGetData(o2);


  
            // test if we have a ray sensor:
      if(geom_data1->ray_sensor) {
        dContact contact;
        if(geom_data1->parent_geom == o2) {
          return;
        }
        
        if(geom_data1->parent_body == dGeomGetBody(o2)) {
          return;
        }
        
        numc = dCollide(o2, o1, 1|CONTACTS_UNIMPORTANT, &(contact.geom), sizeof(dContact));
        if(numc) {
          if(contact.geom.depth < geom_data1->value)
            geom_data1->value = contact.geom.depth;
          ray_collision = 1;
        }
        return;
      }
      else if(geom_data2->ray_sensor) {
        dContact contact;
        if(geom_data2->parent_geom == o1) {
          return;
        }
        if(geom_data2->parent_body == dGeomGetBody(o1)) {
          return;
        }
        numc = dCollide(o2, o1, 1|CONTACTS_UNIMPORTANT, &(contact.geom), sizeof(dContact));
        if(numc) {
          if(contact.geom.depth < geom_data2->value)
            geom_data2->value = contact.geom.depth;
          ray_collision = 1;
        }
        return;
      }
      
      if(b1 && b2 && dAreConnectedExcluding(b1,b2,dJointTypeContact))
        return;

      if(!b1 && !b2 && !geom_data1->ray_sensor && !geom_data2->ray_sensor) return;

      int maxNumContacts = 0;
      if(geom_data1->c_params.max_num_contacts <
         geom_data2->c_params.max_num_contacts) {
        maxNumContacts = geom_data1->c_params.max_num_contacts;
      }
      else {
        maxNumContacts = geom_data2->c_params.max_num_contacts;
      }
      dContact *contact = new dContact[maxNumContacts];


      //for granular test
      //if( (plane != o2) && (plane !=o1)) return ;
  
  
      /*
     /// we use the geomData to handle some special cases
     void* geom_data1 = dGeomGetData(o1);
     void* geom_data2 = dGeomGetData(o2);

     /// one case is, that we don't wont to handle a collision between some special
     /// geoms beweet each other and the ground
     if((geom_data1 && ((robot_geom*)geom_data1)->type & 16)) {
     if(plane == o2) return;
     if((geom_data2 && ((robot_geom*)geom_data2)->type & 16)) return;
     }
     else if((geom_data2 && ((robot_geom*)geom_data2)->type & 16) && (plane == o1)) return;
  
     /// an other case is a ray geom that we use simulate ray sensors
     /// this geom has to be handled in a different way
     if((geom_data1 && ((robot_geom*)geom_data1)->type & 8) ||
     (geom_data2 && ((robot_geom*)geom_data2)->type & 8)) {    
     int n;
     const int N = MAX_CONTACTS;
     dContactGeom contact[N];

     n = dCollide (o2,o1,N,contact,sizeof(dContactGeom));
     if (n > 0) {
     //const dReal ss[3] = {1,0.01,0.01};
     for (i=0; i<n; i++) {
     contact[i].pos[2] += Z_OFFSET;
     if(contact[i].depth > 0.01){
     if(geom_data1 && ((robot_geom*)geom_data1)->type & 8)
     ((robot_geom*)geom_data1)->i_length = contact[0].depth;
     if(geom_data2 && ((robot_geom*)geom_data2)->type & 8)
     ((robot_geom*)geom_data2)->i_length = contact[0].depth;
     }
     }
     }
     return;
     }
      */
  

  
      // frist we set the softness values:
      contact[0].surface.mode = dContactSoftERP | dContactSoftCFM;
      contact[0].surface.soft_cfm = (geom_data1->c_params.cfm +
                                     geom_data2->c_params.cfm)/2;
      contact[0].surface.soft_erp = (geom_data1->c_params.erp +
                                     geom_data2->c_params.erp)/2;
      // then check if one of the geoms want to use the pyramid approximation
      if(geom_data1->c_params.approx_pyramid ||
         geom_data2->c_params.approx_pyramid)
        contact[0].surface.mode |= dContactApprox1;
  
      // Then check the friction for both directions
      contact[0].surface.mu = (geom_data1->c_params.friction1 +
                               geom_data2->c_params.friction1)/2;
      contact[0].surface.mu2 = (geom_data1->c_params.friction2 +
                                geom_data2->c_params.friction2)/2;

      if(contact[0].surface.mu != contact[0].surface.mu2)
        contact[0].surface.mode |= dContactMu2;

      // check if we have to calculate friction direction1
      if(geom_data1->c_params.friction_direction1 ||
         geom_data2->c_params.friction_direction1) {
        // here the calculation becomes more complicated
        // maybe we should make some restrictions
        // so -> we only use friction motion in friction direction 1
        // the friction motion is only set if a local vector for friction
        // direction 1 is given
        // the steps for the calculation:
        // 1. rotate the local vectors to global coordinates
        // 2. scale the vectors to the length of the motion if given
        // 3. vector 3 =  vector 1 - vector 2
        // 4. get the length of vector 3
        // 5. set vector 3 as friction direction 1
        // 6. set motion 1 to the length
        contact[0].surface.mode |= dContactFDir1;
        if(!geom_data2->c_params.friction_direction1) {
          // get the orientation of the geom
          //dGeomGetQuaternion(o1, v);
          //dRfromQ(R, v);
          // copy the friction direction
          v1[0] = geom_data1->c_params.friction_direction1->x();
          v1[1] = geom_data1->c_params.friction_direction1->y();
          v1[2] = geom_data1->c_params.friction_direction1->z();
          // translate the friction direction to global coordinates
          // and set friction direction for contact
          //dMULTIPLY0_331(contact[0].fdir1, R, v1);
          contact[0].fdir1[0] = v1[0];
          contact[0].fdir1[1] = v1[1];
          contact[0].fdir1[2] = v1[2];
          if(geom_data1->c_params.motion1) {
            contact[0].surface.mode |= dContactMotion1;
            contact[0].surface.motion1 = geom_data1->c_params.motion1;
          }
        }
        else if(!geom_data1->c_params.friction_direction1) {
          // get the orientation of the geom
          //dGeomGetQuaternion(o2, v);
          //dRfromQ(R, v);
          // copy the friction direction
          v1[0] = geom_data2->c_params.friction_direction1->x();
          v1[1] = geom_data2->c_params.friction_direction1->y();
          v1[2] = geom_data2->c_params.friction_direction1->z();
          // translate the friction direction to global coordinates
          // and set friction direction for contact
          //dMULTIPLY0_331(contact[0].fdir1, R, v1);
          contact[0].fdir1[0] = v1[0];
          contact[0].fdir1[1] = v1[1];
          contact[0].fdir1[2] = v1[2];
          if(geom_data2->c_params.motion1) {
            contact[0].surface.mode |= dContactMotion1;
            contact[0].surface.motion1 = geom_data2->c_params.motion1;
          }
        }
        else {
          // the calculation steps as mentioned above
          fprintf(stderr, "the calculation for friction directen set for both nodes is not done yet.\n");
        }
      }

      // then check for fds
      if(geom_data1->c_params.fds1 || geom_data2->c_params.fds1) {
        contact[0].surface.mode |= dContactSlip1;
        contact[0].surface.slip1 = (geom_data1->c_params.fds1 +
                                    geom_data2->c_params.fds1);
      }
      if(geom_data1->c_params.fds2 || geom_data2->c_params.fds2) {
        contact[0].surface.mode |= dContactSlip2;
        contact[0].surface.slip2 = (geom_data1->c_params.fds2 +
                                    geom_data2->c_params.fds2);
      }
      if(geom_data1->c_params.bounce || geom_data2->c_params.bounce) {
        contact[0].surface.mode |= dContactBounce;
        contact[0].surface.bounce = (geom_data1->c_params.bounce +
                                     geom_data2->c_params.bounce);
        if(geom_data1->c_params.bounce_vel > geom_data2->c_params.bounce_vel)
          contact[0].surface.bounce_vel = geom_data1->c_params.bounce_vel;
        else
          contact[0].surface.bounce_vel = geom_data2->c_params.bounce_vel;      
      }

      for (i=1;i<maxNumContacts;i++){
        contact[i] = contact[0];
     
      }

      numc=dCollide(o1,o2, maxNumContacts, &contact[0].geom,sizeof(dContact));
      if(numc){ 
		  
	  
        dJointFeedback *fb;
        draw_item item;
        Vector contact_point;

        num_contacts++;
        if(create_contacts) {
          fb = 0;
          item.id = 0;
          item.type = DRAW_LINE;
          item.draw_state = DRAW_STATE_CREATE;
          item.point_size = 10;
          item.myColor.r = 1;
          item.myColor.g = 0;
          item.myColor.b = 0;
          item.myColor.a = 1;
          item.label = "";
          item.t_width = item.t_height = 0;
          item.texture = "";
          item.get_light = 0;

          for(i=0;i<numc;i++){
            item.start.x() = contact[i].geom.pos[0];
            item.start.y() = contact[i].geom.pos[1];
            item.start.z() = contact[i].geom.pos[2];
            item.end.x() = contact[i].geom.pos[0] + contact[i].geom.normal[0];
            item.end.y() = contact[i].geom.pos[1] + contact[i].geom.normal[1];
            item.end.z() = contact[i].geom.pos[2] + contact[i].geom.normal[2];
            draw_intern.push_back(item);
            if(geom_data1->c_params.friction_direction1 ||
               geom_data2->c_params.friction_direction1) {
              v[0] = contact[i].geom.normal[0];
              v[1] = contact[i].geom.normal[1];
              v[2] = contact[i].geom.normal[2];
              dot = dDOT(v, contact[i].fdir1);
              dOPEC(v, *=, dot);
              contact[i].fdir1[0] -= v[0];
              contact[i].fdir1[1] -= v[1];
              contact[i].fdir1[2] -= v[2];
              dNormalize3(contact[0].fdir1);
            }
            contact[0].geom.depth += (geom_data1->c_params.depth_correction +
                                      geom_data2->c_params.depth_correction);
        
            if(contact[0].geom.depth < 0.0) contact[0].geom.depth = 0.0;
            dJointID c=dJointCreateContact(world,contactgroup,contact+i);

            dJointAttach(c,b1,b2);

            geom_data1->num_ground_collisions += numc;
            geom_data2->num_ground_collisions += numc;

            contact_point.x() = contact[i].geom.pos[0];
            contact_point.y() = contact[i].geom.pos[1];
            contact_point.z() = contact[i].geom.pos[2];

            geom_data1->contact_ids.push_back(geom_data2->id);
            geom_data2->contact_ids.push_back(geom_data1->id);
            geom_data1->contact_points.push_back(contact_point);
            geom_data2->contact_points.push_back(contact_point);
            //if(dGeomGetClass(o1) == dPlaneClass) {
            fb = 0;
            if(geom_data2->sense_contact_force) {
              fb = (dJointFeedback*)malloc(sizeof(dJointFeedback));
              dJointSetFeedback(c, fb);
           
              contact_feedback_list.push_back(fb);
              geom_data2->ground_feedbacks.push_back(fb);
              geom_data2->node1 = false;
            } 
            //else if(dGeomGetClass(o2) == dPlaneClass) {
            if(geom_data1->sense_contact_force) {
              if(!fb) {
                fb = (dJointFeedback*)malloc(sizeof(dJointFeedback));
                dJointSetFeedback(c, fb);
                  
                contact_feedback_list.push_back(fb);
              }
              geom_data1->ground_feedbacks.push_back(fb);
              geom_data1->node1 = true;
            }
          }
        }  
      }
Esempio n. 29
0
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
	//make sure both of the geom's are enabled (otherwise this is
	//a waste of our time
	if( !dGeomIsEnabled( o1 ) || !dGeomIsEnabled (o2 ))
	{
		return;
	}


	//collide spaces if neccesary
	if (dGeomIsSpace (o1) || dGeomIsSpace (o2)) 
	{
		// collide the space(s?)
		dSpaceCollide2 (o1,o2,data,&nearCallback);

		// collide all geoms/spaces within the spaces
		//if (dGeomIsSpace (o1)) dSpaceCollide ((dSpaceID)o1,data,&nearCallback);
		//if (dGeomIsSpace (o2)) dSpaceCollide ((dSpaceID)o2,data,&nearCallback);
    }

	//otherwise no spaces, just collide geoms
	else 
	{

		//make sure one of the geoms has a body
		dBodyID body1 = dGeomGetBody( o1 );
		dBodyID body2 = dGeomGetBody( o2 );
		//if( body1 == 0 && body2 == 0)
			//return;
		
		//make sure that the bodies are enabled
		
		

		//declarations
		DynamicsObject* dynobj=NULL, *dynobj2=NULL;
		int n;

		DynamicsSolver* solver = (DynamicsSolver*)data; 

		
		

		//Get 64 contacts
		const int N = 64;
		dContact contact[N];
		n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));

		//Sort all the contacts
		dContact* sortedContacts[N];
		for( int i=0; i<n; i++ ) sortedContacts[i] = &contact[i];
		qsort( sortedContacts, n,sizeof( dContact*), compareContacts );

		//determine how many contacts to actually care about
		//if( n > 8 )
		//	n = 8;
		
		
		if (n > 0) 
		{
			//figure out surface desc stuff
			DynamicsSurfaceDesc* sd1, *sd2;
			DynamicsSurfaceDesc finaldesc;
			sd1 = (DynamicsSurfaceDesc*)dGeomGetData(contact[0].geom.g1);
			sd2 = (DynamicsSurfaceDesc*)dGeomGetData(contact[0].geom.g2);
 			finaldesc.Combine( sd1, sd2);
		

			//Get the bodies involved in the collision
			dBodyID b1, b2;
			b1 = dGeomGetBody(contact[0].geom.g1);
			b2 = dGeomGetBody(contact[0].geom.g2);

			//Inform objects of the collision that occured.
			if(b1) 	dynobj = (DynamicsObject*)dBodyGetData(b1);
			if(b2)	dynobj2 = (DynamicsObject*)dBodyGetData(b2);
			if( dynobj ) dynobj->OnCollide ( dynobj2 );
			if( dynobj2) dynobj2->OnCollide( dynobj);


			//Generate contact joints
			for (int i=0; i<n; i++) 
			{
				contact[i].surface.mode =  dContactSoftERP | dContactSoftCFM | dContactApprox1;// | dContactBounce;
				//contact[i].surface.mu = 0.5f;
				contact[i].surface.mu = finaldesc.mu;
				
				
				if(contact[i].geom.normal[1] < .8f )
				{
					contact[i].surface.mu = 0.1f;
				}

				contact[i].surface.slip1 = finaldesc.ContactSlip1 ;
				contact[i].surface.slip2 = finaldesc.ContactSlip2 ;
				contact[i].surface.soft_erp = finaldesc.SoftERP ;
				contact[i].surface.soft_cfm = finaldesc.SoftCFM;
				contact[i].surface.bounce = finaldesc.Bounce;
					contact[i].surface.bounce_vel = finaldesc.BounceVelocity ;
				dJointID c = dJointCreateContact (solver->WorldID,solver->ContactGroup,&contact[i]);


				//Insert friction anisotropy code here
				fixFrictionVector( b1, b2, contact[i] );


				dJointAttach (c,
						dGeomGetBody(contact[i].geom.g1),
						dGeomGetBody(contact[i].geom.g2));
			}
				


		}
	}

}
Esempio n. 30
0
void Simulator::DrawGeometry(dGeomID geom)
{
    if(dGeomGetData(geom) == ((void *) &TYPE_OBSTACLE))
	glColor3d(0.8, 0.2, 0.2);
    else if(dGeomGetData(geom) == ((void *) &TYPE_TERRAIN))
	glColor3d(0.4, 0.5, 0.7);
    else //type robot
	glColor3d(0.0, 0, 1.0);
    
    
    const int    type = dGeomGetClass(geom);    
    const dReal *pos  = dGeomGetPosition(geom);
    const dReal *rot  = dGeomGetRotation(geom);
    double       m[16];
    
    glPushMatrix();
 
//transform position and orientation into an OpenGL matrix   
    m[0]  = rot[0];
    m[1]  = rot[4];
    m[2]  = rot[8];
    m[4]  = rot[1];
    m[5]  = rot[5];
    m[6]  = rot[9];
    m[8]  = rot[2];
    m[9]  = rot[6];
    m[10] = rot[10];
    m[3]  = m[7] = m[11] =  0;
    m[15] = 1;
    m[12] = pos[0];
    m[13] = pos[1];
    m[14] = pos[2];
    
    glMultMatrixd(m);
    
    if(type == dBoxClass)
    {
	dVector3 lengths;
	dGeomBoxGetLengths(geom, lengths);

	glPushMatrix();
	glScaled(lengths[0], lengths[1], lengths[2]);
	glutSolidCube(1.0);
	glPopMatrix();

    }
    else if(type == dSphereClass)
	glutSolidSphere(dGeomSphereGetRadius(geom), 20, 20);
    else if(type == dCylinderClass)
    {
	dReal r, length;
	dGeomCylinderGetParams(geom, &r, &length);
	glTranslated(0, 0, -0.5 * length);
	
	static GLUquadric *gluQuadric = NULL;
	if(gluQuadric == NULL)
	    gluQuadric = gluNewQuadric();
	gluCylinder(gluQuadric, r, r, length, 20, 20);
    }
    
    glPopMatrix();
}