// Returns an intersection if found with distance maxDistance // viewDir must be a unit vector. // intersectDistance and visPoint are returned values. bool ViewableTriangle::FindIntersectionNT ( const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, double *intersectDistance, VisiblePoint& returnedPoint ) const { assert( IsWellFormed() ); double mdotn = (viewDir^Normal); double planarDist = (viewPos^Normal)-PlaneCoef; // hit distance = -planarDist/mdotn bool frontFace = (mdotn<=0.0); if ( frontFace ) { if ( planarDist<=0 || planarDist >= -maxDistance*mdotn ) { return false; } } else { if ( BackFaceCulled() || planarDist>=0 || -planarDist >= maxDistance*mdotn ) { return false; } } *intersectDistance = -planarDist/mdotn; VectorR3 q; q = viewDir; q *= *intersectDistance; q += viewPos; // Point of view line intersecting plane // Compute barycentric coordinates VectorR3 v(q); v -= VertexA; double vCoord = (v^Ubeta); if ( vCoord<0.0 ) { return false; } double wCoord = (v^Ugamma); if ( wCoord<0.0 || vCoord+wCoord>1.0 ) { return false; } returnedPoint.SetPosition( q ); // Set point of intersection returnedPoint.SetUV( vCoord, wCoord ); // Front/Back face info already set above if ( frontFace ) { returnedPoint.SetMaterial( *FrontMat ); returnedPoint.SetFrontFace(); } else { returnedPoint.SetMaterial( *BackMat ); returnedPoint.SetBackFace(); } returnedPoint.SetNormal( Normal ); returnedPoint.SetFaceNumber( 0 ); return true; }
// Returns an intersection if found with distance maxDistance // viewDir must be a unit vector. // intersectDistance and visPoint are returned values. bool ViewableParallelogram::FindIntersectionNT ( const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, double *intersectDistance, VisiblePoint& returnedPoint ) const { assert( IsWellFormed() ); double mdotn = (viewDir^Normal); double planarDist = (viewPos^Normal)-PlaneCoef; // hit distance = -planarDist/mdotn if ( mdotn<=0.0 ) { if ( planarDist<=0 || planarDist >= -maxDistance*mdotn ) { return false; } returnedPoint.SetFrontFace(); } else { if ( BackFaceCulled() || planarDist>=0 || -planarDist >= maxDistance*mdotn ) { return false; } returnedPoint.SetBackFace(); } *intersectDistance = -planarDist/mdotn; VectorR3 v; v = viewDir; v *= *intersectDistance; v += viewPos; // Point of view line intersecting plane double dotABnormal = v^NormalAB; if ( dotABnormal<CoefAB || dotABnormal>CoefCD ) { return false; } double dotBCnormal = v^NormalBC; if ( dotBCnormal<CoefBC || dotBCnormal>CoefDA ) { return false; } // Front/Back face info already set above returnedPoint.SetPosition( v ); returnedPoint.SetMaterial( (mdotn<=0) ? *FrontMat : *BackMat ); returnedPoint.SetNormal( Normal ); // Compute the u-v coordinates double uCoord = (dotBCnormal-CoefBC)/(CoefDA-CoefBC); double vCoord = (dotABnormal-CoefAB)/(CoefCD-CoefAB); returnedPoint.SetUV(uCoord, vCoord); returnedPoint.SetFaceNumber( 0 ); return true; }
bool CMarkupSTL::x_AddElem( const char * szName, const char * szValue, bool bInsert, bool bAddChild ) { if ( bAddChild ) { // Adding a child element under main position if ( ! m_iPos ) return false; } else if ( m_iPosParent == 0 ) { // Adding root element if ( IsWellFormed() ) return false; // Locate after any version and DTD m_aPos[0].nEndL = m_csDoc.GetLength(); } // Locate where to add element relative to current node int iPosParent, iPosBefore, nOffset = 0, nLength = 0; if ( bAddChild ) { iPosParent = m_iPos; iPosBefore = m_iPosChild; } else { iPosParent = m_iPosParent; iPosBefore = m_iPos; } int nFlags = bInsert?1:0; x_LocateNew( iPosParent, iPosBefore, nOffset, nLength, nFlags ); bool bEmptyParent = m_aPos[iPosParent].IsEmptyElement(); if ( bEmptyParent ) nOffset += 2; // include CRLF // Create element and modify positions of affected elements // If no szValue is specified, an empty element is created // i.e. either <NAME>value</NAME> or <NAME/> // int iPos = x_GetFreePos(); m_aPos[iPos].nStartL = nOffset; // Set links m_aPos[iPos].iElemParent = iPosParent; m_aPos[iPos].iElemChild = 0; m_aPos[iPos].iElemNext = 0; if ( iPosBefore ) { // Link in after iPosBefore m_aPos[iPos].iElemNext = m_aPos[iPosBefore].iElemNext; m_aPos[iPosBefore].iElemNext = iPos; } else { // First child m_aPos[iPos].iElemNext = m_aPos[iPosParent].iElemChild; m_aPos[iPosParent].iElemChild = iPos; } // Create string for insert CStdString csInsert; int nLenName = _tcslen(szName); int nLenValue = szValue? _tcslen(szValue) : 0; if ( ! nLenValue ) { // <NAME/> empty element csInsert = _T("<"); csInsert += szName; csInsert += _T("/>\r\n"); m_aPos[iPos].nStartR = m_aPos[iPos].nStartL + nLenName + 2; m_aPos[iPos].nEndL = m_aPos[iPos].nStartR - 1; m_aPos[iPos].nEndR = m_aPos[iPos].nEndL + 1; } else { // <NAME>value</NAME> CStdString csValue = x_TextToDoc( szValue ); nLenValue = csValue.GetLength(); csInsert = _T("<"); csInsert += szName; csInsert += _T(">"); csInsert += csValue; csInsert += _T("</"); csInsert += szName; csInsert += _T(">\r\n"); m_aPos[iPos].nStartR = m_aPos[iPos].nStartL + nLenName + 1; m_aPos[iPos].nEndL = m_aPos[iPos].nStartR + nLenValue + 1; m_aPos[iPos].nEndR = m_aPos[iPos].nEndL + nLenName + 2; } // Insert int nReplace = 0, nLeft = m_aPos[iPos].nStartL; if ( bEmptyParent ) { CStdString csParentTagName = x_GetTagName(iPosParent); CStdString csFormat; csFormat = _T(">\r\n"); csFormat += csInsert; csFormat += _T("</"); csFormat += csParentTagName; csInsert = csFormat; nLeft -= 3; nReplace = 1; // x_Adjust is going to update all affected indexes by one amount // This will satisfy all except the empty parent // Here we pre-adjust for the empty parent // The empty tag slash is removed m_aPos[iPosParent].nStartR -= 1; // For the newly created end tag, see the following example: // <A/> (len 4) becomes <A><B/></A> (len 11) // In x_Adjust everything will be adjusted 11 - 4 = 7 // But the nEndL of element A should only be adjusted 5 m_aPos[iPosParent].nEndL -= (csParentTagName.GetLength() + 1); } x_DocChange( nLeft, nReplace, csInsert ); x_Adjust( iPos, csInsert.GetLength() - nReplace ); if ( bAddChild ) x_SetPos( m_iPosParent, iPosParent, iPos ); else x_SetPos( iPosParent, iPos, 0 ); return true; }