Skip to content

Commit

Permalink
Added vertex mapping output to converter
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin113D committed Aug 3, 2024
1 parent d062dda commit 1ed76f8
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 27 deletions.
21 changes: 17 additions & 4 deletions src/SA3D.Modeling/Mesh/Converters/ChunkConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ protected override ChunkResult ConvertWeighted(WeightedMesh wba, bool optimize)
}
}

protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize)
protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize, out int[]? vertexMapping)
{
ChunkVertex[] vertices;
ChunkCorner[][] cornerSets = new ChunkCorner[wba.TriangleSets.Length][];
Expand All @@ -453,6 +453,7 @@ protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize
{
type = VertexChunkType.Diffuse;
List<ChunkVertex> colorVertices = [];
List<int> colorVertexMapping = [];
for(int i = 0; i < wba.TriangleSets.Length; i++)
{
BufferCorner[] bufferCorners = wba.TriangleSets[i];
Expand All @@ -466,12 +467,13 @@ protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize

WeightedVertex vertex = wba.Vertices[bc.VertexIndex];
colorVertices.Add(new(vertex.Position, bc.Color, Color.ColorWhite));
colorVertexMapping.Add(bc.VertexIndex);
}

cornerSets[i] = corners;
}

// first, get rid of all duplicate vertices
// get rid of all duplicate vertices
if(colorVertices.TryCreateDistinctMap(out DistinctMap<ChunkVertex> distinctVerts))
{
for(int i = 0; i < cornerSets.Length; i++)
Expand All @@ -482,6 +484,16 @@ protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize
corners[j].Index = distinctVerts[corners[j].Index];
}
}

vertexMapping = new int[distinctVerts.Values.Count];
for(int i = 0; i < colorVertexMapping.Count; i++)
{
vertexMapping[distinctVerts.Map![i]] = colorVertexMapping[i];
}
}
else
{
vertexMapping = colorVertexMapping.ToArray();
}

vertices = distinctVerts.ValueArray;
Expand All @@ -490,6 +502,7 @@ protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize
{
type = VertexChunkType.Normal;
vertices = new ChunkVertex[wba.Vertices.Length];
vertexMapping = null;
// converting the vertices 1:1, with normal information
for(int i = 0; i < wba.Vertices.Length; i++)
{
Expand Down Expand Up @@ -648,9 +661,9 @@ protected override Attach CombineAttaches(List<Attach> attaches, string label)
}
}

public static void ConvertWeightedToChunk(Node model, WeightedMesh[] meshData, bool optimize)
public static void ConvertWeightedToChunk(Node model, WeightedMesh[] meshData, bool optimize, out int[]?[] vertexMapping)
{
new OffsettableChunkConverter().Convert(model, meshData, optimize);
new OffsettableChunkConverter().Convert(model, meshData, optimize, out vertexMapping);
}

#region Convert to Buffer
Expand Down
9 changes: 5 additions & 4 deletions src/SA3D.Modeling/Mesh/Converters/FromWeightedConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,12 @@ protected override BufferResult ConvertWeighted(WeightedMesh wba, bool optimize)
attaches);
}

protected override BufferResult ConvertWeightless(WeightedMesh wba, bool optimize)
protected override BufferResult ConvertWeightless(WeightedMesh wba, bool optimize, out int[]? vertexMapping)
{
List<BufferMesh> meshes = [];

BufferVertex[] vertices = new BufferVertex[wba.Vertices.Length];
vertexMapping = null;

for(int i = 0; i < vertices.Length; i++)
{
Expand All @@ -141,7 +142,7 @@ protected override BufferResult ConvertWeightless(WeightedMesh wba, bool optimiz
vertices.Length,
false,
wba.RootIndices.ToArray(),
new Attach[] { new(result) });
[new(result)]);
}

private static BufferMesh[] GetPolygonMeshes(WeightedMesh wba, bool optimize)
Expand Down Expand Up @@ -215,9 +216,9 @@ protected override Attach CombineAttaches(List<Attach> attaches, string label)

}

public static void Convert(Node model, WeightedMesh[] meshData, bool optimize)
public static void Convert(Node model, WeightedMesh[] meshData, bool optimize, out int[]?[] vertexMapping)
{
new OffsettableBufferConverter().Convert(model, meshData, optimize);
new OffsettableBufferConverter().Convert(model, meshData, optimize, out vertexMapping);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ public static bool BufferWeldedBasicModel(Node model, bool optimize)
}
}

WeightedMesh.ToModel(model, weightedMeshes, AttachFormat.Buffer, optimize);
WeightedMesh.ToModel(model, weightedMeshes, AttachFormat.Buffer, optimize, out _);

