public MeshExporter(USkeletalMesh originalMesh, ELodFormat lodFormat = ELodFormat.FirstLod, bool exportMaterials = true) { _meshName = originalMesh.Owner?.Name ?? originalMesh.Name; if (!originalMesh.TryConvert(out var convertedMesh) || convertedMesh.LODs.Length <= 0) { Log.Logger.Warning($"Mesh '{_meshName}' has no LODs"); _meshLods = new Mesh[0]; return; } _meshLods = new Mesh[lodFormat == ELodFormat.AllLods ? convertedMesh.LODs.Length : 1]; for (var i = 0; i < _meshLods.Length; i++) { if (convertedMesh.LODs[i].Sections.Value.Length <= 0 || convertedMesh.LODs[i].Indices.Value == null) { Log.Logger.Warning($"LOD {i} in mesh '{_meshName}' has no section"); continue; } var usePskx = convertedMesh.LODs[i].NumVerts > 65536; using var writer = new FCustomArchiveWriter(); var materialExports = exportMaterials ? new List <MaterialExporter>() : null; ExportSkeletalMeshLod(convertedMesh.LODs[i], convertedMesh.RefSkeleton, writer, materialExports); _meshLods[i] = new Mesh($"{_meshName}_LOD{i}.psk{(usePskx ? 'x' : "")}", writer.GetBuffer(), materialExports ?? new List <MaterialExporter>()); } }
public MeshExporter(UStaticMesh originalMesh, ELodFormat lodFormat = ELodFormat.FirstLod, bool exportMaterials = true, EMeshFormat meshFormat = EMeshFormat.ActorX, ETexturePlatform platform = ETexturePlatform.DesktopMobile) { MeshLods = new List <Mesh>(); MeshName = originalMesh.Owner?.Name ?? originalMesh.Name; if (!originalMesh.TryConvert(out var convertedMesh) || convertedMesh.LODs.Count == 0) { Log.Logger.Warning($"Mesh '{MeshName}' has no LODs"); return; } var i = 0; foreach (var lod in convertedMesh.LODs) { if (lod.SkipLod) { Log.Logger.Warning($"LOD {i} in mesh '{MeshName}' should be skipped"); continue; } using var Ar = new FArchiveWriter(); var materialExports = exportMaterials ? new List <MaterialExporter>() : null; string ext; switch (meshFormat) { case EMeshFormat.ActorX: ext = "pskx"; ExportStaticMeshLods(lod, Ar, materialExports); break; case EMeshFormat.Gltf2: ext = "glb"; new Gltf(MeshName.SubstringAfterLast("/"), lod, materialExports).Save(meshFormat, Ar); break; case EMeshFormat.OBJ: ext = "obj"; new Gltf(MeshName.SubstringAfterLast("/"), lod, materialExports).Save(meshFormat, Ar); break; default: throw new ArgumentOutOfRangeException(nameof(meshFormat), meshFormat, null); } MeshLods.Add(new Mesh($"{MeshName}_LOD{i}.{ext}", Ar.GetBuffer(), materialExports ?? new List <MaterialExporter>())); if (lodFormat == ELodFormat.FirstLod) { break; } i++; } }