Beispiel #1
0
void PlanarRectangle::InitUnit( const Rectangle & rect, const vec3f & integrationPoint )
{
	// copy src points here
	std::memcpy( &p0, &rect.p0, 4 * sizeof( vec3f ) );

	// Normalize each vertex to get the inscribed triangle,
	// and find the average vertex plane
	vec3f bary( 0 );
	vec3f *verts = &p0;
	for ( int i = 0; i < 4; ++i )
	{
		verts[i] = Normalize( verts[i] - integrationPoint ); // put in intPos frame
		bary += verts[i];
	}

	bary *= 0.25f;

	// project each point on the tangent plane at the barycenter
	f32 rayLenSq = Dot( bary, bary );
	f32 rayLen = std::sqrt( rayLenSq );
	ez = bary / rayLen; // plane normal

	// bary is in relative coordinates to the integration pt already
	const Plane P{ bary, ez };

	for ( int i = 0; i < 4; ++i )
	{
		// with 0 as origin since the vertices are in relative coordinates already
		verts[i] = P.RayIntersection( vec3f( 0 ), verts[i] );
	}

	const vec3f d0 = p1 - p0;
	const vec3f d1 = p3 - p0;

	const vec3f d2 = p2 - p3;
	const vec3f d3 = p2 - p1;

	w = Len( d0 );
	h = Len( d1 );

	ex = d0 / w;
	ey = d1 / h;

	area = 0.5f * ( w * h + Len( d2 ) * Len( d3 ) );
}
Beispiel #2
0
void PlanarRectangle::InitBary( const Rectangle & rect, const vec3f & integrationPoint )
{
	// copy src points here
	std::memcpy( &p0, &rect.p0, 4 * sizeof( vec3f ) );

	const vec3f bary = ( p0 + p1 + p2 + p3 ) * 0.25f;

	vec3f org = Normalize( bary - integrationPoint );

	const f32 rayLenSqr = Dot( org, org );
	const f32 rayLen = std::sqrt( rayLenSqr );
	const vec3f nrm = org / rayLen;

	// org is bary in relative coordinates
	const Plane P{ org, nrm };

	// project each point on the plane P
	vec3f *verts = &p0;
	for ( int i = 0; i < 4; ++i )
	{
		vec3f rayDir = Normalize( verts[i] - integrationPoint );

		// with 0 as origin since the vertices are in relative coordinates already
		verts[i] = P.RayIntersection( vec3f( 0 ), rayDir );
	}

	const vec3f d0 = p1 - p0;
	const vec3f d1 = p3 - p0;

	const vec3f d2 = p2 - p3;
	const vec3f d3 = p2 - p1;

	w = Len( d0 );
	h = Len( d1 );

	ex = d0 / w;
	ey = d1 / h;
	ez = nrm; // normal pointing away from origin

	area = 0.5f * ( w * h + Len( d2 ) * Len( d3 ) );
}
Beispiel #3
0
f32 Rectangle::IntegrateMRP( const vec3f & integrationPos, const vec3f & integrationNrm ) const
{
	const vec3f d0p = -ez;
	const vec3f d1p = integrationNrm;

	const f32 nDotpN = std::max( 0.f, Dot( integrationNrm, ez ) );

	vec3f d0 = Normalize( d0p + integrationNrm * nDotpN );
	vec3f d1 = Normalize( d1p - ez * nDotpN );

	vec3f dh = Normalize( d0 + d1 );

	Plane rectPlane = { position, ez };
	vec3f pH = rectPlane.RayIntersection( integrationPos, dh );
	pH = rectPlane.ClampPointInRect( *this, pH );

	const f32 solidAngle = SolidAngle( integrationPos );

	vec3f rayDir = Normalize( pH - integrationPos );

	return solidAngle * std::max( 0.f, Dot( integrationNrm, rayDir ) );
}