foreach(KeyValuePair<Node, BasicAttach> nodeAttach in attachLUT)
{
Expand Down
21 changes: 12 additions & 9 deletions src/SA3D.Modeling/Mesh/Converters/OffsetableAttachConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace SA3D.Modeling.Mesh.Converters
{
internal abstract class OffsetableAttachConverter<TResult> where TResult : IOffsetableAttachResult
{
protected abstract TResult ConvertWeightless(WeightedMesh wba, bool optimize);
protected abstract TResult ConvertWeightless(WeightedMesh wba, bool optimize, out int[]? vertexMapping);

protected abstract TResult ConvertWeighted(WeightedMesh wba, bool optimize);

Expand All @@ -20,16 +20,19 @@ internal abstract class OffsetableAttachConverter<TResult> where TResult : IOffs

protected abstract Attach CombineAttaches(List<Attach> attaches, string label);

public void Convert(Node model, WeightedMesh[] meshData, bool optimize)
public void Convert(Node model, WeightedMesh[] meshData, bool optimize, out int[]?[] vertexMapping)
{
List<TResult> results = [];
vertexMapping = new int[]?[meshData.Length];
(Node node, Matrix4x4 worldMatrix)[] nodeMatrices = model.GetWorldMatrixTree();

foreach(WeightedMesh wba in meshData)
for(int i = 0; i < meshData.Length; i++)
{
WeightedMesh wba = meshData[i];

if(!wba.IsWeighted)
{
results.Add(ConvertWeightless(wba, optimize));
results.Add(ConvertWeightless(wba, optimize, out vertexMapping[i]));
}
else
{
Expand All @@ -39,18 +42,18 @@ void CorrectVertices(int rootIndex, int[] attachIndices, Attach[] attaches)
{
Matrix4x4 baseMatrix = nodeMatrices[rootIndex].worldMatrix;

for(int i = 0; i < attachIndices.Length; i++)
for(int j = 0; j < attachIndices.Length; j++)
{
int nodeIndex = result.AttachIndices[i] + rootIndex;
attachIndices[i] = nodeIndex;
int nodeIndex = result.AttachIndices[j] + rootIndex;
attachIndices[j] = nodeIndex;

Matrix4x4 nodeMatrix = nodeMatrices[nodeIndex].worldMatrix;
Matrix4x4.Invert(nodeMatrix, out Matrix4x4 invNodeMatrix);
Matrix4x4 vertexMatrix = baseMatrix * invNodeMatrix;
Matrix4x4 normalMatrix = vertexMatrix.GetNormalMatrix();

CorrectSpace(attaches[i], vertexMatrix, normalMatrix);
attaches[i].RecalculateBounds();
CorrectSpace(attaches[j], vertexMatrix, normalMatrix);
attaches[j].RecalculateBounds();
}
}

Expand Down
18 changes: 13 additions & 5 deletions src/SA3D.Modeling/Mesh/Weighted/WeightedMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -314,16 +314,19 @@ private static void GetTexcoordPrecisionLevel(Node model, WeightedMesh[] meshes,
/// </summary>
/// <param name="format">Attach format to convert to.</param>
/// <param name="optimize">Whether to optimize the mesh info.</param>
/// <param name="vertexMapping">Vertex index mapping for formats, where vertices may rearrange.
/// <br/> If a meshes vertices have been rearranged (weighted meshes excluded), then the mapping is set up like:
/// <code>vertexMapping[mesh_index][new_vertex_index] = old_vertex_index</code></param>
/// <returns>The converted attach.</returns>
/// <exception cref="InvalidOperationException"></exception>
public Attach ToAttach(AttachFormat format, bool optimize)
public Attach ToAttach(AttachFormat format, bool optimize, out int[]?[] vertexMapping)
{
HashSet<int> backup = new(RootIndices);
RootIndices.Clear();
RootIndices.Add(0);

Node dummy = new();
ToModel(dummy, new[] { this }, format, optimize);
ToModel(dummy, [this], format, optimize, out vertexMapping);

RootIndices.Clear();
RootIndices.UnionWith(backup);
Expand All @@ -338,23 +341,28 @@ public Attach ToAttach(AttachFormat format, bool optimize)
/// <param name="meshes">Meshes to convert.</param>
/// <param name="format">Attach format to convert to.</param>
/// <param name="optimize">Whether to optimize the mesh info.</param>
public static void ToModel(Node model, WeightedMesh[] meshes, AttachFormat format, bool optimize)
/// <param name="vertexMapping">Vertex index mapping for formats, where vertices may rearrange.
/// <br/> If a meshes vertices have been rearranged (weighted meshes excluded), then the mapping is set up like:
/// <code>vertexMapping[mesh_index][new_vertex_index] = old_vertex_index</code></param>
public static void ToModel(Node model, WeightedMesh[] meshes, AttachFormat format, bool optimize, out int[]?[] vertexMapping)
{
EnsurePolygonsValid(ref meshes);

switch(format)
{
case AttachFormat.Buffer:
FromWeightedConverter.Convert(model, meshes, optimize);
FromWeightedConverter.Convert(model, meshes, optimize, out vertexMapping);
break;
case AttachFormat.BASIC:
BasicConverter.ConvertWeightedToBasic(model, meshes, optimize);
vertexMapping = new int[]?[meshes.Length];
break;
case AttachFormat.CHUNK:
ChunkConverter.ConvertWeightedToChunk(model, meshes, optimize);
ChunkConverter.ConvertWeightedToChunk(model, meshes, optimize, out vertexMapping);
break;
case AttachFormat.GC:
GCConverter.ConvertWeightedToGC(model, meshes, optimize);
vertexMapping = new int[]?[meshes.Length];
break;
default:
throw new ArgumentException("Invalid attach format.", nameof(format));
Expand Down
2 changes: 1 addition & 1 deletion src/SA3D.Modeling/ObjectData/Node.Attach.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public void ConvertAttachFormat(
BasicConverter.ConvertWeightedToBasic(rootNode, weightedMeshes, optimize);
break;
case AttachFormat.CHUNK:
ChunkConverter.ConvertWeightedToChunk(rootNode, weightedMeshes, optimize);
ChunkConverter.ConvertWeightedToChunk(rootNode, weightedMeshes, optimize, out _);
break;
case AttachFormat.GC:
GCConverter.ConvertWeightedToGC(rootNode, weightedMeshes, optimize);
Expand Down
2 changes: 0 additions & 2 deletions src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,6 @@ SA3D.Modeling.Mesh.Weighted.WeightedMesh.Materials.get -> SA3D.Modeling.Mesh.Buf
SA3D.Modeling.Mesh.Weighted.WeightedMesh.RootIndices.get -> System.Collections.Generic.HashSet<int>!
SA3D.Modeling.Mesh.Weighted.WeightedMesh.TexcoordPrecisionLevel.get -> byte
SA3D.Modeling.Mesh.Weighted.WeightedMesh.TexcoordPrecisionLevel.set -> void
SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToAttach(SA3D.Modeling.Mesh.AttachFormat format, bool optimize) -> SA3D.Modeling.Mesh.Attach!
SA3D.Modeling.Mesh.Weighted.WeightedMesh.TriangleSets.get -> SA3D.Modeling.Mesh.Buffer.BufferCorner[]![]!
SA3D.Modeling.Mesh.Weighted.WeightedMesh.Vertices.get -> SA3D.Modeling.Mesh.Weighted.WeightedVertex[]!
SA3D.Modeling.Mesh.Weighted.WeightedMesh.WriteSpecular.get -> bool
Expand Down Expand Up @@ -1887,7 +1886,6 @@ static SA3D.Modeling.Mesh.Weighted.WeightedMesh.FromAttach(SA3D.Modeling.Mesh.At
static SA3D.Modeling.Mesh.Weighted.WeightedMesh.FromModel(SA3D.Modeling.ObjectData.Node! model, SA3D.Modeling.Mesh.Weighted.BufferMode bufferMode) -> SA3D.Modeling.Mesh.Weighted.WeightedMesh![]!
static SA3D.Modeling.Mesh.Weighted.WeightedMesh.MergeAtRoots(SA3D.Modeling.Mesh.Weighted.WeightedMesh![]! meshes) -> SA3D.Modeling.Mesh.Weighted.WeightedMesh![]!
static SA3D.Modeling.Mesh.Weighted.WeightedMesh.MergeWeightedMeshes(System.Collections.Generic.IEnumerable<SA3D.Modeling.Mesh.Weighted.WeightedMesh!>! meshes) -> SA3D.Modeling.Mesh.Weighted.WeightedMesh!
static SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToModel(SA3D.Modeling.ObjectData.Node! model, SA3D.Modeling.Mesh.Weighted.WeightedMesh![]! meshes, SA3D.Modeling.Mesh.AttachFormat format, bool optimize) -> void
static SA3D.Modeling.Mesh.Weighted.WeightedVertex.operator !=(SA3D.Modeling.Mesh.Weighted.WeightedVertex left, SA3D.Modeling.Mesh.Weighted.WeightedVertex right) -> bool
static SA3D.Modeling.Mesh.Weighted.WeightedVertex.operator ==(SA3D.Modeling.Mesh.Weighted.WeightedVertex left, SA3D.Modeling.Mesh.Weighted.WeightedVertex right) -> bool
static SA3D.Modeling.ObjectData.Enums.EnumExtensions.CheckIsCollision(this SA3D.Modeling.ObjectData.Enums.SurfaceAttributes attributes) -> bool
Expand Down
3 changes: 2 additions & 1 deletion src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@

SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToAttach(SA3D.Modeling.Mesh.AttachFormat format, bool optimize, out int[]?[]! vertexMapping) -> SA3D.Modeling.Mesh.Attach!
static SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToModel(SA3D.Modeling.ObjectData.Node! model, SA3D.Modeling.Mesh.Weighted.WeightedMesh![]! meshes, SA3D.Modeling.Mesh.AttachFormat format, bool optimize, out int[]?[]! vertexMapping) -> void

0 comments on commit 1ed76f8

Please sign in to comment.