public ContinuousConvexCollision(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
 {
     m_convexA                = shapeA;
     m_convexB1               = shapeB;
     m_simplexSolver          = simplexSolver;
     m_penetrationDepthSolver = penetrationDepthSolver;
 }
 public virtual void Initialize(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
 {
     m_convexA                = shapeA;
     m_convexB1               = shapeB;
     m_simplexSolver          = simplexSolver;
     m_penetrationDepthSolver = penetrationDepthSolver;
 }
Exemple #3
0
 public ConvexConvexCreateFunc(ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver depthSolver)
 {
     m_numPerturbationIterations          = 0;
     m_minimumPointsPerturbationThreshold = 3;
     m_simplexSolver = simplexSolver;
     m_pdSolver      = depthSolver;
 }
Exemple #4
0
        }                                         // for pool

        public virtual bool CalcPenDepth(ISimplexSolverInterface simplexSolver, ConvexShape convexA, ConvexShape convexB, ref IndexedMatrix transA, ref IndexedMatrix transB,
                                         ref IndexedVector3 v, ref IndexedVector3 wWitnessOnA, ref IndexedVector3 wWitnessOnB, IDebugDraw debugDraw)
        {
            //float radialmargin = 0f;

            IndexedVector3       guessVector = (transA._origin - transB._origin);
            GjkEpaSolver2Results results     = new GjkEpaSolver2Results();

            if (GjkEpaSolver2.Penetration(convexA, ref transA,
                                          convexB, ref transB,
                                          ref guessVector, ref results))
            {
                //	debugDraw.drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
                //resultOut.addContactPoint(results.normal,results.witnesses[1],-results.depth);
                wWitnessOnA = results.witnesses0;
                wWitnessOnB = results.witnesses1;
                v           = results.normal;
                return(true);
            }
            else
            {
                if (GjkEpaSolver2.Distance(convexA, ref transA, convexB, ref transB, ref guessVector, ref results))
                {
                    wWitnessOnA = results.witnesses0;
                    wWitnessOnB = results.witnesses1;
                    v           = results.normal;
                    return(false);
                }
            }
            return(false);
        }
 public virtual void Initialize(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
 {
     m_convexA = shapeA;
     m_convexB1 = shapeB;
     m_simplexSolver = simplexSolver;
     m_penetrationDepthSolver = penetrationDepthSolver;
 }
		public ConvexConvexCreateFunc(ISimplexSolverInterface simplexSolver,IConvexPenetrationDepthSolver depthSolver)
		{
			m_numPerturbationIterations = 0;
			m_minimumPointsPerturbationThreshold =3;
			m_simplexSolver = simplexSolver;
			m_pdSolver = depthSolver;
		}
        public GjkEpaPenetrationDepthSolver() { } // for pool

        public virtual bool CalcPenDepth(ISimplexSolverInterface simplexSolver, ConvexShape convexA, ConvexShape convexB, ref IndexedMatrix transA, ref IndexedMatrix transB,
                ref IndexedVector3 v, ref IndexedVector3 wWitnessOnA, ref IndexedVector3 wWitnessOnB, IDebugDraw debugDraw)
        {
            //float radialmargin = 0f;

            IndexedVector3 guessVector = (transA._origin - transB._origin);
            GjkEpaSolver2Results results = new GjkEpaSolver2Results();
            if (GjkEpaSolver2.Penetration(convexA, ref transA,
                                        convexB, ref transB,
                                        ref guessVector, ref results))
            {
                //	debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
                //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
                wWitnessOnA = results.witnesses0;
                wWitnessOnB = results.witnesses1;
                v = results.normal;
                return true;
            }
            else
            {
                if (GjkEpaSolver2.Distance(convexA, ref transA, convexB, ref transB, ref guessVector, ref results))
                {
                    wWitnessOnA = results.witnesses0;
                    wWitnessOnB = results.witnesses1;
                    v = results.normal;
                    return false;
                }
            }
            return false;
        }
        public ContinuousConvexCollision(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
        {
            m_convexA = shapeA;
            m_convexB = shapeB;
            m_simplexSolver = simplexSolver;
            m_penetrationDepthSolver = penetrationDepthSolver;

        }
	    public Convex2dConvex2dAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold) : base(ci,body0,body1)
        {
            m_simplexSolver = simplexSolver;
            m_pdSolver = pdSolver;
            m_ownManifold = false;
            m_manifoldPtr = mf;
            m_lowLevelOfDetail = false;
            m_numPerturbationIterations = numPerturbationIterations;
            m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
        }
Exemple #10
0
 public Convex2dConvex2dAlgorithm(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold)
     : base(ci, body0, body1)
 {
     m_simplexSolver                      = simplexSolver;
     m_pdSolver                           = pdSolver;
     m_ownManifold                        = false;
     m_manifoldPtr                        = mf;
     m_lowLevelOfDetail                   = false;
     m_numPerturbationIterations          = numPerturbationIterations;
     m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
 }
    	public ConvexConvexAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold) : base(ci,body0,body1)
        {
            m_simplexSolver = simplexSolver;
            m_pdSolver = pdSolver;
            m_ownManifold = false;
            m_manifoldPtr = mf;
            m_lowLevelOfDetail = false;
            #if USE_SEPDISTANCE_UTIL2
            m_sepDistance ((static_cast<btConvexShape*>(body0.getCollisionShape())).getAngularMotionDisc(),
			  (static_cast<btConvexShape*>(body1.getCollisionShape())).getAngularMotionDisc()),
            #endif
            m_numPerturbationIterations = numPerturbationIterations;
            m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
        }
Exemple #12
0
        public void Initialize(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold)
        {
            base.Initialize(ci, body0, body1);
            m_simplexSolver    = simplexSolver;
            m_pdSolver         = pdSolver;
            m_ownManifold      = false;
            m_manifoldPtr      = mf;
            m_lowLevelOfDetail = false;
#if USE_SEPDISTANCE_UTIL2
            m_sepDistance((static_cast <btConvexShape *>(body0.getCollisionShape())).getAngularMotionDisc(),
                          (static_cast <btConvexShape *>(body1.getCollisionShape())).getAngularMotionDisc()),
#endif
            m_numPerturbationIterations          = numPerturbationIterations;
            m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
        }
Exemple #13
0
        public GjkPairDetector(ConvexShape objectA, ConvexShape objectB, BroadphaseNativeTypes shapeTypeA, BroadphaseNativeTypes shapeTypeB, float marginA, float marginB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
        {
            m_minkowskiA = objectA;
            m_minkowskiB = objectB;
            m_shapeTypeA = shapeTypeA;
            m_shapeTypeB = shapeTypeB;
            m_marginA = marginA;
            m_marginB = marginB;

            m_cachedSeparatingAxis = new Vector3(0, 1, 0);

            m_simplexSolver = simplexSolver;
            m_penetrationDepthSolver = penetrationDepthSolver;
            m_ignoreMargin = false;
            m_lastUsedMethod = -1;
            m_catchDegeneracies = true;

        }
        public void Initialize(ConvexShape objectA, ConvexShape objectB, BroadphaseNativeTypes shapeTypeA, BroadphaseNativeTypes shapeTypeB, float marginA, float marginB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
        {
            m_minkowskiA = objectA;
            m_minkowskiB = objectB;
            m_shapeTypeA = shapeTypeA;
            m_shapeTypeB = shapeTypeB;
            m_marginA    = marginA;
            m_marginB    = marginB;

            m_cachedSeparatingAxis = new IndexedVector3(0, 1, 0);

            m_simplexSolver          = simplexSolver;
            m_penetrationDepthSolver = penetrationDepthSolver;
            m_ignoreMargin           = false;
            m_lastUsedMethod         = -1;
            m_catchDegeneracies      = true;
            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGJKDetector)
            {
                BulletGlobals.g_streamWriter.WriteLine(String.Format("GjkPairDetector-alt [{0}] [{1}]", objectA.GetName(), objectB.GetName()));
            }
        }
        public void Initialize(ConvexShape objectA, ConvexShape objectB, BroadphaseNativeTypes shapeTypeA, BroadphaseNativeTypes shapeTypeB, float marginA, float marginB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
        {
            m_minkowskiA = objectA;
            m_minkowskiB = objectB;
            m_shapeTypeA = shapeTypeA;
            m_shapeTypeB = shapeTypeB;
            m_marginA = marginA;
            m_marginB = marginB;

            m_cachedSeparatingAxis = new IndexedVector3(0, 1, 0);

            m_simplexSolver = simplexSolver;
            m_penetrationDepthSolver = penetrationDepthSolver;
            m_ignoreMargin = false;
            m_lastUsedMethod = -1;
            m_catchDegeneracies = true;
            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGJKDetector)
            {
                BulletGlobals.g_streamWriter.WriteLine(String.Format("GjkPairDetector-alt [{0}] [{1}]", objectA.GetName(), objectB.GetName()));
            }

        }
 public SubSimplexConvexCast(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver)
 {
     m_convexA       = shapeA;
     m_convexB       = shapeB;
     m_simplexSolver = simplexSolver;
 }
        public bool CalcPenDepth(ISimplexSolverInterface simplexSolver, ConvexShape convexA, ConvexShape convexB, ref Matrix transA, ref Matrix transB,
                ref Vector3 v, ref Vector3 pa, ref Vector3 pb, IDebugDraw debugDraw)
        {
            bool check2d = convexA.IsConvex2D() && convexB.IsConvex2D();


            float minProj = float.MaxValue;
            Vector3 minNorm = Vector3.Zero;
            Vector3 minA = Vector3.Zero, minB = Vector3.Zero;
            Vector3 seperatingAxisInA, seperatingAxisInB;
            Vector3 pInA, qInB, pWorld, qWorld, w;

#if USE_BATCHED_SUPPORT


            IList<Vector4> supportVerticesABatch = new ObjectArray<Vector4>(NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2);
            IList<Vector4> supportVerticesBBatch = new ObjectArray<Vector4>(NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2);
            IList<Vector3> seperatingAxisInABatch = new ObjectArray<Vector3>(NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2);
            IList<Vector3> seperatingAxisInBBatch = new ObjectArray<Vector3>(NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2);


            int numSampleDirections = NUM_UNITSPHERE_POINTS;

            for (int i = 0; i < numSampleDirections; i++)
            {
                Vector3 norm = sPenetrationDirections[i];
				seperatingAxisInABatch[i] = MathUtil.TransposeTransformNormal(-norm, transA);
				seperatingAxisInBBatch[i] = MathUtil.TransposeTransformNormal(norm, transB);
            }

            {
                int numPDA = convexA.GetNumPreferredPenetrationDirections();
                if (numPDA > 0)
                {
                    for (int i = 0; i < numPDA; i++)
                    {
                        Vector3 norm = Vector3.Up;
                        convexA.GetPreferredPenetrationDirection(i, ref norm);
                        norm = Vector3.TransformNormal(norm, transA);
                        sPenetrationDirections[numSampleDirections] = norm;
                        seperatingAxisInABatch[numSampleDirections] = Vector3.TransformNormal(-norm, transA);
                        seperatingAxisInBBatch[numSampleDirections] = Vector3.Transform(norm, transB);
                        numSampleDirections++;
                    }
                }
            }

            {
                int numPDB = convexB.GetNumPreferredPenetrationDirections();
                if (numPDB > 0)
                {
                    for (int i = 0; i < numPDB; i++)
                    {
                        Vector3 norm = Vector3.Up;
                        convexB.GetPreferredPenetrationDirection(i, ref norm);
                        norm = Vector3.TransformNormal(norm, transB);
                        sPenetrationDirections[numSampleDirections] = norm;
                        seperatingAxisInABatch[numSampleDirections] = Vector3.TransformNormal(-norm, transA);
                        seperatingAxisInBBatch[numSampleDirections] = Vector3.TransformNormal(norm, transB);
                        numSampleDirections++;
                    }
                }
            }

            convexA.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch, supportVerticesABatch, numSampleDirections);
            convexB.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch, supportVerticesBBatch, numSampleDirections);

            for (int i = 0; i < numSampleDirections; i++)
            {
                Vector3 norm = sPenetrationDirections[i];
                if (check2d)
                {
                    // shouldn't this be Y ?
                    norm.Z = 0;
                }
                seperatingAxisInA = seperatingAxisInABatch[i];
                seperatingAxisInB = seperatingAxisInBBatch[i];

                pInA = new Vector3(supportVerticesABatch[i].X, supportVerticesABatch[i].Y, supportVerticesABatch[i].Z);
                qInB = new Vector3(supportVerticesBBatch[i].X, supportVerticesBBatch[i].Y, supportVerticesBBatch[i].Z);

                pWorld = Vector3.Transform(pInA, transA);
                qWorld = Vector3.Transform(qInB, transB);
                if (check2d)
                {
                    // shouldn't this be Y ?
                    pWorld.Z = 0f;
                    qWorld.Z = 0f;
                }


                w = qWorld - pWorld;
                float delta = Vector3.Dot(norm, w);
                //find smallest delta
                if (delta < minProj)
                {
                    minProj = delta;
                    minNorm = norm;
                    minA = pWorld;
                    minB = qWorld;
                }
            }
#else
            int numSampleDirections = NUM_UNITSPHERE_POINTS;

	        {
		        int numPDA = convexA.getNumPreferredPenetrationDirections();
		        if (numPDA > 0)
		        {
			        for (int i=0;i<numPDA;i++)
			        {
				        Vector3 norm = Vector3.Zero;
				        convexA.getPreferredPenetrationDirection(i,ref norm);
				        norm  = Vector3.TransformNormal(norm,transA);
				        sPenetrationDirections[numSampleDirections] = norm;
				        numSampleDirections++;
			        }
		        }
	        }

	        {
		        int numPDB = convexB.getNumPreferredPenetrationDirections();
		        if (numPDB > 0)
		        {
			        for (int i=0;i<numPDB;i++)
			        {
                        Vector3 norm = Vector3.Zero;
				        convexB.getPreferredPenetrationDirection(i,ref norm);
				        norm  = Vector3.TransformNormal(norm,transB);
				        sPenetrationDirections[numSampleDirections] = norm;
				        numSampleDirections++;
			        }
		        }
	        }

	        for (int i=0;i<numSampleDirections;i++)
	        {
		        Vector3 norm = sPenetrationDirections[i];
		        if (check2d)
		        {
			        norm.Z = 0f;
		        }
                if (norm.LengthSquared() > 0.01f)
                {
                    seperatingAxisInA = Vector3.TransformNormal(-norm, transA);
                    seperatingAxisInB = Vector3.TransformNormal(norm, transB);
                    pInA = convexA.localGetSupportVertexWithoutMarginNonVirtual(ref seperatingAxisInA);
                    qInB = convexB.localGetSupportVertexWithoutMarginNonVirtual(ref seperatingAxisInB);
                    pWorld = Vector3.Transform(pInA, transA);
                    qWorld = Vector3.Transform(qInB, transB);
                    if (check2d)
                    {
                        pWorld.Z = 0.0f;
                        qWorld.Z = 0.0f;
                    }

                    w = qWorld - pWorld;
                    float delta = Vector3.Dot(norm, w);
                    //find smallest delta
                    if (delta < minProj)
                    {
                        minProj = delta;
                        minNorm = norm;
                        minA = pWorld;
                        minB = qWorld;
                    }
                }
	        }
#endif //USE_BATCHED_SUPPORT

            //add the margins

            minA += minNorm * convexA.GetMarginNonVirtual();
            minB -= minNorm * convexB.GetMarginNonVirtual();
            //no penetration
            if (minProj < 0f)
            {
                return false;
            }

            float extraSeparation = 0.5f;///scale dependent
            minProj += extraSeparation + (convexA.GetMarginNonVirtual() + convexB.GetMarginNonVirtual());

#if DEBUG_DRAW
	        if (debugDraw)
	        {
		        Vector3 color = new Vector3(0,1,0);
		        debugDraw.drawLine(minA,minB,color);
		        color = new Vector3(1,1,1);
		        Vector3 vec = minB-minA;
		        float prj2 = Vector3.Dot(minNorm,vec);
		        debugDraw.drawLine(minA,minA+(minNorm*minProj),color);

	        }
#endif //DEBUG_DRAW



            GjkPairDetector gjkdet = new GjkPairDetector(convexA, convexB, simplexSolver, null);

            float offsetDist = minProj;
            Vector3 offset = minNorm * offsetDist;

            ClosestPointInput input = new ClosestPointInput();

            Vector3 newOrg = transA.Translation + offset;

            Matrix displacedTrans = transA;
            displacedTrans.Translation = newOrg;

            input.m_transformA = displacedTrans;
            input.m_transformB = transB;
            input.m_maximumDistanceSquared = float.MaxValue;

            MinkowskiIntermediateResult res = new MinkowskiIntermediateResult();
            Vector3 temp = -minNorm;
            gjkdet.SetCachedSeperatingAxis(-minNorm);

            gjkdet.GetClosestPoints(input, res, debugDraw,false);

            float correctedMinNorm = minProj - res.m_depth;

            //the penetration depth is over-estimated, relax it
            float penetration_relaxation = 1f;
            minNorm *= penetration_relaxation;

            if (res.m_hasResult)
            {

                pa = res.m_pointInWorld - minNorm * correctedMinNorm;
                pb = res.m_pointInWorld;
                v = minNorm;

#if DEBUG_DRAW
		        if (debugDraw != null)
		        {
			        Vector3 color = new Vector3(1,0,0);
			        debugDraw.drawLine(pa,pb,color);
		        }
#endif//DEBUG_DRAW


            }
            return res.m_hasResult;
        }
