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)); } } }
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)); } } }
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); } } }
//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); } } }
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); } }
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); } }
// 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)); } } }
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); } } }
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
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 } } }
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); } } }
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)); } } }