Beispiel #1
0
bool RtIntersect::RayTriangle( const Vector3f & rayStart, const Vector3f & rayDir,
							const Vector3f & v0, const Vector3f & v1, const Vector3f & v2,
							float & t0, float & u, float & v )
{
	assert( rayDir.IsNormalized() );

	const Vector3f edge1 = v1 - v0;
	const Vector3f edge2 = v2 - v0;

	const Vector3f tv = rayStart - v0;
	const Vector3f pv = rayDir.Cross( edge2 );
	const Vector3f qv = tv.Cross( edge1 );
	const float det = edge1.Dot( pv );

	// If the determinant is negative then the triangle is backfacing.
	if ( det <= 0.0f )
	{
		return false;
	}

	// This code has been modified to only perform a floating-point
	// division if the ray actually hits the triangle. If back facing
	// triangles are not culled then the sign of 's' and 't' need to
	// be flipped. This can be accomplished by multiplying the values
	// with the determinant instead of the reciprocal determinant.

	const float s = tv.Dot( pv );
	const float t = rayDir.Dot( qv );

	if ( s >= 0.0f && s <= det )
	{
		if ( t >= 0.0f && s + t <= det )
		{
			// If the determinant is almost zero then the ray lies in the triangle plane.
			// This comparison is done last because it is usually rare for
			// the ray to lay in the triangle plane.
			if ( fabsf( det ) > Math<float>::SmallestNonDenormal )
			{
				const float rcpDet = 1.0f / det;
				t0 = edge2.Dot( qv ) * rcpDet;
				u = s * rcpDet;
				v = t * rcpDet;
				return true;
			}
		}
	}

	return false;
}
//==============================
// BitmapFontSurfaceLocal::DrawText3D
void BitmapFontSurfaceLocal::DrawText3D( BitmapFont const & font, fontParms_t const & parms,
		Vector3f const & pos, Vector3f const & normal, Vector3f const & up,
		float scale, Vector4f const & color, char const * text )
{
	if ( text == NULL || text[0] == '\0' )
	{
		return;	// nothing to do here, move along
	}

	// TODO: multiple line support -- we would need to calculate the horizontal width
	// for each string ending in \n
	size_t len;
	float width;
	float height;
	float ascent;
	float descent;
	int const MAX_LINES = 128;
	float lineWidths[MAX_LINES];
	int numLines;
	AsLocal( font ).CalcTextMetrics( text, len, width, height, ascent, descent, lineWidths, MAX_LINES, numLines );
//	LOG( "BitmapFontSurfaceLocal::DrawText3D( \"%s\" %s %s ) : width = %.2f, height = %.2f, numLines = %i, fh = %.2f",
//			text, parms.CenterVert ? "cv" : "", parms.CenterHoriz ? "ch" : "",
//			width, height, numLines, AsLocal( font ).GetFontInfo().FontHeight );
	if ( len == 0 )
	{
		return;
	}

	DROID_ASSERT( normal.IsNormalized(), "BitmapFont" );
	DROID_ASSERT( up.IsNormalized(), "BitmapFont" );

	const FontInfoType & fontInfo = AsLocal( font ).GetFontInfo();

	float imageWidth = (float)AsLocal( font ).GetImageWidth();
	float const xScale = AsLocal( font ).GetFontInfo().ScaleFactor * scale;
	float const yScale = AsLocal( font ).GetFontInfo().ScaleFactor * scale;

	// allocate a vertex block
	size_t numVerts = 4 * len;
	VertexBlockType vb( font, numVerts, pos, Quatf(), parms.Billboard, parms.TrackRoll );

	Vector3f const right = up.Cross( normal );
	Vector3f const r = ( parms.Billboard ) ? Vector3f( 1.0f, 0.0f, 0.0f ) : right;
	Vector3f const u = ( parms.Billboard ) ? Vector3f( 0.0f, 1.0f, 0.0f ) : up;

	Vector3f curPos( 0.0f );
	if ( parms.CenterVert )
	{
		float const vofs = ( height * 0.5f ) - ascent;
		curPos += u * ( vofs * scale );
	}

	Vector3f basePos = curPos;
	if ( parms.CenterHoriz )
	{
		curPos -= r * ( lineWidths[0] * 0.5f * scale );
	}
	
	Vector3f lineInc = u * ( fontInfo.FontHeight * yScale );
	float const distanceScale = imageWidth / FontInfoType::DEFAULT_SCALE_FACTOR;
	const uint8_t fontParms[4] = 
	{
			(uint8_t)( OVR::Alg::Clamp( parms.AlphaCenter + fontInfo.CenterOffset, 0.0f, 1.0f ) * 255 ),
			(uint8_t)( OVR::Alg::Clamp( parms.ColorCenter + fontInfo.CenterOffset, 0.0f, 1.0f ) * 255 ),
			(uint8_t)( OVR::Alg::Clamp( distanceScale, 1.0f, 255.0f ) ),
			0
	};

    int iColor = ColorToABGR( color );

	int curLine = 0;
	fontVertex_t * v = vb.Verts;
	char const * p = text;
	size_t i = 0;
	uint32_t charCode = UTF8Util::DecodeNextChar( &p );
	for ( ; charCode != '\0'; i++, charCode = UTF8Util::DecodeNextChar( &p ) )
	{
		OVR_ASSERT( i < len );
		if ( charCode == '\n' && curLine < numLines && curLine < MAX_LINES )
		{
			// move to next line
			curLine++;
			basePos -= lineInc;
			curPos = basePos;
			if ( parms.CenterHoriz )
			{
				curPos -= r * ( lineWidths[curLine] * 0.5f * scale );
			}
		}

		FontGlyphType const & g = AsLocal( font ).GlyphForCharCode( charCode );

		float s0 = g.X;
		float t0 = g.Y;
		float s1 = ( g.X + g.Width );
		float t1 = ( g.Y + g.Height );

		float bearingX = g.BearingX * xScale;
		float bearingY = g.BearingY * yScale ;

		float rw = ( g.Width + g.BearingX ) * xScale;
		float rh = ( g.Height - g.BearingY ) * yScale;

        // lower left
        v[i * 4 + 0].xyz = curPos + ( r * bearingX ) - ( u * rh );
        v[i * 4 + 0].s = s0;
        v[i * 4 + 0].t = t1;
        *(UInt32*)(&v[i * 4 + 0].rgba[0]) = iColor;
		*(UInt32*)(&v[i * 4 + 0].fontParms[0]) = *(UInt32*)(&fontParms[0]);
	    // upper left
        v[i * 4 + 1].xyz = curPos + ( r * bearingX ) + ( u * bearingY );
        v[i * 4 + 1].s = s0;
        v[i * 4 + 1].t = t0;
        *(UInt32*)(&v[i * 4 + 1].rgba[0]) = iColor;
		*(UInt32*)(&v[i * 4 + 1].fontParms[0]) = *(UInt32*)(&fontParms[0]);
        // upper right
        v[i * 4 + 2].xyz = curPos + ( r * rw ) + ( u * bearingY );
        v[i * 4 + 2].s = s1;
        v[i * 4 + 2].t = t0;
        *(UInt32*)(&v[i * 4 + 2].rgba[0]) = iColor;
		*(UInt32*)(&v[i * 4 + 2].fontParms[0]) = *(UInt32*)(&fontParms[0]);
        // lower right
        v[i * 4 + 3].xyz = curPos + ( r * rw ) - ( u * rh );
        v[i * 4 + 3].s = s1;
        v[i * 4 + 3].t = t1;
        *(UInt32*)(&v[i * 4 + 3].rgba[0]) = iColor;
		*(UInt32*)(&v[i * 4 + 3].fontParms[0]) = *(UInt32*)(&fontParms[0]);
		// advance to start of next char
		curPos += r * ( g.AdvanceX * xScale );
	}
	// add the new vertex block to the array of vertex blocks
	VertexBlocks.PushBack( vb );
}