void ExpMapGenerator::SetSmoothNormal( ExpMapParticle * pParticle, ExpMapParticle::ListEntry * pNbrs, bool bEnable )
{
	if ( bEnable && pParticle->m_bNormalSmoothed )
		return;
	else if ( !bEnable && !pParticle->m_bNormalSmoothed)
		return;

	Wml::Vector3f vPos, vNorm, vNbrPos, vNbrNorm;
	if ( bEnable ) {
		float fWeightSum = 0.0f;
		Wml::Vector3f vAverage = Wml::Vector3f::ZERO;
		GetMesh()->GetVertex( pParticle->VertexID(), vPos, &vNorm);
		ExpMapParticle::ListEntry * pCur = pNbrs;
		while ( pCur != NULL ) {
			IMesh::VertexID nID = pCur->pParticle->VertexID();
			Wml::Vector3f vNbrPos, vNbrNorm;
			GetMesh()->GetVertex( pCur->pParticle->VertexID(), vNbrPos, &vNbrNorm);
			float fWeight = 1.0f / ( (vPos - vNbrPos).Length()  + (0.0001f*m_fMaxEdgeLength) );
			vAverage += fWeight * vNbrNorm;
			fWeightSum += fWeight;
			pCur = pCur->pNext;
		}
		vAverage /= fWeightSum;
		vAverage.Normalize();
		pParticle->Normal() = vAverage;
	} else {
		GetMesh()->GetNormal( pParticle->VertexID(), pParticle->Normal() );
	}

	pParticle->WorldFrame() = Frame3f( pParticle->Position(), pParticle->Normal() );
	pParticle->m_bNormalSmoothed = bEnable;
}
void ExpMapGenerator::PrecomputePropagationData( ExpMapParticle * pCenterParticle,
															 ExtPlane3f & vTangentPlane, 
															 Frame3f & vCenterWorldFrame,
															 Wml::Matrix2f & matFrameRotate )
{
	// compute surface-tangent plane at particle
	Wml::Vector3f vNormal( pCenterParticle->Normal() );

	// compute plane at this point
	vTangentPlane = ExtPlane3f( vNormal, pCenterParticle->Position() );

	// compute 3D frame at center point
	//vCenterWorldFrame = Frame3f( pCenterParticle->Position(), vNormal );
	vCenterWorldFrame = pCenterParticle->WorldFrame();

	// rotate seed world frame Z into this particle's Z
	Frame3f seedWorldFrame( m_pSeedParticle->WorldFrame() );
	seedWorldFrame.AlignZAxis( vCenterWorldFrame );

	// compute cos(angle) between axis
	Wml::Vector3f vCenterAxisX( vCenterWorldFrame.Axis( Frame3f::AxisX ) );
	Wml::Vector3f vSeedAxisX( seedWorldFrame.Axis( Frame3f::AxisX ) );
	float fCosTheta = vCenterAxisX.Dot(vSeedAxisX);

	// compute rotated min-dist vector for this particle
	float fTmp = 1 - fCosTheta*fCosTheta;
	if ( fTmp < 0 ) fTmp = 0;		// need to clamp so that sqrt works...
	float fSinTheta = (float)sqrt(fTmp);
	Wml::Vector3f vCross = vCenterAxisX.Cross(vSeedAxisX);
	if ( vCross.Dot( vNormal ) < 0 )	// get the right sign...
		fSinTheta = -fSinTheta;

	// create transposed 2D rotation matrix
	matFrameRotate = Wml::Matrix2f( fCosTheta, fSinTheta, -fSinTheta, fCosTheta );
}
Wml::Vector2f ExpMapGenerator::ComputeSurfaceVector( ExpMapParticle * pCenterParticle, 
																 ExpMapParticle * pNbrParticle,
																 ExtPlane3f & vTangentPlane, 
																 Frame3f & vCenterWorldFrame, 
																 Wml::Matrix2f & matFrameRotate )
{
	// special case...
	if ( (pNbrParticle->Position() - pCenterParticle->Position()).Length() < Wml::Mathf::EPSILON )
		return pCenterParticle->SurfaceVector();

	// project point into plane
	Wml::Vector3f vPlanePoint = vTangentPlane.RotatePointIntoPlane( pNbrParticle->Position() );

	// project point into coord system of frame
	vPlanePoint -= pCenterParticle->Position();
	vCenterWorldFrame.ToFrameLocal(vPlanePoint);

	// now we can project into surface frame simply by dropping z (which should be 0 anyway,
	//   since the vector lies in the plane!)
	Wml::Vector2f vSurfaceFrame( vPlanePoint.X(), vPlanePoint.Y() );

	// reverse vector so it points back to current particle
	vSurfaceFrame *= -1.0f;

	// transform local vector into coord system of initial surface reference frame
	//  and add accumulated surface vector
	return pCenterParticle->SurfaceVector() + (matFrameRotate * vSurfaceFrame);
}
Exemple #4
0
Wml::Vector3d rms::VectorCastfd( const Wml::Vector3f & vec )
{
	return Wml::Vector3d( (double)vec.X(), (double)vec.Y(), (double)vec.Z() );
}