コード例 #1
0
static void nearCallback(void *data, dGeomID o1, dGeomID o2)        //o1,o2: geometries likely to collide
{
    // inner collision detecting
    innerCollision = innerCollision || (o1 != ground && o2 != ground);

    const int N = 30;
    dContact contact[N];

    // Don’t do anything if the two bodies are connected by a joint
    dBodyID b1 = dGeomGetBody(o1);
    dBodyID b2 = dGeomGetBody(o2);
    if (b1 && b2 && dAreConnected (b1,b2)) return;

    int isGround = ((ground == o1) || (ground == o2));              //Collision with ground
    int n =  dCollide(o1,o2,N,&contact[0].geom,sizeof(dContact));   //n: Number of collision points

    if (isGround) {//If there is a collision with the ground
        for (int i = 0; i < n; i++) {
            contact[i].surface.mode = dContactSoftERP | dContactSoftCFM;
            contact[i].surface.mu   = dInfinity; //Coulomb friction coef
            contact[i].surface.soft_erp = 0.2;	// 1.0 ideal
            contact[i].surface.soft_cfm = 1e-4;	// 0.0 ideal

            dJointID c = dJointCreateContact(world,contactgroup,&contact[i]);
            dJointAttach(c,dGeomGetBody(contact[i].geom.g1),
                           dGeomGetBody(contact[i].geom.g2));
        }
    }
}
コード例 #2
0
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
	int i,n;
	
	dBodyID b1 = dGeomGetBody(o1);
	dBodyID b2 = dGeomGetBody(o2);
	if (b1 && b2 && dAreConnected(b1, b2))
		return;
	
	const int N = 4;
	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 = 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 = 0.0;
			contact[i].surface.slip2 = 0.0;
			contact[i].surface.soft_erp = 0.8;
			contact[i].surface.soft_cfm = 0.01;
			dJointID c = dJointCreateContact (world,contactgroup,contact+i);
			dJointAttach (c,dGeomGetBody(o1),dGeomGetBody(o2));
		}
	}
}
コード例 #3
0
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  int i;
  // if (o1->body && o2->body) return;

  // 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;
    if (b1 && b2 && dAreConnected (b1,b2) ) 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))) {

    //printf("%d\n",numc);
    if (numc>3) numc=3;
    const dReal ss[3] = {0.02,0.02,0.02};
    for (i=0; i<numc; i++) {
      dJointID c = dJointCreateContact (ptr_world,ptr_contactgroup,contact+i);
      dJointAttach (c,b1,b2);

    }
  }

}
コード例 #4
0
ファイル: ODEBaseScene.cpp プロジェクト: saneku/PODE2.0
//description
//Default behavior. 
//Default collision of bodies
void ODEBaseScene::Collide(dGeomID g1, dGeomID g2)
{
    int n;
    
    dBodyID b1 = dGeomGetBody(g1);
    dBodyID b2 = dGeomGetBody(g2);
    if (b1 && b2 && dAreConnected(b1, b2))
            return;
 
    const int N = 4;
    dContact contact[N];
    n = dCollide (g1,g2,N,&contact[0].geom,sizeof(dContact));
    if (n > 0) 
    {
        // printf("Body %d hits body %d.\n", (size_t) dGeomGetData(g1),(size_t) dGeomGetData(g2));
        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 (m_domain->getWorld(), m_domain->getContactGroup(), contact+i);
            dJointAttach(j, b1, b2);
        }
    }
}
コード例 #5
0
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  // exit without doing anything if the two bodies are connected by a joint
  dBodyID b1 = dGeomGetBody(o1);
  dBodyID b2 = dGeomGetBody(o2);
  if (b1 && b2 && dAreConnected (b1,b2)) return;

  // @@@ it's still more convenient to use the C interface here.

  dContact contact;
  contact.surface.mode = 0;
  contact.surface.mu = dInfinity;
  if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom))) {
    dJointID c = dJointCreateContact (world.id(),contactgroup.id(),&contact);
    dJointAttach (c,b1,b2);
  }
}
コード例 #6
0
ファイル: demo_chain1.c プロジェクト: soubok/libset
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  /* exit without doing anything if the two bodies are connected by a joint */
  dBodyID b1,b2;
  dContact contact;

  b1 = dGeomGetBody(o1);
  b2 = dGeomGetBody(o2);
  if (b1 && b2 && dAreConnected (b1,b2)) return;

  contact.surface.mode = 0;
  contact.surface.mu = 0.1;
  contact.surface.mu2 = 0;
  if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom))) {
    dJointID c = dJointCreateContact (world,contactgroup,&contact);
    dJointAttach (c,b1,b2);
  }
}
コード例 #7
0
// this is called by dSpaceCollide when two objects in space are
// potentially colliding.
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
    dBodyID b1,b2;
    dBodyID test;
    assert(o1);
    assert(o2);

    b1 = dGeomGetBody(o1);
    b2 = dGeomGetBody(o2);

    if (b1 && b2 && dAreConnected (b1,b2)) return;

    if (o1 == floorplane || o2 == floorplane)
    {
        if (o1==floorplane)
            test=b2;
        if (o2==floorplane)
            test=b1;
//test should equal the body that is colliding with floor

        for (int x=0; x<creatures.size(); x++)
        {
            int bsize=creatures[x]->bodies.size();
            for (int y=0; y<bsize; y++)
                if (test==creatures[x]->bodies[y])
                    creatures[x]->onground[y]=true;
        }
    }

    const int N = 32;
    dContact contact[N];
    int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact));
    if (n > 0)
    {
        for (int i=0; i<n; i++)
        {
            contact[i].surface.mode = 0;
            contact[i].surface.mu = dInfinity; //50.0; // was: dInfinity
            dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
            dJointAttach (c, dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2));
        }
    }
}
コード例 #8
0
ファイル: test_ray.cpp プロジェクト: Sean3Don/opentribot
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  int i;
  // if (o1->body && o2->body) return;

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

  dContact contact[32];			// up to 3 contacts per box
  for (i=0; i<32; i++) {
    contact[i].surface.mode = dContactBounce; //dContactMu2;
    contact[i].surface.mu = dInfinity;
    contact[i].surface.mu2 = 0;
    contact[i].surface.bounce = 0.5;
    contact[i].surface.bounce_vel = 0.1;
  }
  if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) {
     dMatrix3 RI;
     dRSetIdentity (RI);
     const dReal ss[3] = {0.02,0.02,0.02};
    for (i=0; i<numc; i++) {
		if (dGeomGetClass(o1) == dRayClass || dGeomGetClass(o2) == dRayClass){
			dMatrix3 Rotation;
			dRSetIdentity(Rotation);
			dsDrawSphere(contact[i].geom.pos, Rotation, REAL(0.01));
			continue;
		}

      dJointID c = dJointCreateContact (world,contactgroup,contact+i);
      dJointAttach (c,b1,b2);
       //dsDrawBox (contact[i].geom.pos,RI,ss);

	  
    }
  }
}
コード例 #9
0
ファイル: physicsserver.cpp プロジェクト: skopp/rush
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
コード例 #10
0
ファイル: ODEWorld.cpp プロジェクト: SIGVerse/SIGServer
static void nearCB(void *data, dGeomID o1, dGeomID o2)
{
	ODEObj *odeobj1 = ODEObjectContainer::getInstance()->getODEObjFromGeomID(o1);
	ODEObj *odeobj2 = ODEObjectContainer::getInstance()->getODEObjFromGeomID(o2);

	/*
	SSimRobotEntity *ent1 = ODEObjectContainer::getInstance()->getSSimRobotEntityFromGeomID(o1);
	SSimRobotEntity *ent2 = ODEObjectContainer::getInstance()->getSSimRobotEntityFromGeomID(o2);
	
	if(ent1 != NULL && ent2 != NULL && ent1->name() == ent2->name()){
	  //LOG_MSG(("name (%s, %s)",ent1->name().c_str(), ent2->name().c_str()));
	  return;
	}
	*/

	SParts *p1 = NULL;
	SParts *p2 = NULL;
	dBodyID b1 = dGeomGetBody(o1);
	dBodyID b2 = dGeomGetBody(o2);

	if (b1 == b2) {
		return;
	}

	ODEWorld *world = ODEWorld::get();
	dGeomID ground = world->getGround();

	if (b1 && b2) {
		if (dAreConnected(b1, b2)) { 
			return; 
		}
	}

	if (b1) {
		void *d = dBodyGetData(b1);
		if (d) {
			p1 = (SParts*)d;
			if (p1->isBlind()) { return; }
		}
	}
	
	if (b2) {
		void *d = dBodyGetData(b2);
		if (d) {
			p2 = (SParts*)d;
			if (p2->isBlind()) { return; }
		}
	}

	if (p1 && p2 && p1->sameParent(*p2)) { return; }

	if (dGeomIsSpace(o1) && dGeomIsSpace(o2)) {
		dSpaceCollide2(o1, o2, data, &collideCB);
		return;
	}

#define F_SCHOLAR(V) sqrt(V[0]*V[0] + V[1]*V[1] + V[2]*V[2])

	static dJointFeedback fb;

#define MAX_COLLISION 32

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

	if (n > 0) {
		ODEWorld *world = ODEWorld::get();

		for (int i=0; i<n; i++) {
			dContact *c = &contacts[i];
			dContactGeom &g = c->geom;

			if (p1 && p2) {
#if 0
				LOG_SYS(("Collision #%d/%d %s(geomID=%d) <-> %s(geomID=%d)", i, n,
						 p1->getParent()->name(), o1,
						 p2->getParent()->name(), o2));
				LOG_SYS(("\tpos = (%f, %f, %f)", g.pos[0], g.pos[1], g.pos[2]));
				LOG_SYS(("\tnormal = (%f, %f, %f)", g.normal[0], g.normal[1], g.normal[2]));
				LOG_SYS(("\tfdir = (%f, %f, %f)", c->fdir1[0], c->fdir1[1], c->fdir1[2]));
				LOG_SYS(("\tdepth = %f", g.depth));
#endif
				const char *name1 = p1->getParent()->name();
				const char *name2 = p2->getParent()->name();
				std::string key = chash_key(name1, name2);
				if (key.length() <= 0) { continue; }
				if (chash_find(key)) { continue; }
				s_chash[key] = true;
				s_collisions.push_back(ODEWorld::Collision(name1, name2, p1->name(), p2->name()));
				// Set the collision flag to be ON
				p1->setOnCollision(true);
				p2->setOnCollision(true);
			}
			
			//c->surface.mode = dContactBounce;
			c->surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactBounce;
			//c->surface.mode = dContactSlip1 | dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactBounce;
			//
			// Reflection of material parameters of the collided object
			// Fliction force should be regarded as average of contiguous material (???)
			// TODO: Calclation of fliction force sould be considered
			//
#if 0			
			if (odeobj1 && odeobj2) {
				c->surface.mu       = ( odeobj1->getMu1()     + odeobj2->getMu1() )     / 2.0;
				c->surface.mu2      = ( odeobj1->getMu2()     + odeobj2->getMu2() )     / 2.0;
				c->surface.slip1    = ( odeobj1->getSlip1()   + odeobj2->getSlip1() )   / 2.0;
				c->surface.slip2    = ( odeobj1->getSlip2()   + odeobj2->getSlip2() )   / 2.0;
				c->surface.soft_erp = ( odeobj1->getSoftErp() + odeobj2->getSoftErp() ) / 2.0;
				c->surface.soft_cfm = ( odeobj1->getSoftCfm() + odeobj2->getSoftCfm() ) / 2.0;
				c->surface.bounce   = ( odeobj1->getBounce()  + odeobj2->getBounce() )  / 2.0;
			}
			else {
				c->surface.bounce_vel = world->getCollisionParam("bounce_vel");
				c->surface.bounce     = world->getCollisionParam("bounce");
				c->surface.mu         = world->getCollisionParam("mu");
				c->surface.mu2        = world->getCollisionParam("mu2");
				c->surface.slip1      = world->getCollisionParam("slip1");
				c->surface.slip2      = world->getCollisionParam("slip2");
				c->surface.soft_erp   = world->getCollisionParam("soft_erp");
				c->surface.soft_cfm   = world->getCollisionParam("soft_cfm");
			}
#else
			c->surface.mu	    = SPARTS_MU1;
			c->surface.mu2      = SPARTS_MU2;
			c->surface.slip1    = SPARTS_SLIP1;
			c->surface.slip2    = SPARTS_SLIP2;
			c->surface.soft_erp = SPARTS_ERP;     // parameter for modify the error of Joint position (0..1); if it is 1, modification will be perfect
			c->surface.soft_cfm = SPARTS_CFM;     // If this value=0, joint velocity is strange
			c->surface.bounce   = SPARTS_BOUNCE; // is a little smaller than ball
			c->surface.bounce_vel = 0.0;
#endif
			dJointID cj = dJointCreateContact(world->world(), world->jointGroup(), c);
			//dJointAttach(cj, dGeomGetBody(o1), dGeomGetBody(o2));  //by MSI
			dJointAttach(cj, dGeomGetBody(c->geom.g1), dGeomGetBody(c->geom.g2)); // by Demura.net
#if 0
			if (p1 && p2) {
				dJointSetFeedback(cj, &fb);
				dJointFeedback *pfb = dJointGetFeedback(cj);
				
				if (F_SCHOLAR(pfb->f1) > 1.0) {
					LOG_SYS(("\tF1 = (%f, %f, %f)",   pfb->f1[0], pfb->f1[1], pfb->f1[2]));
					LOG_SYS(("\tF2 = (%f, %f, %f)\n", pfb->f2[0], pfb->f2[1], pfb->f2[2]));
				}
			}
#endif
		}
	}
}
コード例 #11
0
ファイル: Simulation.cpp プロジェクト: alon/track
void Simulation::nearCallback(void* data, dGeomID o1, dGeomID o2)
{
	int i;
	// if (o1->body && o2->body) return;

	// exit without doing anything if the two bodies are connected by a joint
	dBodyID b1 = dGeomGetBody(o1);
	dBodyID b2 = dGeomGetBody(o2);
	//PEXP(b1);
	//PEXP(b2);
	//if (dAreConnected (b1, b2)) cout << "debug: CONNECTED CONNECTED OVER\n";
	if (b1 && b2 && dAreConnected(b1, b2))
		return;

	int g1 = (o1 == this->ground);
	int g2 = (o2 == this->ground);
	int not_ground = (!(g1 ^ g2));
	int one_is_link = (o1 != this->ground) && (b1) && ( dBodyGetData(b1) == (void*)tagLink);
	int two_is_link = (o2 != this->ground) && (b2) && ( dBodyGetData(b2) == (void*)tagLink);
	int link_link = one_is_link && two_is_link;
	double mu;

	// determine friction
	if (link_link)
		mu = 0;
	else if (not_ground)
		mu = this->mu_non_ground;
	else mu = this->mu_ground;
		
	// profiling
	this->callback_count++;

	// debug
	//if (b1 == sprocket || b2 == sprocket) { cout << "debug: collision with sprocket\n"; }

	dContact contact[3];	// up to 3 contacts per box
	if (not_ground) { // except for mu, link_link and link_sprocket are bundled together
		for (i = 0; i < 3; i++) {
			//      contact[i].surface.mode = dContactSoftCFM | dContactApprox1;
			contact[i].surface.mode = 0;
			contact[i].surface.mu = mu;
			contact[i].surface.soft_cfm = 0.01;
		}
	} else {
		for (i = 0; i < 3; i++) {
			contact[i].surface.mode =
			    dContactSlip1 | dContactSlip2 | dContactSoftERP
			    | dContactSoftCFM | dContactApprox1;  // Approx1 means friction only for non zero normal
			contact[i].surface.mu = mu;//dInfinity;
			contact[i].surface.slip1 = 0.1;
			contact[i].surface.slip2 = 0.1;
			contact[i].surface.soft_erp = this->ground_soft_erp;	//0.3;
			contact[i].surface.soft_cfm = this->ground_soft_cfm;	//0.5;
		}
	}
	if (int numc =
	    dCollide(o1, o2, 3, &contact[0].geom, sizeof(dContact))) {
		// profiling
		if (not_ground) {
			this->not_ground_count++;
//              std::cout << "debug: not_ground collision\n";
		} else {
			this->ground_count++;
			//cout << "debug:     ground collision\n";
			
			// if a link is involved, increment its count of contact joints
			dBodyID one_link = (o1 == this->ground? b2 : b1);
			dBodySetData(one_link, (void*)((int)dBodyGetData(one_link) + numc));
		};
		//dMatrix3 RI;
		//dRSetIdentity (RI);
		//const dReal ss[3] = {0.02,0.02,0.02};
		//PEXP(numc);
		for (i = 0; i < numc; i++) {
			dJointID c =
			    dJointCreateContact(this->world, this->contactgroup,
						contact + i);
			dJointAttach(c, b1, b2);
			// dsDrawBox (contact[i].geom.pos,RI,ss);
		}
	}
}
コード例 #12
0
ファイル: testbox.cpp プロジェクト: faturita/wakuseibokan
void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
    int i,n;

    dBodyID b1,b2;

    // only collide things with the ground
    int g1 = (o1 == ground );
    int g2 = (o2 == ground );
    if (!(g1 ^ g2))
    {
        //printf ("Ground colliding..\n");

        //return;
    }


    b1 = dGeomGetBody(o1);
    b2 = dGeomGetBody(o2);
    if (b1 && b2 && dAreConnected (b1,b2)) return;

    if (b1 && isAction(b1) && b2 && (isType(b2,WALRUS) || (isType(b2,MANTA))) && isMineFire(gVehicle(b2),(Gunshot*)gVehicle(b1)) ) return;
    if (b2 && isAction(b2) && b1 && (isType(b1,WALRUS) || (isType(b1,MANTA))) && isMineFire(gVehicle(b1),(Gunshot*)gVehicle(b2)) ) return;

    int val[]={CARRIER,WALRUS,MANTA};

    if (o1 && isRay(o1) && b2 && isType(b2,val,3) && rayHit(gVehicle(b2),(LaserRay*)gVehicle(o1))) {return;}
    if (o2 && isRay(o2) && b1 && isType(b1,val,3) && rayHit(gVehicle(b1),(LaserRay*)gVehicle(o2))) {return;}

    const int N = 10;
    dContact contact[N];
    n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
    if (n > 0) {
        for (i=0; i<n; i++) {

            Vehicle *v1=NULL,*v2=NULL;
            Structure *s1=NULL, *s2=NULL;
            gVehicle(v1,v2,dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2),s1,s2,contact[i].geom.g1,contact[i].geom.g2);


            // Bullets
            if ((isAction(v1) && isWalrus(v2) && isMineFire(v2,(Gunshot*)v1))
                ||
               (isAction(v2) && isWalrus(v1) && isMineFire(v1,(Gunshot*)v2)))
            {
                // Water buyoncy reaction
                contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                dContactSoftERP | dContactSoftCFM | dContactApprox1;

                contact[i].surface.mu = 0.0f;
                contact[i].surface.slip1 = 1.0f;
                contact[i].surface.slip2 = 1.0f;
                contact[i].surface.soft_erp = 1.0f;   // 0 in both will force the surface to be tight.
                contact[i].surface.soft_cfm = 1.0f;
            } else
            if ( isAction(v1) || isAction(v2))
            {
                contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                dContactSoftERP | dContactSoftCFM | dContactApprox1;
                contact[i].surface.mu = 0;
                contact[i].surface.slip1 = 0.1f;
                contact[i].surface.slip2 = 0.1f;

                if (isAction(v1) && isCarrier(v2) && hit(v2,(Gunshot*)v1)) {}
                if (isAction(v2) && isCarrier(v1) && hit(v1,(Gunshot*)v2)) {}
                if (isAction(v1) && isManta(v2) && hit(v2,(Gunshot*)v1)) {}
                if (isAction(v2) && isManta(v1) && hit(v1,(Gunshot*)v2)) {}
                if (isAction(v1) && isWalrus(v2) && hit(v2,(Gunshot*)v1)) {}
                if (isAction(v2) && isWalrus(v1) && hit(v1,(Gunshot*)v2)) {}
                if (isAction(v1) && s2 && hit(s2)) {}
                if (isAction(v2) && s1 && hit(s1)) {}
            } else
            if ( ( isManta(v1) && isCarrier(v2) && releasecontrol(v1) ) ||
                 ( isManta(v2) && isCarrier(v1) && releasecontrol(v2) ) )
                {
                // Manta landing on Carrier
                contact[i].surface.mode = dContactBounce |
                dContactApprox1;

                contact[i].surface.mu = dInfinity;
                contact[i].surface.slip1 = 0.0f;
                contact[i].surface.slip2 = 0.0f;
                contact[i].surface.bounce = 0.2f;
            } else
            if  (isRunway(s1) || isRunway(s2))
            {
                // Manta landing on Runways.
                contact[i].surface.mode = dContactBounce |
                dContactApprox1;


                contact[i].surface.mu = 0.99f;
                contact[i].surface.slip1 = 0.9f;
                contact[i].surface.slip2 = 0.9f;
                contact[i].surface.bounce = 0.2f;

                if ( isRunway(s1) && isManta(v2) && landed(v2, s1->island)) {}
                if ( isRunway(s2) && isManta(v1) && landed(v1, s2->island)) {}

            } else
            if (isIsland(contact[i].geom.g1) || isIsland(contact[i].geom.g2))
            {
                 // Island reaction
                 contact[i].surface.mode = dContactBounce |
                 dContactApprox1;

                 contact[i].surface.mu = 0;
                 contact[i].surface.bounce = 0.2f;
                 contact[i].surface.slip1 = 0.1f;
                 contact[i].surface.slip2 = 0.1f;

                 contact[i].surface.soft_erp = 0;   // 0 in both will force the surface to be tight.
                 contact[i].surface.soft_cfm = 0;


                 // Carrier stranded and Walrus arrived on island.
                 if (isIsland(contact[i].geom.g1) && isCarrier(v2) && stranded(v2,getIsland(contact[i].geom.g1))) {}
                 if (isIsland(contact[i].geom.g2) && isCarrier(v1) && stranded(v1,getIsland(contact[i].geom.g2))) {}
                 if (isIsland(contact[i].geom.g1) && isWalrus(v2)  && arrived(v2,getIsland(contact[i].geom.g1))) {}
                 if (isIsland(contact[i].geom.g2) && isWalrus(v1)  && arrived(v1,getIsland(contact[i].geom.g2))) {}


            } else
            if (ground == contact[i].geom.g1 || ground == contact[i].geom.g2 ) {

                 // Water buyoncy reaction
                 contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                 dContactSoftERP | dContactSoftCFM | dContactApprox1;

                 contact[i].surface.mu = 0.0f;
                 contact[i].surface.slip1 = 0.1f;
                 contact[i].surface.slip2 = 0.1f;
                 contact[i].surface.soft_erp = .5f;   // 0 in both will force the surface to be tight.
                 contact[i].surface.soft_cfm = .3f;

                 // Walrus reaching shore.
                 if (ground == contact[i].geom.g1 && isWalrus(v2) && departed(v2)) {}
                 if (ground == contact[i].geom.g2 && isWalrus(v1) && departed(v1)) {}

                 if (ground == contact[i].geom.g1 && v2 && isManta(v2) && groundcollisions(v2)) {}
                 if (ground == contact[i].geom.g2 && v1 && isManta(v1) && groundcollisions(v1)) {}

            } else {
                /**
                // Water buyoncy reaction
                contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                dContactSoftERP | dContactSoftCFM | dContactApprox1;

                contact[i].surface.mu = 0.0f;
                contact[i].surface.slip1 = 0.1f;
                contact[i].surface.slip2 = 0.1f;
                contact[i].surface.soft_erp = .5f;   // 0 in both will force the surface to be tight.
                contact[i].surface.soft_cfm = .3f;
                **/
                if (v1 && isManta(v1) && groundcollisions(v1)) {}
                if (v2 && isManta(v2) && groundcollisions(v2)) {}
            }

            dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
            dJointAttach (c,
                          dGeomGetBody(contact[i].geom.g1),
                          dGeomGetBody(contact[i].geom.g2));
        }
    }
}