UnitTests/VmdlGeneratorTests.cs

Unit tests for VmdlGenerator and related model/KV3 utilities. They call VmdlGenerator.Generate with various MeshToModelOptions, parse the resulting Kv3Document, and assert presence and fields of render and physics objects; also tests VmdlBulkEditor load/apply behavior.

using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ModelPro.Vmdl;

[TestClass]
public class VmdlGeneratorTests
{
	[TestMethod]
	public void GeneratesValidVmdl_HullCollision()
	{
		var options = new MeshToModelOptions
		{
			Collision = CollisionMode.Hull,
			ImportScale = 0.3937f,
			AlignOriginX = AlignOrigin.BoundsCenter,
			AlignOriginY = AlignOrigin.BoundsCenter,
			AlignOriginZ = AlignOrigin.BoundsMin
		};

		var source = VmdlGenerator.Generate( "models/foo.fbx", options );

		// Parseable, finds all nodes.
		var doc = Kv3Document.Parse( source );
		Assert.AreEqual( 1, doc.FindObjects( "RenderMeshFile" ).Count );
		Assert.AreEqual( 1, doc.FindObjects( "PhysicsHullFromRender" ).Count );
		Assert.AreEqual( 1, doc.FindObjects( "RenderMeshList" ).Count );
		Assert.AreEqual( 1, doc.FindObjects( "PhysicsShapeList" ).Count );

		var mesh = doc.FindObjects( "RenderMeshFile" ).Single();
		Assert.AreEqual( "models/foo.fbx", ((Kv3Scalar)mesh.FindField( "filename" ).Value).Value );
		Assert.AreEqual( "0.3937", ((Kv3Scalar)mesh.FindField( "import_scale" ).Value).Value );
		Assert.AreEqual( "BoundsCenter", ((Kv3Scalar)mesh.FindField( "align_origin_x_type" ).Value).Value );
		Assert.AreEqual( "BoundsMin", ((Kv3Scalar)mesh.FindField( "align_origin_z_type" ).Value).Value );

		// Collision must carry the same align origin.
		var hull = doc.FindObjects( "PhysicsHullFromRender" ).Single();
		Assert.AreEqual( "BoundsCenter", ((Kv3Scalar)hull.FindField( "align_origin_x_type" ).Value).Value );
		Assert.AreEqual( "BoundsCenter", ((Kv3Scalar)hull.FindField( "align_origin_y_type" ).Value).Value );
		Assert.AreEqual( "BoundsMin", ((Kv3Scalar)hull.FindField( "align_origin_z_type" ).Value).Value );
	}

	[TestMethod]
	public void GeneratesMeshCollision()
	{
		var options = new MeshToModelOptions
		{
			Collision = CollisionMode.Mesh,
			ImportScale = 1.0f
		};

		var source = VmdlGenerator.Generate( "models/foo.fbx", options );
		var doc = Kv3Document.Parse( source );
		Assert.AreEqual( 1, doc.FindObjects( "PhysicsMeshFromRender" ).Count );
		Assert.AreEqual( 0, doc.FindObjects( "PhysicsHullFromRender" ).Count );
	}

	[TestMethod]
	public void GeneratesFileCollision()
	{
		var options = new MeshToModelOptions
		{
			Collision = CollisionMode.File,
			ImportScale = 0.3937f
		};

		var source = VmdlGenerator.Generate( "models/foo.fbx", options );
		var doc = Kv3Document.Parse( source );
		Assert.AreEqual( 1, doc.FindObjects( "PhysicsHullFile" ).Count );

		var hull = doc.FindObjects( "PhysicsHullFile" ).Single();
		Assert.AreEqual( "models/foo.fbx", ((Kv3Scalar)hull.FindField( "filename" ).Value).Value );
		Assert.AreEqual( "0.3937", ((Kv3Scalar)hull.FindField( "import_scale" ).Value).Value );
	}

	[TestMethod]
	public void NoCollisionWhenNone()
	{
		var options = new MeshToModelOptions
		{
			Collision = CollisionMode.None,
			ImportScale = 1.0f
		};

		var source = VmdlGenerator.Generate( "models/foo.fbx", options );
		var doc = Kv3Document.Parse( source );
		Assert.AreEqual( 0, doc.FindObjects( "PhysicsShapeList" ).Count );
		Assert.AreEqual( 1, doc.FindObjects( "RenderMeshFile" ).Count );
	}

	[TestMethod]
	public void GeneratedVmdlIsEditableByBulkEditor()
	{
		var options = new MeshToModelOptions
		{
			Collision = CollisionMode.Hull,
			ImportScale = 0.3937f,
			AlignOriginX = AlignOrigin.BoundsCenter,
			AlignOriginY = AlignOrigin.BoundsCenter,
			AlignOriginZ = AlignOrigin.BoundsMin
		};

		var source = VmdlGenerator.Generate( "models/foo.fbx", options );

		// The generated file should load in the bulk editor and find its mesh entry.
		var editor = VmdlBulkEditor.Load( source );
		Assert.AreEqual( 1, editor.MeshEntryCount );

		// And a further bulk edit should work on it.
		var props = new MeshEntryProperties { ImportScale = 2.0f };
		Assert.IsTrue( editor.Apply( props ) );

		var parsed = Kv3Document.Parse( editor.Source );
		var mesh = parsed.FindObjects( "RenderMeshFile" ).Single();
		Assert.AreEqual( "2.0", ((Kv3Scalar)mesh.FindField( "import_scale" ).Value).Value );
	}
}