Exemple #18
0
 public void Initialize(ConvexShape convexA, ConvexShape convexB, ISimplexSolverInterface simplexSolver)
 {
     m_convexA = convexA;
     m_convexB = convexB;
     m_simplexSolver = simplexSolver;
 }
Exemple #19
0
 public GjkConvexCast() { } // for pool 
 public GjkConvexCast(ConvexShape convexA, ConvexShape convexB, ISimplexSolverInterface simplexSolver)
 {
     m_convexA = convexA;
     m_convexB = convexB;
     m_simplexSolver = simplexSolver;
 }
        public bool CalcPenDepth(ISimplexSolverInterface simplexSolver, ConvexShape convexA, ConvexShape convexB, ref IndexedMatrix transA, ref IndexedMatrix transB,
                                 ref IndexedVector3 v, ref IndexedVector3 pa, ref IndexedVector3 pb, IDebugDraw debugDraw)
        {
            bool check2d = convexA.IsConvex2d() && convexB.IsConvex2d();


            float          minProj = float.MaxValue;
            IndexedVector3 minNorm = IndexedVector3.Zero;
            IndexedVector3 minA = IndexedVector3.Zero, minB = IndexedVector3.Zero;
            IndexedVector3 seperatingAxisInA, seperatingAxisInB;
            IndexedVector3 pInA, qInB, pWorld, qWorld, w;

#if USE_BATCHED_SUPPORT
            IndexedVector4[] supportVerticesABatch  = new IndexedVector4[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];
            IndexedVector4[] supportVerticesBBatch  = new IndexedVector4[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];
            IndexedVector3[] seperatingAxisInABatch = new IndexedVector3[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];
            IndexedVector3[] seperatingAxisInBBatch = new IndexedVector3[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];


            int numSampleDirections = NUM_UNITSPHERE_POINTS;

            for (int i = 0; i < numSampleDirections; i++)
            {
                IndexedVector3 norm    = sPenetrationDirections[i];
                IndexedVector3 negNorm = -norm;

                IndexedBasisMatrix.Multiply(ref seperatingAxisInABatch[i], ref negNorm, ref transA._basis);
                IndexedBasisMatrix.Multiply(ref seperatingAxisInBBatch[i], ref norm, ref transB._basis);
                //seperatingAxisInABatch[i] = (-norm) * transA._basis;
                //seperatingAxisInBBatch[i] = norm * transB._basis;
            }

            {
                int numPDA = convexA.GetNumPreferredPenetrationDirections();
                if (numPDA > 0)
                {
                    for (int i = 0; i < numPDA; i++)
                    {
                        IndexedVector3 norm;
                        convexA.GetPreferredPenetrationDirection(i, out norm);
                        IndexedBasisMatrix.Multiply(ref norm, ref transA._basis, ref norm);
                        sPenetrationDirections[numSampleDirections] = norm;
                        IndexedVector3 negNorm = -norm;
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInABatch[numSampleDirections], ref negNorm, ref transA._basis);
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInBBatch[numSampleDirections], ref norm, ref transB._basis);
                        numSampleDirections++;
                    }
                }
            }

            {
                int numPDB = convexB.GetNumPreferredPenetrationDirections();
                if (numPDB > 0)
                {
                    for (int i = 0; i < numPDB; i++)
                    {
                        IndexedVector3 norm;
                        convexB.GetPreferredPenetrationDirection(i, out norm);
                        IndexedBasisMatrix.Multiply(ref norm, ref transB._basis, ref norm);
                        sPenetrationDirections[numSampleDirections] = norm;
                        IndexedVector3 negNorm = -norm;
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInABatch[numSampleDirections], ref negNorm, ref transA._basis);
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInBBatch[numSampleDirections], ref norm, ref transB._basis);
                        numSampleDirections++;
                    }
                }
            }

            convexA.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch, supportVerticesABatch, numSampleDirections);
            convexB.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch, supportVerticesBBatch, numSampleDirections);

            for (int i = 0; i < numSampleDirections; i++)
            {
                IndexedVector3 norm = sPenetrationDirections[i];
                if (check2d)
                {
                    // shouldn't this be Y ?
                    norm.Z = 0;
                }
                if (norm.LengthSquared() > 0.01f)
                {
                    seperatingAxisInA = seperatingAxisInABatch[i];
                    seperatingAxisInB = seperatingAxisInBBatch[i];

                    pInA = new IndexedVector3(supportVerticesABatch[i].X, supportVerticesABatch[i].Y, supportVerticesABatch[i].Z);
                    qInB = new IndexedVector3(supportVerticesBBatch[i].X, supportVerticesBBatch[i].Y, supportVerticesBBatch[i].Z);

                    IndexedMatrix.Multiply(out pWorld, ref transA, ref pInA);
                    IndexedMatrix.Multiply(out qWorld, ref transB, ref qInB);
                    if (check2d)
                    {
                        // shouldn't this be Y ?
                        pWorld.Z = 0f;
                        qWorld.Z = 0f;
                    }

                    IndexedVector3.Subtract(out w, ref qWorld, ref pWorld);
                    float delta = IndexedVector3.Dot(ref norm, ref w);
                    //find smallest delta
                    if (delta < minProj)
                    {
                        minProj = delta;
                        minNorm = norm;
                        minA    = pWorld;
                        minB    = qWorld;
                    }
                }
            }
