Пример #1
0
        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>());
            }
        }
Пример #2
0
        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++;
            }
        }