public void ProcessChildShape(CollisionShape childShape, int index)
        {
            Debug.Assert(index >= 0);
            CompoundShape compoundShape = (CompoundShape)(m_compoundColObj.GetCollisionShape());

            Debug.Assert(index < compoundShape.GetNumChildShapes());

            //backup
            IndexedMatrix orgTrans = m_compoundColObj.GetWorldTransform();
            IndexedMatrix orgInterpolationTrans = m_compoundColObj.GetInterpolationWorldTransform();
            IndexedMatrix childTrans            = compoundShape.GetChildTransform(index);
            IndexedMatrix newChildWorldTrans    = orgTrans * childTrans;

            //perform an AABB check first
            IndexedVector3 aabbMin0;
            IndexedVector3 aabbMax0;
            IndexedVector3 aabbMin1;
            IndexedVector3 aabbMax1;

            childShape.GetAabb(ref newChildWorldTrans, out aabbMin0, out aabbMax0);
            m_otherObj.GetCollisionShape().GetAabb(m_otherObj.GetWorldTransform(), out aabbMin1, out aabbMax1);

            if (AabbUtil2.TestAabbAgainstAabb2(ref aabbMin0, ref aabbMax0, ref aabbMin1, ref aabbMax1))
            {
                m_compoundColObj.SetWorldTransform(ref newChildWorldTrans);
                m_compoundColObj.SetInterpolationWorldTransform(ref newChildWorldTrans);

                //the contactpoint is still projected back using the original inverted worldtrans
                CollisionShape tmpShape = m_compoundColObj.GetCollisionShape();
                m_compoundColObj.InternalSetTemporaryCollisionShape(childShape);

                if (m_childCollisionAlgorithms[index] == null)
                {
                    m_childCollisionAlgorithms[index] = m_dispatcher.FindAlgorithm(m_compoundColObj, m_otherObj, m_sharedManifold);
                    if (m_childCollisionAlgorithms[index] == m_parent)
                    {
                        int ibreak = 0;
                    }
                }

                ///detect swapping case
                if (m_resultOut.GetBody0Internal() == m_compoundColObj)
                {
                    m_resultOut.SetShapeIdentifiersA(-1, index);
                }
                else
                {
                    m_resultOut.SetShapeIdentifiersB(-1, index);
                }


                m_childCollisionAlgorithms[index].ProcessCollision(m_compoundColObj, m_otherObj, m_dispatchInfo, m_resultOut);
                if (m_dispatchInfo.getDebugDraw() != null && (((m_dispatchInfo.getDebugDraw().GetDebugMode() & DebugDrawModes.DBG_DrawAabb)) != 0))
                {
                    IndexedVector3 worldAabbMin = IndexedVector3.Zero, worldAabbMax = IndexedVector3.Zero;
                    m_dispatchInfo.getDebugDraw().DrawAabb(aabbMin0, aabbMax0, new IndexedVector3(1, 1, 1));
                    m_dispatchInfo.getDebugDraw().DrawAabb(aabbMin1, aabbMax1, new IndexedVector3(1, 1, 1));
                }

                //revert back transform
                m_compoundColObj.InternalSetTemporaryCollisionShape(tmpShape);
                m_compoundColObj.SetWorldTransform(ref orgTrans);
                m_compoundColObj.SetInterpolationWorldTransform(ref orgInterpolationTrans);
            }
        }
예제 #2
0
        public void GImpactVsShape(CollisionObject body0,
                                   CollisionObject body1,
                                   GImpactShapeInterface shape0,
                                   CollisionShape shape1, bool swapped)
        {
#if DEBUG
            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
            {
                BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsShape");
            }
#endif

            if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE)
            {
                GImpactMeshShape meshshape0 = shape0 as GImpactMeshShape;

                // check this...
                //int& part = swapped ? m_part1 : m_part0;
                //part = meshshape0.GetMeshPartCount();
                int part = meshshape0.GetMeshPartCount();

                while (part-- != 0)
                {
                    GImpactVsShape(body0,
                                   body1,
                                   meshshape0.GetMeshPart(part),
                                   shape1, swapped);
                }
                if (swapped)
                {
                    m_part1 = part;
                }
                else
                {
                    m_part0 = part;
                }
                return;
            }

#if GIMPACT_VS_PLANE_COLLISION
            if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE_PART &&
                shape1.GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE)
            {
                GImpactMeshShapePart shapepart  = shape0 as GImpactMeshShapePart;
                StaticPlaneShape     planeshape = shape1 as StaticPlaneShape;
                GImpactTrimeshpartVsPlaneCollision(body0, body1, shapepart, planeshape, swapped);
                return;
            }