#else
            int numSampleDirections = NUM_UNITSPHERE_POINTS;

            {
                int numPDA = convexA.GetNumPreferredPenetrationDirections();
                if (numPDA > 0)
                {
                    for (int i = 0; i < numPDA; i++)
                    {
                        IndexedVector3 norm;
                        convexA.GetPreferredPenetrationDirection(i, out norm);
                        norm = IndexedVector3.TransformNormal(norm, transA);
                        sPenetrationDirections[numSampleDirections] = norm;
                        numSampleDirections++;
                    }
                }
            }

            {
                int numPDB = convexB.GetNumPreferredPenetrationDirections();
                if (numPDB > 0)
                {
                    for (int i = 0; i < numPDB; i++)
                    {
                        IndexedVector3 norm = IndexedVector3.Zero;
                        convexB.GetPreferredPenetrationDirection(i, out norm);
                        norm = IndexedVector3.TransformNormal(norm, transB);
                        sPenetrationDirections[numSampleDirections] = norm;
                        numSampleDirections++;
                    }
                }
            }

            for (int i = 0; i < numSampleDirections; i++)
            {
                IndexedVector3 norm = sPenetrationDirections[i];
                if (check2d)
                {
                    norm.Z = 0f;
                }
                if (norm.LengthSquared() > 0.01f)
                {
                    seperatingAxisInA = IndexedVector3.TransformNormal(-norm, transA);
                    seperatingAxisInB = IndexedVector3.TransformNormal(norm, transB);
                    pInA   = convexA.LocalGetSupportVertexWithoutMarginNonVirtual(ref seperatingAxisInA);
                    qInB   = convexB.LocalGetSupportVertexWithoutMarginNonVirtual(ref seperatingAxisInB);
                    pWorld = IndexedVector3.Transform(pInA, transA);
                    qWorld = IndexedVector3.Transform(qInB, transB);
                    if (check2d)
                    {
                        pWorld.Z = 0.0f;
                        qWorld.Z = 0.0f;
                    }

                    w = qWorld - pWorld;
                    float delta = IndexedVector3.Dot(norm, w);
                    //find smallest delta
                    if (delta < minProj)
                    {
                        minProj = delta;
                        minNorm = norm;
                        minA    = pWorld;
                        minB    = qWorld;
                    }
                }
            }
