Оптимизировать/распараллелить загрузку данных?C#

Место общения программистов C#
Ответить
Anonymous
 Оптимизировать/распараллелить загрузку данных?

Сообщение Anonymous »

Я занимаюсь реверс-инжинирингом игры Zelda: Twilight Princess для GameCube и воссоздаю ее в Unity. В частности, я анализирую двоичные файлы, содержащие данные о сетках, текстурах и материалах, для создания игровых объектов Unity с сетками и материалами.
Моя текущая реализация работает, но немного медленно. Одна простая область занимает около 100 мс. При создании всех NPC, объектов и т. д. это занимает до 2 секунд. При запуске игры я загружаю все эти двоичные файлы, при этом загрузка моего процессора в процессе загрузки довольно низкая (около 3% или около того). Я не знаю, как лучше структурировать задачи.
Вот упрощенная версия структуры моего кода:
Загрузите двоичный файл и проанализируйте заголовки.

[*]Для каждого «куска» (тега) в файле:
[*]Декодируйте тег (например, вершины) , текстуры, материалы).
[*]Сохраните проанализированные данные в соответствующих объектах (например, INF1, SHP1 и т. д.).
[*]После того, как все фрагменты проанализированы, создайте сетки и назначьте материалы в Unity.
< /ul>
Надеюсь, кто-нибудь сможет мне помочь!
Вот суть моей текущей реализации (урезанной для краткости):
public class BMD : MonoBehaviour
{
public string FullBMD = "";

public INF1 INF1Tag;
public VTX1 VTX1Tag;
public EVP1 EVP1Tag;
public DRW1 DRW1Tag;
public JNT1 JNT1Tag;
public SHP1 SHP1Tag;
public MAT3 MAT3Tag;
public TEX1 TEX1Tag;

public Material DefaultMaterial;

// This method takes 90ms to execute, so a faster loading process is required
void Start()
{
using (EndianBinaryReader reader = new EndianBinaryReader(File.ReadAllBytes(FullBMD), Endian.Big))
{
reader.Skip(8);

int size = reader.ReadInt32();
int numChunks = reader.ReadInt32();

reader.Skip(16);

for (int i = 0; i < numChunks; i++)
{
long tagStart = reader.BaseStream.Position;

string tagName = reader.ReadString(4);
int tagSize = reader.ReadInt32();

switch (tagName)
{
case "INF1":
INF1Tag = new INF1();
INF1Tag.LoadINF1FromStream(reader, tagStart);
break;
case "VTX1":
VTX1Tag = new VTX1();
VTX1Tag.LoadVTX1FromStream(reader, tagStart, tagSize);
break;
case "EVP1":
EVP1Tag = new EVP1();
EVP1Tag.LoadEVP1FromStream(reader, tagStart);
break;
case "DRW1":
DRW1Tag = new DRW1();
DRW1Tag.LoadDRW1FromStream(reader, tagStart);
break;
case "JNT1":
JNT1Tag = new JNT1();
JNT1Tag.LoadJNT1FromStream(reader, tagStart);
JNT1Tag.CalculateParentJointsForSkeleton(INF1Tag.HierarchyRoot);
break;
case "SHP1":
SHP1Tag = new SHP1();
SHP1Tag.ReadSHP1FromStream(reader, tagStart, VTX1Tag.VertexData);
break;
case "MAT3":
MAT3Tag = new MAT3();
MAT3Tag.LoadMAT3FromStream(reader, tagStart);
break;
case "TEX1":
TEX1Tag = new TEX1();
TEX1Tag.LoadTEX1FromStream(this, reader, tagStart, new List());
break;
case "MDL3":
break;
}
reader.BaseStream.Position = tagStart + tagSize;
}
// After loading data, create the meshes
CreateMeshes();
}
}

// This method takes 10ms to execute
private void CreateMeshes()
{
List meshFilters = new List();
List meshRenderers = new List();
List meshMaterials = new List();
List childs = new List();
foreach (SHP1.Shape shape in SHP1Tag.Shapes)
{
GameObject go = new GameObject("shape" + SHP1Tag.Shapes.IndexOf(shape));
childs.Add(go);

Material3 material = MAT3Tag.MaterialList[MAT3Tag.MaterialRemapTable[shape.MaterialIndex]];
BTI texture = TEX1Tag.BTIs[MAT3Tag.TextureRemapTable[baseTexture]];

List verts = shape.OverrideVertPos.Count > 0 ? shape.OverrideVertPos : shape.VertexData.Position;
List normals = shape.OverrideNormals.Count > 0 ? shape.OverrideNormals : shape.VertexData.Normal;

// Create mesh
Mesh mesh = new Mesh();
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
mesh.vertices = verts.ToArray();

int numVertices = verts.Count;
int numTriangles = numVertices / 3;

int[] triangles = new int[numTriangles * 3]; // Single sided
for (int i = 0; i < numTriangles; i++)
{
triangles[i * 3] = i * 3;
triangles[i * 3 + 1] = i * 3 + 1;
triangles[i * 3 + 2] = i * 3 + 2;
}
mesh.triangles = triangles;
mesh.normals = normals.ToArray();
mesh.uv = shape.VertexData.Tex0.ToArray();
mesh.colors = shape.VertexData.Color0.ToArray();

// Assign material to shader
Material mat = new Material(DefaultMaterial);
mat.mainTexture = texture.Texture;

MeshFilter filter = go.AddComponent();
filter.sharedMesh = mesh;

MeshRenderer renderer = go.AddComponent();
renderer.sharedMaterial = mat;

meshFilters.Add(filter);
meshRenderers.Add(renderer);
meshMaterials.Add(mat);
}

// Combine meshes
CombineMeshesToASingle();
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... ading-data
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»