Skip to content

Commit

Permalink
Merge pull request #67 from NotAdam/xande
Browse files Browse the repository at this point in the history
Pull in what we have for Xande so far
  • Loading branch information
NotAdam authored Sep 11, 2023
2 parents 5710f32 + 98db98e commit 2e08df7
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 24 deletions.
18 changes: 14 additions & 4 deletions src/Lumina/Data/Parsing/MdlStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,15 +337,25 @@ public static ShapeStruct Read( LuminaBinaryReader br )

public struct ShapeMeshStruct
{
public uint StartIndex;
/// <summary>
/// From TT: The offset to the index block this Shape Data should be replacing in.
/// This is how Shape Data is tied to each mesh.
/// </summary>
public uint MeshIndexOffset;
public uint ShapeValueCount;
public uint ShapeValueOffset;
}

public struct ShapeValueStruct
{
public ushort Offset;
public ushort Value;
/// <summary>
/// PROBABLY: Index into the Indices array of a mesh.
/// </summary>
public ushort BaseIndicesIndex;
/// <summary>
/// PROBABLY: Index into the (without transformation probably unused) vertex of a mesh.
/// </summary>
public ushort ReplacingVertexIndex;
}

public struct BoundingBoxStruct
Expand All @@ -362,4 +372,4 @@ public static BoundingBoxStruct Read( LuminaBinaryReader br )
}
}
}
}
}
9 changes: 7 additions & 2 deletions src/Lumina/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,11 @@ public GameData( string dataPath, ILogger logger, LuminaOptions? options = null!
/// Load a defined file given a filesystem path
/// </summary>
/// <param name="path">A relative or absolute path to the file to load</param>
/// <param name="origPath">The original file path in SqPack, required for reading some files (e.g. materials)</param>
/// <typeparam name="T">The type of <see cref="FileResource"/> to load the raw file in to</typeparam>
/// <returns>The requested file if found, null if not</returns>
/// <exception cref="FileNotFoundException">The path given doesn't point to an existing file</exception>
public T GetFileFromDisk< T >( string path ) where T : FileResource
public T GetFileFromDisk< T >( string path, string? origPath = null ) where T : FileResource
{
SetCurrentContext();

Expand All @@ -206,6 +207,10 @@ public T GetFileFromDisk< T >( string path ) where T : FileResource

var file = Activator.CreateInstance< T >();
file.Data = fileContent;
if( origPath != null )
{
file.FilePath = ParseFilePath( origPath )!;
}
file.Reader = new LuminaBinaryReader( file.Data, Options.CurrentPlatform );
file.LoadFile();

Expand Down Expand Up @@ -320,4 +325,4 @@ internal static void SetCurrentContext( GameData gameData )
CurrentContext = new(() => gameData);
}
}
}
}
3 changes: 1 addition & 2 deletions src/Lumina/Models/Models/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ private void ReadVertices()
MdlStructs.VertexDeclarationStruct currentDecl = Parent.File.VertexDeclarations[ MeshIndex ];

// We have to go through these in order by offset with this implementation
var orderedElements = currentDecl.VertexElements.ToList();
orderedElements.Sort( ( e1, e2 ) => e1.Offset.CompareTo( e2.Offset ) );
var orderedElements = currentDecl.VertexElements.OrderBy( e => e.Offset ).ToList();
Vertices = new Vertex[currentMesh.VertexCount];

// Vertices may be defined across at most 3 streams defined by a Mesh's VertexDeclarations
Expand Down
17 changes: 11 additions & 6 deletions src/Lumina/Models/Models/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private void BuildModel()
ReadStrings();
ReadMaterials();
ReadMeshes();
ReadShapes();
ReadShapes( Meshes );
}

/// <summary>
Expand Down Expand Up @@ -127,14 +127,19 @@ private void ReadMaterials()
}
}