#endif //USE_BATCHED_SUPPORT

            //add the margins

            minA += minNorm * convexA.GetMarginNonVirtual();
            minB -= minNorm * convexB.GetMarginNonVirtual();
            //no penetration
            if (minProj < 0f)
            {
                return(false);
            }

            float extraSeparation = 0.5f;///scale dependent
            minProj += extraSeparation + (convexA.GetMarginNonVirtual() + convexB.GetMarginNonVirtual());

#if DEBUG_DRAW
            if (debugDraw)
            {
                IndexedVector3 color = new IndexedVector3(0, 1, 0);
                debugDraw.drawLine(minA, minB, color);
                color = new IndexedVector3(1, 1, 1);
                IndexedVector3 vec  = minB - minA;
                float          prj2 = IndexedVector3.Dot(minNorm, vec);
                debugDraw.drawLine(minA, minA + (minNorm * minProj), color);
            }
#endif //DEBUG_DRAW



            GjkPairDetector gjkdet = BulletGlobals.GjkPairDetectorPool.Get();
            gjkdet.Initialize(convexA, convexB, simplexSolver, null);

            float          offsetDist = minProj;
            IndexedVector3 offset     = minNorm * offsetDist;

            ClosestPointInput input = ClosestPointInput.Default();

            IndexedVector3 newOrg = transA._origin + offset;

            IndexedMatrix displacedTrans = transA;
            displacedTrans._origin = newOrg;

            input.m_transformA             = displacedTrans;
            input.m_transformB             = transB;
            input.m_maximumDistanceSquared = float.MaxValue;

            MinkowskiIntermediateResult res = new MinkowskiIntermediateResult();
            gjkdet.SetCachedSeperatingAxis(-minNorm);

            gjkdet.GetClosestPoints(ref input, res, debugDraw, false);

            float correctedMinNorm = minProj - res.m_depth;

            //the penetration depth is over-estimated, relax it
            float penetration_relaxation = 1f;
            minNorm *= penetration_relaxation;

            if (res.m_hasResult)
            {
                pa = res.m_pointInWorld - minNorm * correctedMinNorm;
                pb = res.m_pointInWorld;
                v  = minNorm;

#if DEBUG_DRAW
                if (debugDraw != null)
                {
                    IndexedVector3 color = new IndexedVector3(1, 0, 0);
                    debugDraw.drawLine(pa, pb, color);
                }
#endif//DEBUG_DRAW
            }

            BulletGlobals.GjkPairDetectorPool.Free(gjkdet);
            return(res.m_hasResult);
        }
        }                          // for pool

        public GjkConvexCast(ConvexShape convexA, ConvexShape convexB, ISimplexSolverInterface simplexSolver)
        {
            m_convexA       = convexA;
            m_convexB       = convexB;
            m_simplexSolver = simplexSolver;
        }
        }                            // for pool

        public GjkPairDetector(ConvexShape objectA, ConvexShape objectB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
        {
            Initialize(objectA, objectB, simplexSolver, penetrationDepthSolver);
        }
        public bool CalcPenDepth(ISimplexSolverInterface simplexSolver, ConvexShape convexA, ConvexShape convexB, ref IndexedMatrix transA, ref IndexedMatrix transB,
                ref IndexedVector3 v, ref IndexedVector3 pa, ref IndexedVector3 pb, IDebugDraw debugDraw)
        {
            bool check2d = convexA.IsConvex2d() && convexB.IsConvex2d();


            float minProj = float.MaxValue;
            IndexedVector3 minNorm = IndexedVector3.Zero;
            IndexedVector3 minA = IndexedVector3.Zero, minB = IndexedVector3.Zero;
            IndexedVector3 seperatingAxisInA, seperatingAxisInB;
            IndexedVector3 pInA, qInB, pWorld, qWorld, w;

#if USE_BATCHED_SUPPORT


            IndexedVector4[] supportVerticesABatch = new IndexedVector4[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];
            IndexedVector4[] supportVerticesBBatch = new IndexedVector4[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];
            IndexedVector3[] seperatingAxisInABatch = new IndexedVector3[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];
            IndexedVector3[] seperatingAxisInBBatch = new IndexedVector3[NUM_UNITSPHERE_POINTS + ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS * 2];


            int numSampleDirections = NUM_UNITSPHERE_POINTS;

            for (int i = 0; i < numSampleDirections; i++)
            {
                IndexedVector3 norm = sPenetrationDirections[i];
                IndexedVector3 negNorm = -norm;

                IndexedBasisMatrix.Multiply(ref seperatingAxisInABatch[i], ref negNorm, ref transA._basis);
                IndexedBasisMatrix.Multiply(ref seperatingAxisInBBatch[i], ref norm, ref transB._basis);
                //seperatingAxisInABatch[i] = (-norm) * transA._basis;
                //seperatingAxisInBBatch[i] = norm * transB._basis;
            }

            {
                int numPDA = convexA.GetNumPreferredPenetrationDirections();
                if (numPDA > 0)
                {
                    for (int i = 0; i < numPDA; i++)
                    {
                        IndexedVector3 norm;
                        convexA.GetPreferredPenetrationDirection(i, out norm);
                        IndexedBasisMatrix.Multiply(ref norm ,ref transA._basis ,ref norm);
                        sPenetrationDirections[numSampleDirections] = norm;
                        IndexedVector3 negNorm = -norm;
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInABatch[numSampleDirections], ref negNorm,ref transA._basis);
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInBBatch[numSampleDirections] ,ref norm ,ref transB._basis);
                        numSampleDirections++;
                    }
                }
            }

            {
                int numPDB = convexB.GetNumPreferredPenetrationDirections();
                if (numPDB > 0)
                {
                    for (int i = 0; i < numPDB; i++)
                    {
                        IndexedVector3 norm;
                        convexB.GetPreferredPenetrationDirection(i, out norm);
                        IndexedBasisMatrix.Multiply(ref norm, ref transB._basis, ref norm);
                        sPenetrationDirections[numSampleDirections] = norm;
                        IndexedVector3 negNorm = -norm;
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInABatch[numSampleDirections],ref negNorm,ref transA._basis);
                        IndexedBasisMatrix.Multiply(ref seperatingAxisInBBatch[numSampleDirections],ref norm ,ref transB._basis);
                        numSampleDirections++;
                    }
                }
            }

            convexA.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch, supportVerticesABatch, numSampleDirections);
            convexB.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch, supportVerticesBBatch, numSampleDirections);

            for (int i = 0; i < numSampleDirections; i++)
            {
                IndexedVector3 norm = sPenetrationDirections[i];
                if (check2d)
                {
                    // shouldn't this be Y ?
                    norm.Z = 0;
                }
                if (norm.LengthSquared() > 0.01f)
                {
                    seperatingAxisInA = seperatingAxisInABatch[i];
                    seperatingAxisInB = seperatingAxisInBBatch[i];

                    pInA = new IndexedVector3(supportVerticesABatch[i].X, supportVerticesABatch[i].Y, supportVerticesABatch[i].Z);
                    qInB = new IndexedVector3(supportVerticesBBatch[i].X, supportVerticesBBatch[i].Y, supportVerticesBBatch[i].Z);

                    IndexedMatrix.Multiply(out  pWorld, ref transA, ref pInA);
                    IndexedMatrix.Multiply(out  qWorld, ref transB, ref qInB);
                    if (check2d)
                    {
                        // shouldn't this be Y ?
                        pWorld.Z = 0f;
                        qWorld.Z = 0f;
                    }

                    IndexedVector3.Subtract(out w, ref qWorld, ref pWorld);
                    float delta = IndexedVector3.Dot(ref norm, ref w);
                    //find smallest delta
                    if (delta < minProj)
                    {
                        minProj = delta;
                        minNorm = norm;
                        minA = pWorld;
                        minB = qWorld;
                    }
                }
            }
