-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathPMXProjectTextures.cs
More file actions
116 lines (103 loc) · 4.57 KB
/
Copy pathPMXProjectTextures.cs
File metadata and controls
116 lines (103 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using UMT;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace UMT.Editor
{
/// <summary>
/// Editor texture loader that resolves a PMX model's texture paths to project <see cref="Texture2D"/> assets through the <see cref="AssetDatabase"/> for the editor import path.
/// </summary>
public static class PMXProjectTextures
{
/// <summary>
/// Loads each PMX texture into a texture-index map of project <see cref="Texture2D"/> assets, resolving paths relative to the source asset directory and falling back to a recursive file-name search.
/// </summary>
/// <param name="model">PMX model providing the texture paths to resolve.</param>
/// <param name="sourceAssetPath">Project path of the source PMX asset used as the texture lookup base.</param>
/// <returns>An array of project textures indexed by PMX texture index; unresolved entries are <c>null</c>.</returns>
public static Texture2D[] Load(PMXModel model, string sourceAssetPath)
{
HashSet<string> textureWarnings = new HashSet<string>(StringComparer.Ordinal);
Texture2D[] texturesByIndex = new Texture2D[model.texturePaths.Length];
for (int i = 0; i < model.texturePaths.Length; ++i)
{
texturesByIndex[i] = LoadTexture(model, i, sourceAssetPath, textureWarnings);
}
return texturesByIndex;
}
private static Texture2D LoadTexture(PMXModel model, int textureIndex, string sourceAssetPath, ISet<string> warnings)
{
if (textureIndex < 0 || textureIndex >= model.texturePaths.Length)
{
return null;
}
string texturePath = model.texturePaths[textureIndex].ToString();
if (string.IsNullOrWhiteSpace(texturePath))
{
return null;
}
string sourceDirectory = Path.GetDirectoryName(sourceAssetPath)?.Replace('\\', '/') ?? "Assets";
string[] candidates = new[]
{
$"{sourceDirectory}/{texturePath}",
$"{sourceDirectory}/{texturePath.Replace('\\', '/')}",
$"{sourceDirectory}/{texturePath.Replace('/', '\\')}".Replace('\\', '/'),
};
HashSet<string> visitedCandidates = new HashSet<string>(StringComparer.Ordinal);
foreach (string candidate in candidates)
{
if (!visitedCandidates.Add(candidate))
{
continue;
}
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(candidate);
if (texture != null)
{
return texture;
}
}
string fileName = Path.GetFileName(texturePath);
if (string.IsNullOrEmpty(fileName))
{
AddTextureWarning(warnings, $"Texture path has no file name: {texturePath}");
return null;
}
string sourceFullPath = Path.GetFullPath(sourceDirectory);
if (!Directory.Exists(sourceFullPath))
{
AddTextureWarning(warnings, $"Texture source directory was not found: {sourceDirectory}");
return null;
}
foreach (string file in Directory.GetFiles(sourceFullPath, "*", SearchOption.AllDirectories))
{
if (!string.Equals(Path.GetFileName(file), fileName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
string assetPath = ToAssetPath(file);
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
if (texture != null)
{
return texture;
}
}
AddTextureWarning(warnings, $"Texture asset was not found: {texturePath} (source: {sourceAssetPath})");
return null;
}
private static void AddTextureWarning(ISet<string> warnings, string message)
{
if (warnings != null && !warnings.Add(message))
{
return;
}
Debug.LogWarning($"[PMX Unity Import] {message}");
}
private static string ToAssetPath(string fullPath)
{
string projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, "..")).Replace('\\', '/');
return Path.GetFullPath(fullPath).Replace('\\', '/').Replace(projectRoot + "/", "");
}
}
}