#endif



            if (shape1.IsCompound())
            {
                CompoundShape compoundshape = shape1 as CompoundShape;
                GImpactVsCompoundshape(body0, body1, shape0, compoundshape, swapped);
                return;
            }
            else if (shape1.IsConcave())
            {
                ConcaveShape concaveshape = shape1 as ConcaveShape;
                GImpactVsConcave(body0, body1, shape0, concaveshape, swapped);
                return;
            }


            IndexedMatrix orgtrans0 = body0.GetWorldTransform();

            IndexedMatrix orgtrans1 = body1.GetWorldTransform();

            ObjectArray <int> collided_results = new ObjectArray <int>(64);

            GImpactVsShapeFindPairs(ref orgtrans0, ref orgtrans1, shape0, shape1, collided_results);

            if (collided_results.Count == 0)
            {
                return;
            }


            shape0.LockChildShapes();

            using (GIM_ShapeRetriever retriever0 = BulletGlobals.GIM_ShapeRetrieverPool.Get())
            {
                retriever0.Initialize(shape0);
                bool child_has_transform0 = shape0.ChildrenHasTransform();


                int i = collided_results.Count;
#if DEBUG
                if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
                {
                    BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsShape [{0}]", collided_results.Count);
                }
#endif

                while (i-- != 0)
                {
                    int child_index = collided_results[i];
                    if (swapped)
                    {
                        m_triface1 = child_index;
                    }
                    else
                    {
                        m_triface0 = child_index;
                    }

                    CollisionShape colshape0 = retriever0.GetChildShape(child_index);

                    if (child_has_transform0)
                    {
                        body0.SetWorldTransform(orgtrans0 * shape0.GetChildTransform(child_index));
                    }

                    //collide two shapes
                    if (swapped)
                    {
                        ShapeVsShapeCollision(body1, body0, shape1, colshape0);
                    }
                    else
                    {
                        ShapeVsShapeCollision(body0, body1, colshape0, shape1);
                    }

                    //restore transforms
                    if (child_has_transform0)
                    {
                        body0.SetWorldTransform(ref orgtrans0);
                    }
                }

                shape0.UnlockChildShapes();
            }
        }
        public override void ProcessCollision(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            //resultOut = null;
            CollisionObject colObj   = m_isSwapped ? body1 : body0;
            CollisionObject otherObj = m_isSwapped ? body0 : body1;

            Debug.Assert(colObj.GetCollisionShape().IsCompound());
            CompoundShape compoundShape = (CompoundShape)(colObj.GetCollisionShape());

            ///btCompoundShape might have changed:
            ////make sure the internal child collision algorithm caches are still valid
            if (compoundShape.GetUpdateRevision() != m_compoundShapeRevision)
            {
                ///clear and update all
                RemoveChildAlgorithms();
                PreallocateChildAlgorithms(body0, body1);
            }


            Dbvt tree = compoundShape.GetDynamicAabbTree();

            //use a dynamic aabb tree to cull potential child-overlaps
            using (CompoundLeafCallback callback = BulletGlobals.CompoundLeafCallbackPool.Get())
            {
                callback.Initialize(colObj, otherObj, m_dispatcher, dispatchInfo, resultOut, this, m_childCollisionAlgorithms, m_sharedManifold);

                ///we need to refresh all contact manifolds
                ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
                ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
                {
                    m_manifoldArray.Clear();
                    for (int i = 0; i < m_childCollisionAlgorithms.Count; i++)
                    {
                        if (m_childCollisionAlgorithms[i] != null)
                        {
                            m_childCollisionAlgorithms[i].GetAllContactManifolds(m_manifoldArray);
                            for (int m = 0; m < m_manifoldArray.Count; m++)
                            {
                                if (m_manifoldArray[m].GetNumContacts() > 0)
                                {
                                    resultOut.SetPersistentManifold(m_manifoldArray[m]);
                                    resultOut.RefreshContactPoints();
                                    resultOut.SetPersistentManifold(null);//??necessary?
                                }
                            }
                            m_manifoldArray.Clear();
                        }
                    }
                }

                if (tree != null)
                {
                    IndexedVector3 localAabbMin;
                    IndexedVector3 localAabbMax;
                    IndexedMatrix  otherInCompoundSpace;
                    //otherInCompoundSpace = MathUtil.BulletMatrixMultiply(colObj.GetWorldTransform(),otherObj.GetWorldTransform());
                    otherInCompoundSpace = colObj.GetWorldTransform().Inverse() * otherObj.GetWorldTransform();

                    otherObj.GetCollisionShape().GetAabb(ref otherInCompoundSpace, out localAabbMin, out localAabbMax);

                    DbvtAabbMm bounds = DbvtAabbMm.FromMM(ref localAabbMin, ref localAabbMax);
                    //process all children, that overlap with  the given AABB bounds
                    Dbvt.CollideTV(tree.m_root, ref bounds, callback);
                }
                else
                {
                    //iterate over all children, perform an AABB check inside ProcessChildShape
                    int numChildren = m_childCollisionAlgorithms.Count;
                    for (int i = 0; i < numChildren; i++)
                    {
                        callback.ProcessChildShape(compoundShape.GetChildShape(i), i);
                    }
                }

                {
                    //iterate over all children, perform an AABB check inside ProcessChildShape
                    int numChildren = m_childCollisionAlgorithms.Count;

                    m_manifoldArray.Clear();
                    CollisionShape childShape = null;
                    IndexedMatrix  orgTrans;
                    IndexedMatrix  orgInterpolationTrans;
                    IndexedMatrix  newChildWorldTrans;


                    for (int i = 0; i < numChildren; i++)
                    {
                        if (m_childCollisionAlgorithms[i] != null)
                        {
                            childShape = compoundShape.GetChildShape(i);
                            //if not longer overlapping, remove the algorithm
                            orgTrans = colObj.GetWorldTransform();
                            orgInterpolationTrans = colObj.GetInterpolationWorldTransform();
                            IndexedMatrix childTrans = compoundShape.GetChildTransform(i);

                            newChildWorldTrans = orgTrans * childTrans;

                            //perform an AABB check first
                            IndexedVector3 aabbMin0;
                            IndexedVector3 aabbMax0;
                            IndexedVector3 aabbMin1;
                            IndexedVector3 aabbMax1;

                            childShape.GetAabb(ref newChildWorldTrans, out aabbMin0, out aabbMax0);
                            otherObj.GetCollisionShape().GetAabb(otherObj.GetWorldTransform(), out aabbMin1, out aabbMax1);

                            if (!AabbUtil2.TestAabbAgainstAabb2(ref aabbMin0, ref aabbMax0, ref aabbMin1, ref aabbMax1))
                            {
                                m_dispatcher.FreeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
                                m_childCollisionAlgorithms[i] = null;
                            }
                        }
                    }
                }
            }
        }