/// A colliding pair of shapes. public cpArbiter(cpShape a, cpShape b) { this.handler = null; this.swapped = false; this.handlerA = null; this.handlerB = null; /// Calculated value to use for the elasticity coefficient. /// Override in a pre-solve collision handler for custom behavior. this.e = 0; /// Calculated value to use for the friction coefficient. /// Override in a pre-solve collision handler for custom behavior. this.u = 0; /// Calculated value to use for applying surface velocities. /// Override in a pre-solve collision handler for custom behavior. this.surface_vr = cpVect.Zero; this.a = a; this.body_a = a.body; this.b = b; this.body_b = b.body; this.thread_a = new cpArbiterThread(null, null); this.thread_b = new cpArbiterThread(null, null); this.contacts = new List <cpContact>(); this.stamp = 0; this.state = cpArbiterState.FirstCollision; }
public void Update(cpCollisionInfo info, cpSpace space) { cpShape a = info.a, b = info.b; // For collisions between two similar primitive types, the order could have been swapped since the last frame. this.a = a; this.body_a = a.body; this.b = b; this.body_b = b.body; // Iterate over the possible pairs to look for hash value matches. for (int i = 0; i < info.count; i++) { cpContact con = info.arr[i]; // r1 and r2 store absolute offsets at init time. // Need to convert them to relative offsets. con.r1 = cpVect.cpvsub(con.r1, a.body.p); con.r2 = cpVect.cpvsub(con.r2, b.body.p); // Cached impulses are not zeroed at init time. con.jnAcc = con.jtAcc = 0.0f; for (int j = 0; j < this.Count; j++) { cpContact old = this.contacts[j]; // This could trigger false positives, but is fairly unlikely nor serious if it does. if (con.hash == old.hash) { // Copy the persistant contact information. con.jnAcc = old.jnAcc; con.jtAcc = old.jtAcc; } } } //TODO: revise this.contacts = info.arr.ToList(); //this.count = info.count; this.n = info.n; this.e = a.e * b.e; this.u = a.u * b.u; cpVect surface_vr = cpVect.cpvsub(b.surfaceV, a.surfaceV); this.surface_vr = cpVect.cpvsub(surface_vr, cpVect.cpvmult(info.n, cpVect.cpvdot(surface_vr, info.n))); ulong typeA = info.a.type, typeB = info.b.type; cpCollisionHandler defaultHandler = space.defaultHandler; cpCollisionHandler handler = this.handler = space.LookupHandler(typeA, typeB, defaultHandler); // Check if the types match, but don't swap for a default handler which use the wildcard for type A. bool swapped = this.swapped = (typeA != handler.typeA && handler.typeA != cp.WILDCARD_COLLISION_TYPE); if (handler != defaultHandler || space.usesWildcards) { // The order of the main handler swaps the wildcard handlers too. Uffda. this.handlerA = space.LookupHandler(swapped ? typeB : typeA, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing); this.handlerB = space.LookupHandler(swapped ? typeA : typeB, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing); } // mark it as new if it's been cached if (this.state == cpArbiterState.Cached) { this.state = cpArbiterState.FirstCollision; } }
/// Causes a collision pair to be ignored as if you returned false from a begin callback. /// If called from a pre-step callback, you will still need to return false /// if you want it to be ignored in the current step. public bool Ignore() { this.state = cpArbiterState.Ignore; return(false); }
public void Update(cpCollisionInfo info, cpSpace space) { cpShape a = info.a, b = info.b; // For collisions between two similar primitive types, the order could have been swapped since the last frame. this.a = a; this.body_a = a.body; this.b = b; this.body_b = b.body; // Iterate over the possible pairs to look for hash value matches. for (int i = 0; i < info.count; i++) { cpContact con = info.arr[i]; // r1 and r2 store absolute offsets at init time. // Need to convert them to relative offsets. con.r1 = cpVect.cpvsub(con.r1, a.body.p); con.r2 = cpVect.cpvsub(con.r2, b.body.p); // Cached impulses are not zeroed at init time. con.jnAcc = con.jtAcc = 0.0f; for (int j = 0; j < this.Count; j++) { cpContact old = this.contacts[j]; // This could trigger false positives, but is fairly unlikely nor serious if it does. if (con.hash == old.hash) { // Copy the persistant contact information. con.jnAcc = old.jnAcc; con.jtAcc = old.jtAcc; } } } //TODO: revise this.contacts = info.arr.ToList(); //this.count = info.count; this.n = info.n; this.e = a.e * b.e; this.u = a.u * b.u; cpVect surface_vr = cpVect.cpvsub(b.surfaceV, a.surfaceV); this.surface_vr = cpVect.cpvsub(surface_vr, cpVect.cpvmult(info.n, cpVect.cpvdot(surface_vr, info.n))); ulong typeA = info.a.type, typeB = info.b.type; cpCollisionHandler defaultHandler = space.defaultHandler; cpCollisionHandler handler = this.handler = space.LookupHandler(typeA, typeB, defaultHandler); // Check if the types match, but don't swap for a default handler which use the wildcard for type A. bool swapped = this.swapped = (typeA != handler.typeA && handler.typeA != cp.WILDCARD_COLLISION_TYPE); if (handler != defaultHandler || space.usesWildcards) { // The order of the main handler swaps the wildcard handlers too. Uffda. this.handlerA = space.LookupHandler(swapped ? typeB : typeA, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing); this.handlerB = space.LookupHandler(swapped ? typeA : typeB, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing); } // mark it as new if it's been cached if (this.state == cpArbiterState.Cached) this.state = cpArbiterState.FirstCollision; }
/// Causes a collision pair to be ignored as if you returned false from a begin callback. /// If called from a pre-step callback, you will still need to return false /// if you want it to be ignored in the current step. public bool Ignore() { this.state = cpArbiterState.Ignore; return false; }
/// A colliding pair of shapes. public cpArbiter(cpShape a, cpShape b) { this.handler = null; this.swapped = false; this.handlerA = null; this.handlerB = null; /// Calculated value to use for the elasticity coefficient. /// Override in a pre-solve collision handler for custom behavior. this.e = 0; /// Calculated value to use for the friction coefficient. /// Override in a pre-solve collision handler for custom behavior. this.u = 0; /// Calculated value to use for applying surface velocities. /// Override in a pre-solve collision handler for custom behavior. this.surface_vr = cpVect.Zero; this.a = a; this.body_a = a.body; this.b = b; this.body_b = b.body; this.thread_a = new cpArbiterThread(null, null); this.thread_b = new cpArbiterThread(null, null); this.contacts = new List<cpContact>(); this.stamp = 0; this.state = cpArbiterState.FirstCollision; }