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; }
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; }
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; }