private void ReadShapes()
private void ReadShapes( IReadOnlyList< Mesh > meshes )
{
if( File == null )
{
return;
}

var shapeMeshes = ShapeMesh.ConstructList( File, meshes );
Shapes = new Dictionary< string, Shape >();
for( int i = 0; i < File?.Shapes.Length; i++ )
{
// We will need more info in the constructor here... eventually
var shape = new Shape( this, i );
Shapes[ shape.ShapeName ] = shape;
var shape = new Shape( this, Lod, shapeMeshes, i );
Shapes[ shape.Name ] = shape;
}
}

Expand Down Expand Up @@ -250,4 +255,4 @@ public Mesh[] GetMeshesByType( Mesh.MeshType mp )
return Meshes.Where( m => m.Types.Contains( mp ) ).ToArray();
}
}
}
}
56 changes: 47 additions & 9 deletions src/Lumina/Models/Models/Shape.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,54 @@
using System.Collections.Generic;
using System.Linq;
using Lumina.Data.Files;

namespace Lumina.Models.Models
{
public class Shape
{
public string ShapeName { get; private set; }
public struct ShapeMesh {
public Mesh AssociatedMesh;

public ( ushort BaseIndicesIndex, ushort ReplacedVertexIndex )[] Values;

public static IReadOnlyList< ShapeMesh > ConstructList( MdlFile file, IReadOnlyList< Mesh > meshes )
{
var ret = new ShapeMesh[ file.ModelHeader.ShapeMeshCount ];
var idx = 0;

var meshDict = meshes.ToDictionary( m => file.Meshes[ m.MeshIndex ].StartIndex, m => m );

foreach( var shapeMeshStruct in file.ShapeMeshes ) {

if( !meshDict.TryGetValue( shapeMeshStruct.MeshIndexOffset, out var mesh ) ) continue;

var values = Enumerable
.Range( (int)shapeMeshStruct.ShapeValueOffset, (int)shapeMeshStruct.ShapeValueCount )
.Select( i => ( file.ShapeValues[ i ].BaseIndicesIndex, file.ShapeValues[ i ].ReplacingVertexIndex ) )
.ToArray();

ret[ idx++ ] = new ShapeMesh {
AssociatedMesh = mesh,
Values = values,
};
}

return ret;
}
}

public class Shape {
public string Name { get; private set; }
public ShapeMesh[] Meshes { get; private set; }

public Shape(Model model, int shapeIndex)
public Shape( Model model, Model.ModelLod lod, IReadOnlyList< ShapeMesh > shapeMeshes, int shapeIndex )
{
var currentShape = model.File.Shapes[ shapeIndex ];

Check warning on line 44 in src/Lumina/Models/Models/Shape.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Dereference of a possibly null reference.
ShapeName = model.StringOffsetToStringMap[ (int) currentShape.StringOffset ];

// TODO: shape index modifier things
// someone else do this pls
Name = model.StringOffsetToStringMap[ (int)currentShape.StringOffset ];
Meshes = new ShapeMesh[ currentShape.ShapeMeshCount[ (int)lod ] ];
var end = currentShape.ShapeMeshCount[ (int)lod ];
var offset = currentShape.ShapeMeshStartIndex[ (int)lod ];
for( var i = 0; i < end; ++i ) {
Meshes[ i ] = shapeMeshes[ i + offset ];
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/Lumina/Models/Models/Submesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Submesh( Model model, int meshIndex, int subMeshIndex )
int subMeshListIndex = currentMesh.SubMeshIndex + subMeshIndex;
var currentSubMesh = model.File.Submeshes[ subMeshListIndex ];

IndexOffset = currentSubMesh.IndexOffset;
IndexOffset = currentSubMesh.IndexOffset - currentMesh.StartIndex;
IndexNum = currentSubMesh.IndexCount;

// AttributeIndexMask is a bit-based index mask
Expand Down

0 comments on commit 2e08df7

Please sign in to comment.