예제 #1
0
// Cylinder - Box by CroTeam
// Ported by Nguyen Binh
int dCollideCylinderBox(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip)
{
	sCylinderBoxData	cData;

	// Assign ODE stuff
	cData.gCylinder = o1;
	cData.gBox		= o2;
	cData.iFlags	= flags;
	cData.iSkip		= skip;
	cData.gContact	= contact;

	// initialize collider
	_cldInitCylinderBox( cData );

	// do intersection test and find best separating axis
	if(!_cldTestSeparatingAxes( cData ) ) 
	{
		// if not found do nothing
		return 0;
	}

	// if best separation axis is not found
	if ( cData.iBestAxis == 0 ) 
	{
		// this should not happen (we should already exit in that case)
		dIASSERT(0);
		// do nothing
		return 0;
	}

	dReal fdot = dVector3Dot(cData.vNormal,cData.vCylinderAxis);
	// choose which clipping method are we going to apply
	if (dFabs(fdot) < REAL(0.9) ) 
	{
		// clip cylinder over box
		if(!_cldClipCylinderToBox(cData)) 
		{
			return 0;
		}
	} 
	else 
	{
		_cldClipBoxToCylinder(cData);  
	}

	return cData.nContacts;
}
int sCylinderBoxData::PerformCollisionChecking()
{
	// initialize collider
	_cldInitCylinderBox();

	// do intersection test and find best separating axis
	if ( !_cldTestSeparatingAxes() ) 
	{
		// if not found do nothing
		return 0;
	}

	// if best separation axis is not found
	if ( m_iBestAxis == 0 ) 
	{
		// this should not happen (we should already exit in that case)
		dIASSERT(0);
		// do nothing
		return 0;
	}

	dReal fdot = dVector3Dot(m_vNormal,m_vCylinderAxis);
	// choose which clipping method are we going to apply
	if (dFabs(fdot) < REAL(0.9) ) 
	{
		// clip cylinder over box
		if(!_cldClipCylinderToBox()) 
		{
			return 0;
		}
	} 
	else 
	{
		_cldClipBoxToCylinder();  
	}

	return m_nContacts;
}
void TestOneTriangleVsCylinder(   sData& cData,
                                  const dVector3 &v0,
                                  const dVector3 &v1,
                                  const dVector3 &v2,
                                  const bool bDoubleSided)
{

    // calculate triangle normal
    dVector3Subtract( v2 , v1 ,cData.vE1);
    dVector3 vTemp;
    dVector3Subtract( v0 , v1 ,vTemp);
    dVector3Cross(cData.vE1 , vTemp , cData.vNormal );

    dNormalize3( cData.vNormal);

    // create plane from triangle
    //Plane4f plTrianglePlane = Plane4f( vPolyNormal, v0 );
    dReal plDistance = -dVector3Dot(v0, cData.vNormal);
    dVector4 plTrianglePlane;
    dConstructPlane( cData.vNormal,plDistance,plTrianglePlane);

    // calculate sphere distance to plane
    dReal fDistanceCylinderCenterToPlane = dPointPlaneDistance(cData.vCylinderPos , plTrianglePlane);

    // Sphere must be over positive side of triangle
    if(fDistanceCylinderCenterToPlane < 0 && !bDoubleSided)
    {
        // if not don't generate contacts
        return;
    }

    dVector3 vPnt0;
    dVector3 vPnt1;
    dVector3 vPnt2;

    if (fDistanceCylinderCenterToPlane < REAL(0.0) )
    {
        // flip it
        dVector3Copy(v0 , vPnt0);
        dVector3Copy(v1 , vPnt2);
        dVector3Copy(v2 , vPnt1);
    }
    else
    {
        dVector3Copy(v0 , vPnt0);
        dVector3Copy(v1 , vPnt1);
        dVector3Copy(v2 , vPnt2);
    }

    cData.fBestDepth = MAX_REAL;

    // do intersection test and find best separating axis
    if(!_cldTestSeparatingAxes(cData , vPnt0, vPnt1, vPnt2) )
    {
        // if not found do nothing
        return;
    }

    // if best separation axis is not found
    if ( cData.iBestAxis == 0 )
    {
        // this should not happen (we should already exit in that case)
        dIASSERT(false);
        // do nothing
        return;
    }

    dReal fdot = dVector3Dot( cData.vContactNormal , cData.vCylinderAxis );

    // choose which clipping method are we going to apply
    if (dFabs(fdot) < REAL(0.9) )
    {
        if (!_cldClipCylinderEdgeToTriangle(cData ,vPnt0, vPnt1, vPnt2))
        {
            return;
        }
    }
    else
    {
        _cldClipCylinderToTriangle(cData ,vPnt0, vPnt1, vPnt2);
    }

}