#else
            int numSampleDirections = NUM_UNITSPHERE_POINTS;

	        {
		        int numPDA = convexA.GetNumPreferredPenetrationDirections();
		        if (numPDA > 0)
		        {
			        for (int i=0;i<numPDA;i++)
			        {
				        IndexedVector3 norm;
				        convexA.GetPreferredPenetrationDirection(i, out norm);
				        norm  = IndexedVector3.TransformNormal(norm,transA);
				        sPenetrationDirections[numSampleDirections] = norm;
				        numSampleDirections++;
			        }
		        }
	        }

	        {
		        int numPDB = convexB.GetNumPreferredPenetrationDirections();
		        if (numPDB > 0)
		        {
			        for (int i=0;i<numPDB;i++)
			        {
                        IndexedVector3 norm = IndexedVector3.Zero;
				        convexB.GetPreferredPenetrationDirection(i, out norm);
				        norm  = IndexedVector3.TransformNormal(norm,transB);
				        sPenetrationDirections[numSampleDirections] = norm;
				        numSampleDirections++;
			        }
		        }
	        }

	        for (int i=0;i<numSampleDirections;i++)
	        {
		        IndexedVector3 norm = sPenetrationDirections[i];
		        if (check2d)
		        {
			        norm.Z = 0f;
		        }
                if (norm.LengthSquared() > 0.01f)
                {
                    seperatingAxisInA = IndexedVector3.TransformNormal(-norm, transA);
                    seperatingAxisInB = IndexedVector3.TransformNormal(norm, transB);
                    pInA = convexA.LocalGetSupportVertexWithoutMarginNonVirtual(ref seperatingAxisInA);
                    qInB = convexB.LocalGetSupportVertexWithoutMarginNonVirtual(ref seperatingAxisInB);
                    pWorld = IndexedVector3.Transform(pInA, transA);
                    qWorld = IndexedVector3.Transform(qInB, transB);
                    if (check2d)
                    {
                        pWorld.Z = 0.0f;
                        qWorld.Z = 0.0f;
                    }

                    w = qWorld - pWorld;
                    float delta = IndexedVector3.Dot(norm, w);
                    //find smallest delta
                    if (delta < minProj)
                    {
                        minProj = delta;
                        minNorm = norm;
                        minA = pWorld;
                        minB = qWorld;
                    }
                }
	        }
