//! 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();
                }
        }
        public void GImpactVsShape(CollisionObject body0,
                                   CollisionObject body1,
                                   GImpactShapeInterface shape0,
                                   CollisionShape shape1, bool swapped)
        {
            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
            {
                BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsShape");
            }


            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 (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactAlgo)
                {
                    BulletGlobals.g_streamWriter.WriteLine("GImpactAglo::GImpactVsShape [{0}]", collided_results.Count);
                }


                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();
            }
        }
Пример #3
0
        public void InitGImpactCollision()
        {

            /// Create Torus Shape
            {
                m_indexVertexArrays = new TriangleIndexVertexArray(DemoMeshes.TORUS_NUM_TRIANGLES, DemoMeshes.gTorusIndices, 3, DemoMeshes.TORUS_NUM_VERTICES, DemoMeshes.gTorusVertices, 3);

#if BULLET_GIMPACT_CONVEX_DECOMPOSITION
			btGImpactConvexDecompositionShape * trimesh  = new
			btGImpactConvexDecompositionShape(
			m_indexVertexArrays, IndexedVector3(1.f,1.f,1.f),btScalar(0.01));
			trimesh->setMargin(0.07);
			trimesh->updateBound();


#else
                //GImpactMeshShape trimesh = new GImpactMeshShape(m_indexVertexArrays);
                //IndexedVector3 scaling = IndexedVector3.One;
                //trimesh.SetLocalScaling(ref scaling);
                //trimesh.SetMargin(0.07f); ///?????
                //trimesh.UpdateBound();
#endif

                //m_trimeshShape = trimesh;

            }

            /// Create Bunny Shape
            {
                m_indexVertexArrays2 = new TriangleIndexVertexArray(DemoMeshes.BUNNY_NUM_TRIANGLES, DemoMeshes.gBunnyIndices, 3, DemoMeshes.BUNNY_NUM_VERTICES, DemoMeshes.gBunnyVertices, 3);
#if BULLET_GIMPACT_CONVEX_DECOMPOSITION
			btGImpactConvexDecompositionShape * trimesh2  = new
			btGImpactConvexDecompositionShape(
			m_indexVertexArrays2, IndexedVector3(4.f,4.f,4.f),btScalar(0.01));
			trimesh2->setMargin(0.07);
			trimesh2->updateBound();
#else
                GImpactMeshShape trimesh2 = new GImpactMeshShape(m_indexVertexArrays2);
                IndexedVector3 scaling = new IndexedVector3(4.0f, 4.0f, 4.0f);
                trimesh2.SetLocalScaling(ref scaling);
                //trimesh2.SetMargin(0.07f); ///?????
                trimesh2.UpdateBound();
#endif
                m_trimeshShape2 = trimesh2;

            }


            ///register GIMPACT algorithm
            CollisionDispatcher dispatcher = m_dynamicsWorld.GetDispatcher() as CollisionDispatcher;

            GImpactCollisionAlgorithm.RegisterAlgorithm(dispatcher);
        }