/// <summary> /// Export a Valve VWNOD to GLTF. /// </summary> /// <param name="resourceName">The name of the resource being exported.</param> /// <param name="fileName">Target file name.</param> /// <param name="worldNode">The worldNode resource to export.</param> public void ExportToFile(string resourceName, string fileName, VWorldNode worldNode) { if (FileLoader == null) { throw new InvalidOperationException(nameof(FileLoader) + " must be set first."); } DstDir = Path.GetDirectoryName(fileName); var exportedModel = CreateModelRoot(resourceName, out var scene); var worldNodeModels = LoadWorldNodeModels(worldNode); foreach (var(Model, Name, Transform) in worldNodeModels) { var meshes = LoadModelMeshes(Model, Name); for (var i = 0; i < meshes.Length; i++) { var node = AddMeshNode(exportedModel, scene, Model, meshes[i].Name, meshes[i].Mesh, Model.GetSkeleton(i)); if (node == null) { continue; } // Swap Rotate upright, scale inches to meters, after local transform. node.WorldMatrix = Transform * TRANSFORMSOURCETOGLTF; } } WriteModelFile(exportedModel, fileName); }
private IList <(VModel Model, string ModelName, Matrix4x4 Transform)> LoadWorldNodeModels(VWorldNode worldNode) { var sceneObjects = worldNode.Data.GetArray("m_sceneObjects"); var models = new List <(VModel, string, Matrix4x4)>(); foreach (var sceneObject in sceneObjects) { var renderableModel = sceneObject.GetProperty <string>("m_renderableModel"); if (renderableModel == null) { continue; } var modelResource = FileLoader.LoadFile(renderableModel + "_c"); if (modelResource == null) { continue; } var model = (VModel)modelResource.DataBlock; var matrix = sceneObject.GetArray("m_vTransform").ToMatrix4x4(); models.Add((model, Path.GetFileNameWithoutExtension(renderableModel), matrix)); } return(models); }