// 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;
}
示例#3
0
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;
}