public override IObservable <Space> Process(IObservable <Space> source) { return(Observable.Defer(() => { var handlers = collisionHandlers.ToDictionary(h => new CollisionHandlerKey(h.Material1, h.Material2)); var contacts = new ContactGeom[MaxContacts]; var collisionGroup = new JointGroup(); return source.Do(space => { collisionGroup.Clear(); space.Collide((g1, g2) => { var numContacts = Geom.Collide(g1, g2, contacts); if (numContacts == 0) { return; } var body1 = g1.Body; var body2 = g2.Body; var metadata1 = g1.Tag as GeomMetadata; var metadata2 = g2.Tag as GeomMetadata; if (metadata1 != null) { metadata1.OnCollision(g1, g2, contacts, numContacts); } if (metadata2 != null) { metadata2.OnCollision(g2, g1, contacts, numContacts); } CollisionHandler collisionHandler; if (metadata1 != null && metadata2 != null && handlers.TryGetValue(new CollisionHandlerKey(metadata1.Material, metadata2.Material), out collisionHandler)) { if (body1 != null || body2 != null) { if (ExcludeConnected && body1 != null && body2 != null && Body.AreConnectedExcluding(body1, body2, JointType.Contact)) { return; } var collisionSurface = collisionHandler.CollisionSurface; var world = body1 != null ? body1.World : body2.World; for (int i = 0; i < numContacts; i++) { var contactInfo = new ContactInfo(); contactInfo.Geometry = contacts[i]; contactInfo.Surface = collisionSurface; var contact = new Contact(world, contactInfo, collisionGroup); contact.Attach(body1, body2); } } } }); }).Finally(collisionGroup.Clear); })); }
public Geom isTouchingGeom(bool countGround) { foreach (Geom geometry in Game.instance.physicsSimulator.GeomList) { if (geom != geometry && (geom.CollisionCategories & geometry.CollisionCategories) != CollisionCategory.None && AABB.Intersect(ref geom.AABB, ref geometry.AABB) && geom.Collide(geometry)) { if (countGround || !geometry.Equals(Game.instance.groundGeom)) { return(geom); } } } return(null); }
private void nearCallback(Geom geom1, Geom geom2) { if (!AllowOdeNearCallback) { return; } if (Stuff.SkipBroadPhase.Contains(geom1) || Stuff.SkipBroadPhase.Contains(geom2)) { return; } Body body = geom1.Body; Body body2 = geom2.Body; if (body == null || body2 == null || (body.Kinematic && body2.Kinematic)) { return; } int maxContacts = 10; ContactGeom[] array = new ContactGeom[maxContacts]; ContactInfo contact = default(ContactInfo); for (int i = 0; i < Geom.Collide(geom1, geom2, array); i++) { contact.Geometry = array[i]; contact.Surface.Mode = (ContactModes.Bounce | ContactModes.SoftCfm | ContactModes.SoftErp); contact.Surface.SoftCfm = 0.0001f; contact.Surface.SoftErp = 0.2f; contact.Surface.Mu = float.PositiveInfinity; contact.Surface.Bounce = 0.40f; contact.Surface.BounceVelocity = 0.0002f; Contact _contact = new Contact(Stuff.World, contact, Stuff.ContactGroup); _contact.Attach(body, body2); } }