// Returns meshes in meters, in the proper basis, with proper winding static IEnumerable <ModelMesh> GetModelMeshesFromGameObject(GameObject obj, SceneStatePayload payload, bool reverseWinding) { int i = -1; string exportName = obj.name; foreach (MeshData data in VisitMeshes(obj)) { i++; var mesh = data.mesh; for (int sm = 0; sm < mesh.subMeshCount; sm++) { var exportableMaterial = GetMaterialForMeshData(data); // TODO: The geometry pools could be aggregated, for faster downstream rendering. var geo = new GeometryPool(); geo.Layout = exportableMaterial.VertexLayout; geo.Append(mesh, geo.Layout); // Important: This transform should only be applied once, since the pools are shared, and // cannot include any mesh-local transformations. ExportUtils.ConvertToMetersAndChangeBasis(geo, ExportUtils.GetBasisMatrix(payload)); if (reverseWinding) { // Note: this triangle flip intentionally un-does the Unity FBX import flip. ExportUtils.ReverseTriangleWinding(geo, 1, 2); } var objectMesh = new ModelMesh { model = null, // The model is only used for uniquefying the texture names. name = exportName + "_" + i + "_" + sm, id = data.renderer.gameObject.GetInstanceID(), pool = geo, xform = ExportUtils.ChangeBasisNonUniformScale(payload, data.renderer.localToWorldMatrix), exportableMaterial = exportableMaterial, meshIndex = i }; yield return(objectMesh); } } }