예제 #1
0
        public static void FindCollision(GImpactQuantizedBvh boxset0, ref IndexedMatrix trans0,
                                         GImpactQuantizedBvh boxset1, ref IndexedMatrix trans1,
                                         PairSet collision_pairs)
        {
            if (boxset0.GetNodeCount() == 0 || boxset1.GetNodeCount() == 0)
            {
                return;
            }

            BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0 = new BT_BOX_BOX_TRANSFORM_CACHE();

            trans_cache_1to0.CalcFromHomogenic(ref trans0, ref trans1);

#if TRI_COLLISION_PROFILING
            BulletGlobals.StartProfile("GIMPACT-TRIMESH");
#endif //TRI_COLLISION_PROFILING

            FindQuantizedCollisionPairsRecursive(boxset0, boxset1, collision_pairs, ref trans_cache_1to0, 0, 0, true);
#if TRI_COLLISION_PROFILING
            BulletGlobals.StopProfile();
#endif //TRI_COLLISION_PROFILING
        }
예제 #2
0
        protected void GImpactVsGImpactFindPairs(
            ref IndexedMatrix trans0,
            ref IndexedMatrix trans1,
            GImpactShapeInterface shape0,
            GImpactShapeInterface shape1, PairSet pairset)
        {
            if (shape0.HasBoxSet() && shape1.HasBoxSet())
            {
                GImpactQuantizedBvh.FindCollision(shape0.GetBoxSet(), ref trans0, shape1.GetBoxSet(), ref trans1, pairset);
            }
            else
            {
                AABB boxshape0 = new AABB();
                AABB boxshape1 = new AABB();
                int  i         = shape0.GetNumChildShapes();

                while (i-- != 0)
                {
                    shape0.GetChildAabb(i, ref trans0, out boxshape0.m_min, out boxshape0.m_max);

                    int j = shape1.GetNumChildShapes();
                    while (j-- != 0)
                    {
                        shape1.GetChildAabb(i, ref trans1, out boxshape1.m_min, out boxshape1.m_max);

                        if (boxshape1.HasCollision(ref boxshape0))
                        {
                            pairset.PushPair(i, j);
                        }
                    }
                }
            }
#if DEBUG
            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
            {
                BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsGImpactFindPairs [{0}]", pairset.Count);
            }
#endif
        }
예제 #3
0
        public static void FindCollision(GImpactBvh boxset1, ref IndexedMatrix trans1,
                                         GImpactBvh boxset2, ref IndexedMatrix trans2,
                                         PairSet collision_pairs)
        {
            if (boxset1.GetNodeCount() == 0 || boxset2.GetNodeCount() == 0)
            {
                return;
            }

            BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0 = new BT_BOX_BOX_TRANSFORM_CACHE();

            trans_cache_1to0.CalcFromHomogenic(ref trans1, ref trans2);

#if TRI_COLLISION_PROFILING
            bt_begin_gim02_tree_time();
#endif //TRI_COLLISION_PROFILING

            FindCollisionPairsRecursive(boxset1, boxset2, collision_pairs, trans_cache_1to0, 0, 0, true);
#if TRI_COLLISION_PROFILING
            bt_end_gim02_tree_time();
#endif //TRI_COLLISION_PROFILING
        }
