示例#1
0
 /// After the Run() has completed, you can call this function to
 /// fill a 'contact container', that is an object inherited from class
 /// ChContactContainer. For instance ChSystem, after each Run()
 /// collision detection, calls this method multiple times for all contact containers in the system,
 /// Children classes _must_ implement this.
 /// The basic behavior of the implementation should be the following: collision system
 /// will call in sequence the functions BeginAddContact(), AddContact() (x n times),
 /// EndAddContact() of the contact container.
 /// In case a specialized implementation (ex. a GPU parallel collision engine)
 /// finds that the contact container is a specialized one (ex with a GPU buffer)
 /// it can call more performant methods to add directly the contacts in batches, for instance
 /// by recognizing that he can call, say, some special AddAllContactsAsGpuBuffer() instead of many AddContact().
 public abstract void ReportContacts(ChContactContainer mcontactcontainer);
示例#2
0
            public override void ReportContacts(ChContactContainer mcontactcontainer)
            {
                // This should remove all old contacts (or at least rewind the index)
                mcontactcontainer.BeginAddContact();

                // NOTE: Bullet does not provide information on radius of curvature at a contact point.
                // As such, for all Bullet-identified contacts, the default value will be used (SMC only).
                ChCollisionInfo icontact = new ChCollisionInfo();

                int numManifolds = bt_collision_world.GetDispatcher().GetNumManifolds();

                for (int i = 0; i < numManifolds; i++)
                {
                    PersistentManifold contactManifold = bt_collision_world.GetDispatcher().GetManifoldByIndexInternal(i);
                    CollisionObject    obA             = (CollisionObject)(contactManifold.GetBody0());
                    CollisionObject    obB             = (CollisionObject)(contactManifold.GetBody1());

                    if (obA != null && obA != null) // Alan
                    {
                        contactManifold.RefreshContactPoints(ref obA.GetWorldTransform(), ref obB.GetWorldTransform());

                        icontact.modelA = (ChCollisionModel)obA.GetUserPointer();
                        icontact.modelB = (ChCollisionModel)obB.GetUserPointer();

                        double envelopeA = icontact.modelA.GetEnvelope();
                        double envelopeB = icontact.modelB.GetEnvelope();

                        double marginA = icontact.modelA.GetSafeMargin();
                        double marginB = icontact.modelB.GetSafeMargin();

                        // Execute custom broadphase callback, if any
                        bool do_narrow_contactgeneration = true;
                        if (this.broad_callback != null)
                        {
                            do_narrow_contactgeneration = this.broad_callback.OnBroadphase(icontact.modelA, icontact.modelB);
                        }

                        if (do_narrow_contactgeneration)
                        {
                            int numContacts = contactManifold.GetNumContacts();
                            //GetLog() << "numContacts=" << numContacts << "\n";
                            for (int j = 0; j < numContacts; j++)
                            {
                                // Debug.Log("contacts " + numContacts);
                                ManifoldPoint pt = contactManifold.GetContactPoint(j);

                                // Discard "too far" constraints (the Bullet engine also has its threshold)
                                if (pt.GetDistance() < marginA + marginB)
                                {
                                    IndexedVector3 ptA = pt.GetPositionWorldOnA();
                                    IndexedVector3 ptB = pt.GetPositionWorldOnB();

                                    icontact.vpA.Set(ptA.X, ptA.Y, ptA.Z);
                                    icontact.vpB.Set(ptB.X, ptB.Y, ptB.Z);

                                    icontact.vN.Set(-pt.GetNormalWorldOnB().X, -pt.GetNormalWorldOnB().Y,
                                                    -pt.GetNormalWorldOnB().Z);
                                    icontact.vN.Normalize();

                                    double ptdist = pt.GetDistance();

                                    icontact.vpA      = icontact.vpA - icontact.vN * envelopeA;
                                    icontact.vpB      = icontact.vpB + icontact.vN * envelopeB;
                                    icontact.distance = ptdist + envelopeA + envelopeB;

                                    icontact.reaction_cache = pt.reactions_cache;// reactions_cache;

                                    // Execute some user custom callback, if any
                                    bool add_contact = true;
                                    if (this.narrow_callback != null)
                                    {
                                        add_contact = this.narrow_callback.OnNarrowphase(icontact);
                                    }

                                    // Add to contact container
                                    if (add_contact)
                                    {
                                        mcontactcontainer.AddContact(icontact);
                                    }
                                }
                            }
                        }
                    }

                    // you can un-comment out this line, and then all points are removed
                    // contactManifold->clearManifold();
                }
                mcontactcontainer.EndAddContact();
            }