void OBBMeshQuery::PerformTest()
{
	RenderTerrain();

	Matrix3x3 MX,MY,MZ;
	RotX(MX, mAngleX);
	RotY(MY, mAngleY);
	RotY(MZ, mAngleZ);
	mBox.mRot = MX * MY * MZ;

	DrawOBB(mBox);

	const Model* TM = GetTerrainModel();
	if(TM)
	{
		OBBCollider Collider;
		mSettings.SetupCollider(Collider);

		mProfiler.Start();
		bool Status = Collider.Collide(mCache, mBox, *TM, null, null);
		mProfiler.End();
		mProfiler.Accum();

		if(Status)
		{
			if(Collider.GetContactStatus())
			{
				udword NbTris = Collider.GetNbTouchedPrimitives();
				const udword* Indices = Collider.GetTouchedPrimitives();

				RenderTerrainTriangles(NbTris, Indices);
			}
		}
	}

	// Raycast hit
	if(mValidHit)
	{
		Point wp = mLocalHit + mBox.mCenter;
		DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f);
		DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f);
		DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f);
	}

	char Buffer[4096];
	sprintf(Buffer, "OBB-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles);
	GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
}
static void dQueryCCTLPotentialCollisionTriangles(OBBCollider &Collider, 
                                                  const sTrimeshCapsuleColliderData &cData, dxTriMesh *TriMesh, dxGeom *Capsule,
                                                  OBBCache &BoxCache)
{
    // It is a potential issue to explicitly cast to float 
    // if custom width floating point type is introduced in OPCODE.
    // It is necessary to make a typedef and cast to it
    // (e.g. typedef float opc_float;)
    // However I'm not sure in what header it should be added.

    const dVector3 &vCapsulePosition = cData.m_vCapsulePosition;

    Point cCenter(/*(float)*/ vCapsulePosition[0], /*(float)*/ vCapsulePosition[1], /*(float)*/ vCapsulePosition[2]);
    Point cExtents(/*(float)*/ cData.m_vCapsuleRadius, /*(float)*/ cData.m_vCapsuleRadius,/*(float)*/ cData.m_fCapsuleSize/2);

    Matrix3x3 obbRot;

    const dMatrix3 &mCapsuleRotation = cData.m_mCapsuleRotation;

    obbRot[0][0] = /*(float)*/ mCapsuleRotation[0];
    obbRot[1][0] = /*(float)*/ mCapsuleRotation[1];
    obbRot[2][0] = /*(float)*/ mCapsuleRotation[2];

    obbRot[0][1] = /*(float)*/ mCapsuleRotation[4];
    obbRot[1][1] = /*(float)*/ mCapsuleRotation[5];
    obbRot[2][1] = /*(float)*/ mCapsuleRotation[6];

    obbRot[0][2] = /*(float)*/ mCapsuleRotation[8];
    obbRot[1][2] = /*(float)*/ mCapsuleRotation[9];
    obbRot[2][2] = /*(float)*/ mCapsuleRotation[10];

    OBB obbCapsule(cCenter,cExtents,obbRot);

    Matrix4x4 CapsuleMatrix;
    MakeMatrix(vCapsulePosition, mCapsuleRotation, CapsuleMatrix);

    Matrix4x4 MeshMatrix;
    MakeMatrix(cData.m_mTriMeshPos, cData.m_mTriMeshRot, MeshMatrix);

    // TC results
    if (TriMesh->doBoxTC) {
        dxTriMesh::BoxTC* BoxTC = 0;
        for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){
            if (TriMesh->BoxTCCache[i].Geom == Capsule){
                BoxTC = &TriMesh->BoxTCCache[i];
                break;
            }
        }
        if (!BoxTC){
            TriMesh->BoxTCCache.push(dxTriMesh::BoxTC());

            BoxTC = &TriMesh->BoxTCCache[TriMesh->BoxTCCache.size() - 1];
            BoxTC->Geom = Capsule;
            BoxTC->FatCoeff = 1.0f;
        }

        // Intersect
        Collider.SetTemporalCoherence(true);
        Collider.Collide(*BoxTC, obbCapsule, TriMesh->Data->BVTree, null, &MeshMatrix);
    }
    else {
        Collider.SetTemporalCoherence(false);
        Collider.Collide(BoxCache, obbCapsule, TriMesh->Data->BVTree, null,&MeshMatrix);
    }
}