bool IntrSphere3Sphere3x::Test (fixed fTMax,
    const Vector3x& rkVelocity0, const Vector3x& rkVelocity1)
{
    Vector3x kVDiff = rkVelocity1 - rkVelocity0;
    fixed fA = kVDiff.SquaredLength();
    Vector3x kCDiff = m_rkSphere1.Center - m_rkSphere0.Center;
    fixed fC = kCDiff.SquaredLength();
    fixed fRSum = m_rkSphere0.Radius + m_rkSphere1.Radius;
    fixed fRSumSqr = fRSum*fRSum;

    if (fA > FIXED_ZERO)
    {
        fixed fB = kCDiff.Dot(kVDiff);
        if (fB <= FIXED_ZERO)
        {
            if (-fTMax*fA <= fB)
            {
                return fA*fC - fB*fB <= fA*fRSumSqr;
            }
            else
            {
                return fTMax*(fTMax*fA + FixedFromFloat((float)2.0)*fB) + fC <= fRSumSqr;
            }
        }
    }

    return fC <= fRSumSqr;
}
Example #2
0
void Matrix2x::EigenDecomposition (Matrix2x& rkRot, Matrix2x& rkDiag) const
{
    fixed fTrace = m_afEntry[0] + m_afEntry[3];
    fixed fDiff = m_afEntry[0] - m_afEntry[3];
    fixed fDiscr = Mathx::Sqrt(fDiff*fDiff +
        FixedFromFloat((float)4.0)*m_afEntry[1]*m_afEntry[1]);
    fixed fEVal0 = FIXED_HALF*(fTrace-fDiscr);
    fixed fEVal1 = FIXED_HALF*(fTrace+fDiscr);
    rkDiag.MakeDiagonal(fEVal0,fEVal1);

    fixed fCos, fSin;
    if (fDiff >= FIXED_ZERO)
    {
        fCos = m_afEntry[1];
        fSin = fEVal0 - m_afEntry[0];
    }
    else
    {
        fCos = fEVal0 - m_afEntry[3];
        fSin = m_afEntry[1];
    }
    fixed fTmp = Mathx::InvSqrt(fCos*fCos + fSin*fSin);
    fCos *= fTmp;
    fSin *= fTmp;

    rkRot.m_afEntry[0] = fCos;
    rkRot.m_afEntry[1] = -fSin;
    rkRot.m_afEntry[2] = fSin;
    rkRot.m_afEntry[3] = fCos;
}
Example #3
0
Sphere3x MergeSpheres (const Sphere3x& rkSphere0,
							const Sphere3x& rkSphere1)
{
    Vector3x kCDiff = rkSphere1.Center - rkSphere0.Center;
    fixed fLSqr = kCDiff.SquaredLength();
    fixed fRDiff = rkSphere1.Radius - rkSphere0.Radius;
    fixed fRDiffSqr = fRDiff*fRDiff;
	
    if (fRDiffSqr >= fLSqr)
    {
        return (fRDiff >= FIXED_ZERO ? rkSphere1 : rkSphere0);
    }
	
    fixed fLength = Mathx::Sqrt(fLSqr);
    Sphere3x kSphere;
	
    if (fLength > Mathx::ZERO_TOLERANCE)
    {
        fixed fCoeff = (fLength + fRDiff)/(FixedFromFloat((float)2.0)*fLength);
        kSphere.Center = rkSphere0.Center + fCoeff*kCDiff;
    }
    else
    {
        kSphere.Center = rkSphere0.Center;
    }
	
    kSphere.Radius = (FIXED_HALF)*(fLength + rkSphere0.Radius +
        rkSphere1.Radius);
	
    return kSphere;
}
static bool FillGlyphDimensions(HDC hDC, const TEXTMETRICW& TextMetric, CTextureStringGlyph* pGlyphs, uint32 nNumGlyphs)
{
	// Setup the transform for the glyph.  Just use identity.
	MAT2 mat;
	mat.eM11 = FixedFromFloat( 1.0f );
	mat.eM12 = FixedFromFloat( 0.0f );
	mat.eM21 = FixedFromFloat( 0.0f );
	mat.eM22 = FixedFromFloat( 1.0f );

	//determine if this is a truetype font or not
	bool bTrueType = (TextMetric.tmPitchAndFamily & TMPF_TRUETYPE) != 0;

	// Get the individual widths of all chars in font, indexed by character values.
	GLYPHMETRICS GlyphMetrics;
	memset( &GlyphMetrics, 0, sizeof( GlyphMetrics ) );

	for( uint32 nCurrGlyph = 0; nCurrGlyph < nNumGlyphs; nCurrGlyph++ )
	{
		// Get the character for this glyph.
		CTextureStringGlyph& Glyph = pGlyphs[nCurrGlyph];

		if(bTrueType)
		{
			// Get the glyph metrics for this glyph.
			if( GDI_ERROR == GetGlyphOutlineW( hDC, Glyph.m_cGlyph, GGO_METRICS, &GlyphMetrics, 0, NULL, &mat ))
			{
				// Use the default character on anything that has issues.
				if( GDI_ERROR == GetGlyphOutlineW( hDC, TextMetric.tmDefaultChar, GGO_METRICS, &GlyphMetrics, 0, NULL, &mat ))
				{
					return false;
				}
			}

			//we have the glyph outline, so we now need to convert the data from that over to the glyph data
			//format
			Glyph.m_nTotalWidth			= GlyphMetrics.gmCellIncX;

			Glyph.m_rBlackBox.Left()	= GlyphMetrics.gmptGlyphOrigin.x;
			Glyph.m_rBlackBox.Top()		= TextMetric.tmAscent - GlyphMetrics.gmptGlyphOrigin.y;

			Glyph.m_rBlackBox.Right()	= Glyph.m_rBlackBox.Left() + GlyphMetrics.gmBlackBoxX + 1;
			Glyph.m_rBlackBox.Bottom()	= Glyph.m_rBlackBox.Top()  + GlyphMetrics.gmBlackBoxY + 1;
		}
		else
		{
			//this is not a truetype font, so we have to use a different approach for getting the glyph
			//sizes
			INT nWidth = 0;
			if(!GetCharWidth32W(hDC, Glyph.m_cGlyph, Glyph.m_cGlyph, &nWidth))
			{
				if(!GetCharWidth32W(hDC, TextMetric.tmDefaultChar, TextMetric.tmDefaultChar, &nWidth))
				{
					return false;
				}
			}

			//setup our character from that information
			Glyph.m_nTotalWidth			= nWidth;

			Glyph.m_rBlackBox.Left()	= 0;
			Glyph.m_rBlackBox.Top()		= 0;

			Glyph.m_rBlackBox.Right()	= nWidth;
			Glyph.m_rBlackBox.Bottom()	= TextMetric.tmHeight;
		}
	}

	//success
	return true;
}
bool IntrSphere3Sphere3x::Find (fixed fTMax,
    const Vector3x& rkVelocity0, const Vector3x& rkVelocity1)
{
    Vector3x kVDiff = rkVelocity1 - rkVelocity0;
    fixed fA = kVDiff.SquaredLength();
    Vector3x kCDiff = m_rkSphere1.Center - m_rkSphere0.Center;
    fixed fC = kCDiff.SquaredLength();
    fixed fRSum = m_rkSphere0.Radius + m_rkSphere1.Radius;
    fixed fRSumSqr = fRSum*fRSum;

    if (fA > FIXED_ZERO)
    {
        fixed fB = kCDiff.Dot(kVDiff);
        if (fB <= FIXED_ZERO)
        {
            if (-fTMax*fA <= fB
            ||  fTMax*(fTMax*fA + FixedFromFloat((float)2.0)*fB) + fC <= fRSumSqr )
            {
                fixed fCDiff = fC - fRSumSqr;
                fixed fDiscr = fB*fB - fA*fCDiff;
                if (fDiscr >= FIXED_ZERO)
                {
                    if (fCDiff <= FIXED_ZERO)
                    {
                        // The spheres are initially intersecting.  Estimate a
                        // point of contact by using the midpoint of the line
                        // segment connecting the sphere centers.
                        m_fContactTime = FIXED_ZERO;
                        m_kContactPoint = (FIXED_HALF)*(m_rkSphere0.Center +
                            m_rkSphere1.Center);
                    }
                    else
                    {
                        // The first time of contact is in [0,fTMax].
                        m_fContactTime = -(fB + Mathx::Sqrt(fDiscr))/fA;
                        if (m_fContactTime < FIXED_ZERO)
                        {
                            m_fContactTime = FIXED_ZERO;
                        }
                        else if (m_fContactTime > fTMax)
                        {
                            m_fContactTime = fTMax;
                        }

                        Vector3x kNewCDiff = kCDiff +
                            m_fContactTime*kVDiff;

                        m_kContactPoint = m_rkSphere0.Center +
                            m_fContactTime*rkVelocity0 +
                            (m_rkSphere0.Radius/fRSum)*kNewCDiff;
                    }
                    return true;
                }
            }
            return false;
        }
    }

    if (fC <= fRSumSqr)
    {
        // The spheres are initially intersecting.  Estimate a point of
        // contact by using the midpoint of the line segment connecting the
        // sphere centers.
        m_fContactTime = FIXED_ZERO;
        m_kContactPoint = (FIXED_HALF)*(m_rkSphere0.Center +
            m_rkSphere1.Center);
        return true;
    }

    return false;
}