예제 #4
0
        public static void FindQuantizedCollisionPairsRecursive(
            GImpactQuantizedBvh boxset0, GImpactQuantizedBvh boxset1,
            PairSet collision_pairs,
            ref BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0,
            int node0, int node1, bool complete_primitive_tests)
        {
            if (QuantizedNodeCollision(
                    boxset0, boxset1, trans_cache_1to0,
                    node0, node1, complete_primitive_tests) == false)
            {
                return;                                                  //avoid colliding internal nodes
            }
            if (boxset0.IsLeafNode(node0))
            {
                if (boxset1.IsLeafNode(node1))
                {
                    // collision result
                    collision_pairs.PushPair(boxset0.GetNodeData(node0), boxset1.GetNodeData(node1));
                    return;
                }
                else
                {
                    //collide left recursive

                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        node0, boxset1.GetLeftNode(node1), false);

                    //collide right recursive
                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        node0, boxset1.GetRightNode(node1), false);
                }
            }
            else
            {
                if (boxset1.IsLeafNode(node1))
                {
                    //collide left recursive
                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        boxset0.GetLeftNode(node0), node1, false);


                    //collide right recursive

                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        boxset0.GetRightNode(node0), node1, false);
                }
                else
                {
                    //collide left0 left1



                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        boxset0.GetLeftNode(node0), boxset1.GetLeftNode(node1), false);

                    //collide left0 right1

                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        boxset0.GetLeftNode(node0), boxset1.GetRightNode(node1), false);


                    //collide right0 left1

                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        boxset0.GetRightNode(node0), boxset1.GetLeftNode(node1), false);

                    //collide right0 right1

                    FindQuantizedCollisionPairsRecursive(
                        boxset0, boxset1,
                        collision_pairs, ref trans_cache_1to0,
                        boxset0.GetRightNode(node0), boxset1.GetRightNode(node1), false);
                } // else if node1 is not a leaf
            }     // else if node0 is not a leaf
        }
        //! Collides two gimpact shapes

        /*!
         * \pre shape0 and shape1 couldn't be btGImpactMeshShape objects
         */


        public void GImpactVsGImpact(CollisionObject body0,
                                     CollisionObject body1,
                                     GImpactShapeInterface shape0,
                                     GImpactShapeInterface shape1)
        {
            if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE)
            {
                GImpactMeshShape meshshape0 = shape0 as GImpactMeshShape;
                m_part0 = meshshape0.GetMeshPartCount();

                while (m_part0-- != 0)
                {
                    GImpactVsGImpact(body0, body1, meshshape0.GetMeshPart(m_part0), shape1);
                }

                return;
            }

            if (shape1.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE)
            {
                GImpactMeshShape meshshape1 = shape1 as GImpactMeshShape;
                m_part1 = meshshape1.GetMeshPartCount();

                while (m_part1-- != 0)
                {
                    GImpactVsGImpact(body0, body1, shape0, meshshape1.GetMeshPart(m_part1));
                }

                return;
            }


            IndexedMatrix orgtrans0 = body0.GetWorldTransform();
            IndexedMatrix orgtrans1 = body1.GetWorldTransform();

            PairSet pairset = new PairSet();

            GImpactVsGImpactFindPairs(ref orgtrans0, ref orgtrans1, shape0, shape1, pairset);

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


            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
            {
                BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsGImpact [{0}]", pairset.Count);
            }

            if (shape0.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE_PART &&
                shape1.GetGImpactShapeType() == GIMPACT_SHAPE_TYPE.CONST_GIMPACT_TRIMESH_SHAPE_PART)
            {
                GImpactMeshShapePart shapepart0 = shape0 as GImpactMeshShapePart;
                GImpactMeshShapePart shapepart1 = shape1 as GImpactMeshShapePart;
                //specialized function
#if BULLET_TRIANGLE_COLLISION
                CollideGjkTriangles(body0, body1, shapepart0, shapepart1, &pairset[0].m_index1, pairset.size());
#else
                CollideSatTriangles(body0, body1, shapepart0, shapepart1, pairset, pairset.Count);
#endif

                return;
            }

            //general function

            shape0.LockChildShapes();
            shape1.LockChildShapes();

            using (GIM_ShapeRetriever retriever0 = BulletGlobals.GIM_ShapeRetrieverPool.Get())
                using (GIM_ShapeRetriever retriever1 = BulletGlobals.GIM_ShapeRetrieverPool.Get())
                {
                    retriever0.Initialize(shape0);
                    retriever1.Initialize(shape1);

                    bool child_has_transform0 = shape0.ChildrenHasTransform();
                    bool child_has_transform1 = shape1.ChildrenHasTransform();

                    int i = pairset.Count;
                    while (i-- != 0)
                    {
                        GIM_PAIR pair = pairset[i];
                        m_triface0 = pair.m_index1;
                        m_triface1 = pair.m_index2;
                        CollisionShape colshape0 = retriever0.GetChildShape(m_triface0);
                        CollisionShape colshape1 = retriever1.GetChildShape(m_triface1);

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

                        if (child_has_transform1)
                        {
                            body1.SetWorldTransform(orgtrans1 * shape1.GetChildTransform(m_triface1));
                        }

                        //collide two convex shapes
                        ConvexVsConvexCollision(body0, body1, colshape0, colshape1);


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

                        if (child_has_transform1)
                        {
                            body1.SetWorldTransform(ref orgtrans1);
                        }
                    }

                    shape0.UnlockChildShapes();
                    shape1.UnlockChildShapes();
                }
        }
        protected void CollideSatTriangles(CollisionObject body0,
                                           CollisionObject body1,
                                           GImpactMeshShapePart shape0,
                                           GImpactMeshShapePart shape1,
                                           PairSet pairs, int pair_count)
        {
            IndexedMatrix orgtrans0 = body0.GetWorldTransform();
            IndexedMatrix orgtrans1 = body1.GetWorldTransform();

            PrimitiveTriangle ptri0 = new PrimitiveTriangle();
            PrimitiveTriangle ptri1 = new PrimitiveTriangle();

            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
            {
                BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::CollideSatTriangles [{0}]", pair_count);
            }


            shape0.LockChildShapes();
            shape1.LockChildShapes();

            int pair_pointer = 0;

            while (pair_count-- != 0)
            {
                m_triface0    = pairs[pair_pointer].m_index1;
                m_triface1    = pairs[pair_pointer].m_index2;
                pair_pointer += 1;


                shape0.GetPrimitiveTriangle(m_triface0, ptri0);
                shape1.GetPrimitiveTriangle(m_triface1, ptri1);

#if TRI_COLLISION_PROFILING
                BulletGlobal.StartProfile("gim02_tri_time");
#endif

                ptri0.ApplyTransform(ref orgtrans0);
                ptri1.ApplyTransform(ref orgtrans1);


                //build planes
                ptri0.BuildTriPlane();
                ptri1.BuildTriPlane();
                // test conservative

                if (ptri0.OverlapTestConservative(ptri1))
                {
                    if (ptri0.FindTriangleCollisionClipMethod(ptri1, m_contact_data))
                    {
                        int j = m_contact_data.m_point_count;
                        while (j-- != 0)
                        {
                            AddContactPoint(body0, body1,
                                            m_contact_data.m_points[j],
                                            MathUtil.Vector4ToVector3(ref m_contact_data.m_separating_normal),
                                            -m_contact_data.m_penetration_depth);
                        }
                    }
                }

#if TRI_COLLISION_PROFILING
                BulletGlobals.StopProfile();
#endif
            }

            shape0.UnlockChildShapes();
            shape1.UnlockChildShapes();
        }