static void AddNeighbor( 
	const CCoreDispInfo *pListBase,

	CCoreDispInfo *pMain,
	int iEdge,				// Which of pMain's sides this is on.
	int iSub,				// Which sub neighbor this takes up in pSide.
	NeighborSpan span,		// What span this fills in pMain.
	
	CCoreDispInfo *pOther,
	int iNeighborEdge,
	NeighborSpan nbSpan 
	)
{
	// The edge iteration before coming in here goes 0-1, 1-2, 2-3, 3-4.
	// This flips the sense of CORNER_TO_MIDPOINT/MIDPOINT_TO_CORNER on the right and 
	// bottom edges and is undone here.
	span = NeighborSpanFlip( iEdge, span );
	nbSpan = NeighborSpanFlip( iNeighborEdge, nbSpan );

	// Get the subspan this fills on our displacement.
	CDispSubNeighbor *pSub = &pMain->GetEdgeNeighbor(iEdge)->m_SubNeighbors[iSub];
	
	// Which subspan does this use in the neighbor?
	CDispSubNeighbor *pNeighborSub;
	if ( nbSpan == MIDPOINT_TO_CORNER )
		pNeighborSub = &pOther->GetEdgeNeighbor(iNeighborEdge)->m_SubNeighbors[1];
	else
		pNeighborSub = &pOther->GetEdgeNeighbor(iNeighborEdge)->m_SubNeighbors[0];

	// Make sure this slot isn't used on either displacement.
	if ( pSub->IsValid() || pNeighborSub->IsValid() )
	{
		ExecuteOnce( Warning( "Found a displacement edge abutting multiple other edges.\n" ) );
		return;
	}

	// Now just copy the data into each displacement.	
	pSub->m_iNeighbor = pOther - pListBase;
	pSub->m_NeighborOrientation = g_CoreDispNeighborOrientationMap[iEdge][iNeighborEdge];
	pSub->m_Span = span;
	pSub->m_NeighborSpan = nbSpan;

	pNeighborSub->m_iNeighbor = pMain - pListBase;
	pNeighborSub->m_NeighborOrientation = g_CoreDispNeighborOrientationMap[iNeighborEdge][iEdge];
	pNeighborSub->m_Span = nbSpan;
	pNeighborSub->m_NeighborSpan = span;

#if defined( _DEBUG )
	// Walk an iterator over the new connection to make sure it works.
	CDispSubEdgeIterator it;
	it.Start( pMain, iEdge, iSub );
	while ( it.Next() )
	{
		CVertIndex nbIndex;
		TransformIntoNeighbor( pMain, iEdge, it.GetVertIndex(), nbIndex );
	}
#endif
}
Beispiel #2
0
void BlendEdges( CCoreDispInfo **ppListBase, int listSize )
{
	for ( int iDisp=0; iDisp < listSize; iDisp++ )
	{
		CCoreDispInfo *pDisp = ppListBase[iDisp];

		for ( int iEdge=0; iEdge < 4; iEdge++ )
		{
			CDispNeighbor *pEdge = pDisp->GetEdgeNeighbor( iEdge );

			for ( int iSub=0; iSub < 2; iSub++ )
			{
				CDispSubNeighbor *pSub = &pEdge->m_SubNeighbors[iSub];
				if ( !pSub->IsValid() )
					continue;

				CCoreDispInfo *pNeighbor = ppListBase[ pSub->GetNeighborIndex() ];

				int iEdgeDim = g_EdgeDims[iEdge];

				CDispSubEdgeIterator it;
				it.Start( pDisp, iEdge, iSub, true );

				// Get setup on the first corner vert.
				it.Next();
				CVertIndex viPrevPos = it.GetVertIndex();

				while ( it.Next() )
				{
					// Blend the two.
					if ( !it.IsLastVert() )
					{
						Vector vAverage = pDisp->GetNormal( it.GetVertIndex() ) + pNeighbor->GetNormal( it.GetNBVertIndex() );
						VectorNormalize( vAverage );

						pDisp->SetNormal( it.GetVertIndex(), vAverage );
						pNeighbor->SetNormal( it.GetNBVertIndex(), vAverage );

#if defined( USE_SCRATCHPAD )
						ScratchPad_DrawArrowSimple( g_pPad, pDisp->GetVert( it.GetVertIndex() ), pDisp->GetNormal( it.GetVertIndex() ), Vector( 1, 0, 0 ), 25 );
#endif
					}

					// Now blend the in-between verts (if this edge is high-res).
					int iPrevPos = viPrevPos[ !iEdgeDim ];
					int iCurPos = it.GetVertIndex()[ !iEdgeDim ];
					
					for ( int iTween = iPrevPos+1; iTween < iCurPos; iTween++ )
					{
						float flPercent = RemapVal( iTween, iPrevPos, iCurPos, 0, 1 );
						Vector vNormal;
						VectorLerp( pDisp->GetNormal( viPrevPos ), pDisp->GetNormal( it.GetVertIndex() ), flPercent, vNormal );
						VectorNormalize( vNormal );

						CVertIndex viTween;
						viTween[iEdgeDim] = it.GetVertIndex()[ iEdgeDim ];
						viTween[!iEdgeDim] = iTween;
						pDisp->SetNormal( viTween, vNormal );

#if defined( USE_SCRATCHPAD )
						ScratchPad_DrawArrowSimple( g_pPad, pDisp->GetVert( viTween ), pDisp->GetNormal( viTween ), Vector( 1, 0.5, 0 ), 25 );
#endif
					}
			
					viPrevPos = it.GetVertIndex();
				}
			}
		}
	}
}