Exemple #1
0
        public override IObservable <EventPattern <Geom, GeomCollisionEventArgs> > Process(IObservable <Geom> source)
        {
            return(source.SelectMany(geom =>
            {
                var metadata = geom.Tag as GeomMetadata;
                if (metadata == null)
                {
                    throw new InvalidOperationException("Collision geom must have a valid metadata object.");
                }

                return Observable.Create <EventPattern <Geom, GeomCollisionEventArgs> >(observer =>
                {
                    CollisionEventHandler handler = (g1, g2, contacts, length) =>
                    {
                        if (IncludeContacts)
                        {
                            var output = new ContactGeom[length];
                            Array.Copy(contacts, output, length);
                            contacts = output;
                        }
                        else
                        {
                            contacts = EmptyContacts;
                        }
                        observer.OnNext(new EventPattern <Geom, GeomCollisionEventArgs>(g1, new GeomCollisionEventArgs(g2, contacts)));
                    };

                    metadata.Collision += handler;
                    return Disposable.Create(() => metadata.Collision -= handler);
                });
            }));
        }
Exemple #2
0
        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);
            }));
        }
Exemple #3
0
        static ContactGeom[] Collide(Geom geom1, Geom geom2, int maxContacts)
        {
            var contacts = new ContactGeom[maxContacts];
            var count    = Geom.Collide(geom1, geom2, contacts);

            Array.Resize(ref contacts, count);
            return(contacts);
        }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
 public static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1,
     ref Vector3 side1, ref Vector3 p2,
     ref Matrix3 R2, ref Vector3 side2,
     ref Vector3 normal, out dReal depth, out int return_code,
     int maxc, out ContactGeom contact, int skip);