Example #1
0
//==============================
// FontInfoType::LoadFromBuffer
bool FontInfoType::LoadFromBuffer( void const * buffer, size_t const bufferSize ) 
{
	char const * errorMsg = NULL;
	OVR::JSON * jsonRoot = OVR::JSON::Parse( reinterpret_cast< char const * >( buffer ), &errorMsg );
	if ( jsonRoot == NULL )
	{
		LOG( "JSON Error: %s", ( errorMsg != NULL ) ? errorMsg : "<NULL>" );
		return false;
	}

	int32_t maxCharCode = -1;
	// currently we're only supporting the first unicode plane up to 65k. If we were to support other planes
	// we could conceivably end up with a very sparse 1,114,111 byte type for mapping character codes to
	// glyphs and if that's the case we may just want to use a hash, or use a combination of tables for
	// the first 65K and hashes for the other, less-frequently-used characters.
	static const int MAX_GLYPHS = 0xffff;	

	// load the glyphs
	const JsonReader jsonGlyphs( jsonRoot );
	if ( !jsonGlyphs.IsObject() )
	{
		jsonRoot->Release();
		return false;
	}

	int Version = jsonGlyphs.GetChildFloatByName( "Version" );
	if ( Version != FNT_FILE_VERSION )
	{
		jsonRoot->Release();
		return false;
	}

	FontName = jsonGlyphs.GetChildStringByName( "FontName" );
	CommandLine = jsonGlyphs.GetChildStringByName( "CommandLine" );
	ImageFileName = jsonGlyphs.GetChildStringByName( "ImageFileName" );
	const int numGlyphs = jsonGlyphs.GetChildInt32ByName( "NumGlyphs" );
	if ( numGlyphs < 0 || numGlyphs > MAX_GLYPHS )
	{
		OVR_ASSERT( numGlyphs > 0 && numGlyphs <= MAX_GLYPHS );
		jsonRoot->Release();
		return false;
	}

	NaturalWidth = jsonGlyphs.GetChildFloatByName( "NaturalWidth" );
	NaturalHeight = jsonGlyphs.GetChildFloatByName( "NaturalHeight" );

	// we scale everything after loading integer values from the JSON file because the OVR JSON writer loses precision on floats
	double nwScale = 1.0f / NaturalWidth;
	double nhScale = 1.0f / NaturalHeight;

	HorizontalPad = jsonGlyphs.GetChildFloatByName( "HorizontalPad" ) * nwScale;
	VerticalPad = jsonGlyphs.GetChildFloatByName( "VerticalPad" ) * nhScale;
	FontHeight = jsonGlyphs.GetChildFloatByName( "FontHeight" ) * nhScale;
	CenterOffset = jsonGlyphs.GetChildFloatByName( "CenterOffset" );
	TweakScale = jsonGlyphs.GetChildFloatByName( "TweakScale", 1.0f );

	LOG( "FontName = %s", FontName.ToCStr() );
	LOG( "CommandLine = %s", CommandLine.ToCStr() );
	LOG( "HorizontalPad = %.4f", HorizontalPad );
	LOG( "VerticalPad = %.4f", VerticalPad );
	LOG( "FontHeight = %.4f", FontHeight );
	LOG( "CenterOffset = %.4f", CenterOffset );
	LOG( "TweakScale = %.4f", TweakScale );
	LOG( "ImageFileName = %s", ImageFileName.ToCStr() );
	LOG( "Loading %i glyphs.", numGlyphs );

/// HACK: this is hard-coded until we do not have a dependcy on reading the font from Home
	if ( OVR_stricmp( FontName.ToCStr(), "korean.fnt" ) == 0 )
	{
		TweakScale = 1.4f;
		CenterOffset = -0.02f;
	}
/// HACK: end hack

	Glyphs.Resize( numGlyphs );

	const JsonReader jsonGlyphArray( jsonGlyphs.GetChildByName( "Glyphs" ) );
	double totalWidth = 0.0;
	if ( jsonGlyphArray.IsArray() )
	{
		for ( int i = 0; i < Glyphs.GetSizeI() && !jsonGlyphArray.IsEndOfArray(); i++ )
		{
			const JsonReader jsonGlyph( jsonGlyphArray.GetNextArrayElement() );
			if ( jsonGlyph.IsObject() )
			{
				FontGlyphType & g = Glyphs[i];
				g.CharCode	= jsonGlyph.GetChildInt32ByName( "CharCode" );
				g.X			= jsonGlyph.GetChildFloatByName( "X" );
				g.Y			= jsonGlyph.GetChildFloatByName( "Y" );
				g.Width		= jsonGlyph.GetChildFloatByName( "Width" );
				g.Height	= jsonGlyph.GetChildFloatByName( "Height" );
				g.AdvanceX	= jsonGlyph.GetChildFloatByName( "AdvanceX" );
				g.AdvanceY	= jsonGlyph.GetChildFloatByName( "AdvanceY" );
				g.BearingX	= jsonGlyph.GetChildFloatByName( "BearingX" );
				g.BearingY	= jsonGlyph.GetChildFloatByName( "BearingY" );

				g.X *= nwScale;
				g.Y *= nhScale;
				g.Width *= nwScale;
				g.Height *= nhScale;
				g.AdvanceX *= nwScale;
				g.AdvanceY *= nhScale;
				g.BearingX *= nwScale;
				g.BearingY *= nhScale;

				totalWidth += g.Width;

				maxCharCode = Alg::Max( maxCharCode, g.CharCode );
			}
		}
	}

	double averageGlyphWidth = totalWidth / numGlyphs;

	// this is the average width in uv space of characters in the ClearSans font. This is used to 
	// compute a scaling factor for other fonts.
	double const DEFAULT_GLYPH_UV_WIDTH = 0.047458650262793022;	
	float const DEFAULT_TEXT_SCALE = 0.0025f;

	float const widthScaleFactor = static_cast< float >( DEFAULT_GLYPH_UV_WIDTH / averageGlyphWidth );
	ScaleFactor = DEFAULT_SCALE_FACTOR * DEFAULT_TEXT_SCALE * widthScaleFactor * TweakScale;

	// This is not intended for wide or ucf character sets -- depending on the size range of
	// character codes lookups may need to be changed to use a hash.
	if ( maxCharCode >= MAX_GLYPHS )
	{
		OVR_ASSERT( maxCharCode <= MAX_GLYPHS );
		maxCharCode = MAX_GLYPHS;
	}
	
	// resize the array to the maximum glyph value
	CharCodeMap.Resize( maxCharCode + 1 );
	for ( int i = 0; i < Glyphs.GetSizeI(); ++i )
	{
		FontGlyphType const & g = Glyphs[i];
		CharCodeMap[g.CharCode] = i;
	}

	jsonRoot->Release();

	return true;
}
Example #2
0
void ParseModelsJsonTest( const char * jsonFileName, const char * binFileName )
{
	const BinaryReader bin( binFileName, NULL );
	if ( bin.ReadUInt32() != 0x6272766F )
	{
		return;
	}

	JSON * json = JSON::Load( jsonFileName );
	if ( json == NULL )
	{
		return;
	}
	const JsonReader models( json );
	if ( models.IsObject() )
	{
		//
		// Render Model
		//

		const JsonReader render_model( models.GetChildByName( "render_model" ) );
		if ( render_model.IsObject() )
		{
			const JsonReader texture_array( render_model.GetChildByName( "textures" ) );
			if ( texture_array.IsArray() )
			{
				while ( !texture_array.IsEndOfArray() )
				{
					const JsonReader texture( texture_array.GetNextArrayElement() );
					if ( texture.IsObject() )
					{
						const String name = texture.GetChildStringByName( "name" );
						const String usage = texture.GetChildStringByName( "usage" );
						const String occlusion = texture.GetChildStringByName( "occlusion" );
					}
				}
			}

			const JsonReader joint_array( render_model.GetChildByName( "joints" ) );
			if ( joint_array.IsArray() )
			{
				while ( !joint_array.IsEndOfArray() )
				{
					const JsonReader joint( joint_array.GetNextArrayElement() );
					if ( joint.IsObject() )
					{
						struct Joint
						{
							String		name;
							Matrix4f	transform;
							String		animation;
							Vector3f	parameters;
							float		timeOffset;
							float		timeScale;
						} newJoint;
						newJoint.name = joint.GetChildStringByName( "name" );
						newJoint.animation = joint.GetChildStringByName( "animation" );
						StringUtils::StringTo( newJoint.transform, joint.GetChildStringByName( "transform" ) );
						newJoint.parameters.x = joint.GetChildFloatByName( "parmX" );
						newJoint.parameters.y = joint.GetChildFloatByName( "parmY" );
						newJoint.parameters.z = joint.GetChildFloatByName( "parmZ" );
						newJoint.timeScale = joint.GetChildFloatByName( "timeScale" );
						newJoint.timeOffset = joint.GetChildFloatByName( "timeOffset" );
					}
				}
			}

			const JsonReader tag_array( render_model.GetChildByName( "tags" ) );
			if ( tag_array.IsArray() )
			{
				while ( !tag_array.IsEndOfArray() )
				{
					const JsonReader tag( tag_array.GetNextArrayElement() );
					if ( tag.IsObject() )
					{
						struct Tag
						{
							String		name;
							Matrix4f	matrix;
							Vector4i	jointIndices;
							Vector4f	jointWeights;
						} newTag;

						const String name = tag.GetChildStringByName( "name" );
						StringUtils::StringTo( newTag.matrix, tag.GetChildStringByName( "matrix" ) );
						StringUtils::StringTo( newTag.jointIndices, tag.GetChildStringByName( "jointIndices" ) );
						StringUtils::StringTo( newTag.jointWeights, tag.GetChildStringByName( "jointWeights" ) );
					}
				}
			}

			const JsonReader surface_array( render_model.GetChildByName( "surfaces" ) );
			if ( surface_array.IsArray() )
			{
				while ( !surface_array.IsEndOfArray() )
				{
					struct Surface
					{
						String				name;
						String				materialType;
						int					diffuseTexture;
						int					normalTexture;
						int					specularTexture;
						int					emissiveTexture;
						Bounds3f			bounds;
						Array< Vector3f >	position;
						Array< Vector3f >	normal;
						Array< Vector3f >	tangent;
						Array< Vector3f >	binormal;
						Array< Vector4f >	color;
						Array< Vector2f >	uv0;
						Array< Vector2f >	uv1;
						Array< Vector4f >	jointWeights;
						Array< Vector4i >	jointIndices;
						Array< uint16_t >	indices;
					} newSurface;

					const JsonReader surface( surface_array.GetNextArrayElement() );
					if ( surface.IsObject() )
					{
						const JsonReader source( surface.GetChildByName( "source" ) );
						if ( source.IsArray() )
						{
							while ( !source.IsEndOfArray() )
							{
								if ( newSurface.name.GetLength() )
								{
									newSurface.name += ";";
								}
								newSurface.name += source.GetNextArrayString();
							}
						}

						const JsonReader material( surface.GetChildByName( "material" ) );
						if ( material.IsObject() )
						{
							newSurface.materialType		= material.GetChildStringByName( "type" );
							newSurface.diffuseTexture	= material.GetChildInt32ByName( "diffuse", -1 );
							newSurface.normalTexture	= material.GetChildInt32ByName( "normal", -1 );
							newSurface.specularTexture	= material.GetChildInt32ByName( "specular", -1 );
							newSurface.emissiveTexture	= material.GetChildInt32ByName( "emissive", -1 );
						}

						StringUtils::StringTo( newSurface.bounds, surface.GetChildStringByName( "bounds" ) );

						//
						// Vertices
						//

						const JsonReader vertices( surface.GetChildByName( "vertices" ) );
						if ( vertices.IsObject() )
						{
							const int vertexCount = vertices.GetChildInt32ByName( "vertexCount" );
							ReadModelArray( newSurface.position,     vertices.GetChildStringByName( "position" ),		bin, vertexCount );
							ReadModelArray( newSurface.normal,       vertices.GetChildStringByName( "normal" ),			bin, vertexCount );
							ReadModelArray( newSurface.tangent,      vertices.GetChildStringByName( "tangent" ),		bin, vertexCount );
							ReadModelArray( newSurface.binormal,     vertices.GetChildStringByName( "binormal" ),		bin, vertexCount );
							ReadModelArray( newSurface.color,        vertices.GetChildStringByName( "color" ),			bin, vertexCount );
							ReadModelArray( newSurface.uv0,          vertices.GetChildStringByName( "uv0" ),			bin, vertexCount );
							ReadModelArray( newSurface.uv1,          vertices.GetChildStringByName( "uv1" ),			bin, vertexCount );
							ReadModelArray( newSurface.jointIndices, vertices.GetChildStringByName( "jointIndices" ),	bin, vertexCount );
							ReadModelArray( newSurface.jointWeights, vertices.GetChildStringByName( "jointWeights" ),	bin, vertexCount );
						}

						//
						// Triangles
						//

						const JsonReader triangles( surface.GetChildByName( "triangles" ) );
						if ( triangles.IsObject() )
						{
							const int indexCount = triangles.GetChildInt32ByName( "indexCount" );
							ReadModelArray( newSurface.indices, triangles.GetChildStringByName( "indices" ), bin, indexCount );
						}
					}
				}
			}
		}

		//
		// Collision Model
		//

		const JsonReader collision_model( models.GetChildByName( "collision_model" ) );
		if ( collision_model.IsArray() )
		{
			while ( !collision_model.IsEndOfArray() )
			{
				Array< Planef > planes;

				const JsonReader polytope( collision_model.GetNextArrayElement() );
				if ( polytope.IsObject() )
				{
					const String name = polytope.GetChildStringByName( "name" );
					StringUtils::StringTo( planes, polytope.GetChildStringByName( "planes" ) );
				}
			}
		}

		//
		// Ground Collision Model
		//

		const JsonReader ground_collision_model( models.GetChildByName( "ground_collision_model" ) );
		if ( ground_collision_model.IsArray() )
		{
			while ( !ground_collision_model.IsEndOfArray() )
			{
				Array< Planef > planes;

				const JsonReader polytope( ground_collision_model.GetNextArrayElement() );
				if ( polytope.IsObject() )
				{
					const String name = polytope.GetChildStringByName( "name" );
					StringUtils::StringTo( planes, polytope.GetChildStringByName( "planes" ) );
				}
			}
		}

		//
		// Ray-Trace Model
		//

		const JsonReader raytrace_model( models.GetChildByName( "raytrace_model" ) );
		if ( raytrace_model.IsObject() )
		{
			ModelTrace traceModel;

			traceModel.header.numVertices	= raytrace_model.GetChildInt32ByName( "numVertices" );
			traceModel.header.numUvs		= raytrace_model.GetChildInt32ByName( "numUvs" );
			traceModel.header.numIndices	= raytrace_model.GetChildInt32ByName( "numIndices" );
			traceModel.header.numNodes		= raytrace_model.GetChildInt32ByName( "numNodes" );
			traceModel.header.numLeafs		= raytrace_model.GetChildInt32ByName( "numLeafs" );
			traceModel.header.numOverflow	= raytrace_model.GetChildInt32ByName( "numOverflow" );

			StringUtils::StringTo( traceModel.header.bounds, raytrace_model.GetChildStringByName( "bounds" ) );

			ReadModelArray( traceModel.vertices, raytrace_model.GetChildStringByName( "vertices" ), bin, traceModel.header.numVertices );
			ReadModelArray( traceModel.uvs, raytrace_model.GetChildStringByName( "uvs" ), bin, traceModel.header.numUvs );
			ReadModelArray( traceModel.indices, raytrace_model.GetChildStringByName( "indices" ), bin, traceModel.header.numIndices );

			if ( !bin.ReadArray( traceModel.nodes, traceModel.header.numNodes ) )
			{
				const JsonReader nodes_array( raytrace_model.GetChildByName( "nodes" ) );
				if ( nodes_array.IsArray() )
				{
					while ( !nodes_array.IsEndOfArray() )
					{
						const UPInt index = traceModel.nodes.AllocBack();

						const JsonReader node( nodes_array.GetNextArrayElement() );
						if ( node.IsObject() )
						{
							traceModel.nodes[index].data = (UInt32) node.GetChildInt64ByName( "data" );
							traceModel.nodes[index].dist = node.GetChildFloatByName( "dist" );
						}
					}
				}
			}

			if ( !bin.ReadArray( traceModel.leafs, traceModel.header.numLeafs ) )
			{
				const JsonReader leafs_array( raytrace_model.GetChildByName( "leafs" ) );
				if ( leafs_array.IsArray() )
				{
					while ( !leafs_array.IsEndOfArray() )
					{
						const UPInt index = traceModel.leafs.AllocBack();

						const JsonReader leaf( leafs_array.GetNextArrayElement() );
						if ( leaf.IsObject() )
						{
							StringUtils::StringTo( traceModel.leafs[index].triangles, RT_KDTREE_MAX_LEAF_TRIANGLES, leaf.GetChildStringByName( "triangles" ) );
							StringUtils::StringTo( traceModel.leafs[index].ropes, 6, leaf.GetChildStringByName( "ropes" ) );
							StringUtils::StringTo( traceModel.leafs[index].bounds, leaf.GetChildStringByName( "bounds" ) );
						}
					}
				}
			}

			ReadModelArray( traceModel.overflow, raytrace_model.GetChildStringByName( "overflow" ), bin, traceModel.header.numOverflow );
		}
	}
	json->Release();

	assert( bin.IsAtEnd() );
}