#endif //USE_BATCHED_SUPPORT

            //add the margins

            minA += minNorm * convexA.GetMarginNonVirtual();
            minB -= minNorm * convexB.GetMarginNonVirtual();
            //no penetration
            if (minProj < 0f)
            {
                return false;
            }

            float extraSeparation = 0.5f;///scale dependent
            minProj += extraSeparation + (convexA.GetMarginNonVirtual() + convexB.GetMarginNonVirtual());

#if DEBUG_DRAW
	        if (debugDraw)
	        {
		        IndexedVector3 color = new IndexedVector3(0,1,0);
		        debugDraw.drawLine(minA,minB,color);
		        color = new IndexedVector3(1,1,1);
		        IndexedVector3 vec = minB-minA;
		        float prj2 = IndexedVector3.Dot(minNorm,vec);
		        debugDraw.drawLine(minA,minA+(minNorm*minProj),color);

	        }
#endif //DEBUG_DRAW



            GjkPairDetector gjkdet = BulletGlobals.GjkPairDetectorPool.Get();
            gjkdet.Initialize(convexA, convexB, simplexSolver, null);

            float offsetDist = minProj;
            IndexedVector3 offset = minNorm * offsetDist;

            ClosestPointInput input = ClosestPointInput.Default();

            IndexedVector3 newOrg = transA._origin + offset;

            IndexedMatrix displacedTrans = transA;
            displacedTrans._origin = newOrg;

            input.m_transformA = displacedTrans;
            input.m_transformB = transB;
            input.m_maximumDistanceSquared = float.MaxValue;

            MinkowskiIntermediateResult res = new MinkowskiIntermediateResult();
            gjkdet.SetCachedSeperatingAxis(-minNorm);

            gjkdet.GetClosestPoints(ref input, res, debugDraw, false);

            float correctedMinNorm = minProj - res.m_depth;

            //the penetration depth is over-estimated, relax it
            float penetration_relaxation = 1f;
            minNorm *= penetration_relaxation;

            if (res.m_hasResult)
            {

                pa = res.m_pointInWorld - minNorm * correctedMinNorm;
                pb = res.m_pointInWorld;
                v = minNorm;

#if DEBUG_DRAW
		        if (debugDraw != null)
		        {
			        IndexedVector3 color = new IndexedVector3(1,0,0);
			        debugDraw.drawLine(pa,pb,color);
		        }
#endif//DEBUG_DRAW


            }

            BulletGlobals.GjkPairDetectorPool.Free(gjkdet);
            return res.m_hasResult;
        }
        public GjkPairDetector() { } // for pool

        public GjkPairDetector(ConvexShape objectA, ConvexShape objectB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
        {
            Initialize(objectA, objectB, simplexSolver, penetrationDepthSolver);
        }
 public SubSimplexConvexCast (ConvexShape shapeA,ConvexShape shapeB,ISimplexSolverInterface simplexSolver)
 {
     m_convexA = shapeA;
     m_convexB = shapeB;
     m_simplexSolver = simplexSolver;
 }
 public void Initialize(ConvexShape convexA, ConvexShape convexB, ISimplexSolverInterface simplexSolver)
 {
     m_convexA       = convexA;
     m_convexB       = convexB;
     m_simplexSolver = simplexSolver;
 }
 public void Initialize(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver)
 {
     m_convexA       = shapeA;
     m_convexB       = shapeB;
     m_simplexSolver = simplexSolver;
 }
 public GjkPairDetector(ConvexShape objectA, ConvexShape objectB, BroadphaseNativeTypes shapeTypeA, BroadphaseNativeTypes shapeTypeB, float marginA, float marginB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
 {
     Initialize(objectA, objectB, shapeTypeA, shapeTypeB, marginA, marginB, simplexSolver, penetrationDepthSolver);
 }
 public void Initialize(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolverInterface simplexSolver)
 {
     m_convexA = shapeA;
     m_convexB = shapeB;
     m_simplexSolver = simplexSolver;
 }
 public GjkPairDetector(ConvexShape objectA, ConvexShape objectB, BroadphaseNativeTypes shapeTypeA, BroadphaseNativeTypes shapeTypeB, float marginA, float marginB, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
 {
     Initialize(objectA, objectB, shapeTypeA, shapeTypeB, marginA, marginB, simplexSolver,penetrationDepthSolver);
 }