Я занимаюсь реверс-инжинирингом игры 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
Оптимизировать/распараллелить загрузку данных? ⇐ C#
Место общения программистов C#
-
Anonymous
1735318375
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();
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79312338/optimize-parallelize-loading-data[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия