Skip to content

Commit

Permalink
Merge pull request #20 from lmcintyre/master
Browse files Browse the repository at this point in the history
Models, Materials, Textures, Terrain
  • Loading branch information
NotAdam authored Apr 5, 2021
2 parents 0edd570 + be90399 commit ac19b2a
Show file tree
Hide file tree
Showing 13 changed files with 1,696 additions and 0 deletions.
98 changes: 98 additions & 0 deletions src/Lumina/Data/Files/MdlFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using Lumina.Data.Parsing;
using Lumina.Data.Structs;
using Lumina.Extensions;

namespace Lumina.Data.Files {
public class MdlFile : FileResource {
public MdlStructs.ModelFileHeader FileHeader;
public MdlStructs.VertexDeclarationStruct[] VertexDeclarations;
public MdlStructs.ModelHeader ModelHeader;
public MdlStructs.ElementIdStruct[] ElementIds;
public MdlStructs.LodStruct[] Lods;
public MdlStructs.ExtraLodStruct[] ExtraLods;
public MdlStructs.MeshStruct[] Meshes;
public uint[] AttributeNameOffsets;
public MdlStructs.SubmeshStruct[] Submeshes;

public MdlStructs.TerrainShadowMeshStruct[] TerrainShadowMeshes;
public MdlStructs.TerrainShadowSubmeshStruct[] TerrainShadowSubmeshes;

public uint[] MaterialNameOffsets;
public uint[] BoneNameOffsets;
public MdlStructs.BoneTableStruct[] BoneTables;
public MdlStructs.ShapeStruct[] Shapes;
public MdlStructs.ShapeMeshStruct[] ShapeMeshes;
public MdlStructs.ShapeValueStruct[] ShapeValues;

public ushort[] SubmeshBoneMap;
public MdlStructs.BoundingBoxStruct BoundingBoxes;
public MdlStructs.BoundingBoxStruct ModelBoundingBoxes;
public MdlStructs.BoundingBoxStruct WaterBoundingBoxes;
public MdlStructs.BoundingBoxStruct VerticalFogBoundingBoxes;
public MdlStructs.BoundingBoxStruct[] BoneBoundingBoxes;

public ushort StringCount;
public byte[] Strings;

public override void LoadFile()
{
// We can ensure based on content-type that files are models
if( FileInfo.Type != FileType.Model )
{
Console.WriteLine( $"Attempted to load {FilePath} of content type {FileInfo.Type} as a model, returning..." );
return;
}

FileHeader = MdlStructs.ModelFileHeader.Read( Reader );

VertexDeclarations = new MdlStructs.VertexDeclarationStruct[FileHeader.VertexDeclarationCount];
for( int i = 0; i < FileHeader.VertexDeclarationCount; i++ ) VertexDeclarations[ i ] = MdlStructs.VertexDeclarationStruct.Read( Reader );

StringCount = Reader.ReadUInt16();
Reader.ReadUInt16();
uint stringSize = Reader.ReadUInt32();
Strings = Reader.ReadBytes( (int) stringSize );

ModelHeader = Reader.ReadStructure<MdlStructs.ModelHeader>();
ElementIds = new MdlStructs.ElementIdStruct[ModelHeader.ElementIdCount];
Meshes = new MdlStructs.MeshStruct[ModelHeader.MeshCount];
BoneTables = new MdlStructs.BoneTableStruct[ModelHeader.BoneTableCount];
Shapes = new MdlStructs.ShapeStruct[ModelHeader.ShapeCount];
BoneBoundingBoxes = new MdlStructs.BoundingBoxStruct[ModelHeader.BoneCount];

for( int i = 0; i < ModelHeader.ElementIdCount; i++ ) ElementIds[ i ] = MdlStructs.ElementIdStruct.Read( Reader );
Lods = Reader.ReadStructuresAsArray< MdlStructs.LodStruct >( 3 );

if( ModelHeader.ExtraLodEnabled )
ExtraLods = Reader.ReadStructuresAsArray< MdlStructs.ExtraLodStruct >( 3 );

for( int i = 0; i < ModelHeader.MeshCount; i++ ) Meshes[ i ] = MdlStructs.MeshStruct.Read( Reader );
AttributeNameOffsets = Reader.ReadStructures< UInt32 >( ModelHeader.AttributeCount ).ToArray();
TerrainShadowMeshes = Reader.ReadStructuresAsArray< MdlStructs.TerrainShadowMeshStruct >( ModelHeader.TerrainShadowMeshCount );
Submeshes = Reader.ReadStructuresAsArray< MdlStructs.SubmeshStruct >( ModelHeader.SubmeshCount );
TerrainShadowSubmeshes = Reader.ReadStructuresAsArray< MdlStructs.TerrainShadowSubmeshStruct >( ModelHeader.TerrainShadowSubmeshCount );

MaterialNameOffsets = Reader.ReadStructures< UInt32 >( ModelHeader.MaterialCount ).ToArray();
BoneNameOffsets = Reader.ReadStructures< UInt32 >( ModelHeader.BoneCount ).ToArray();
for( int i = 0; i < ModelHeader.BoneTableCount; i++ ) BoneTables[ i ] = MdlStructs.BoneTableStruct.Read( Reader );

for( int i = 0; i < ModelHeader.ShapeCount; i++ ) Shapes[ i ] = MdlStructs.ShapeStruct.Read( Reader );
ShapeMeshes = Reader.ReadStructuresAsArray< MdlStructs.ShapeMeshStruct >( ModelHeader.ShapeMeshCount );
ShapeValues = Reader.ReadStructuresAsArray< MdlStructs.ShapeValueStruct >( ModelHeader.ShapeValueCount );

uint submeshBoneMapSize = Reader.ReadUInt32();
SubmeshBoneMap = Reader.ReadStructures< UInt16 >( (int) submeshBoneMapSize / 2 ).ToArray();

byte paddingAmount = Reader.ReadByte();
Reader.Seek( Reader.BaseStream.Position + paddingAmount );

// Dunno what this first one is for?
BoundingBoxes = MdlStructs.BoundingBoxStruct.Read( Reader );
ModelBoundingBoxes = MdlStructs.BoundingBoxStruct.Read( Reader );
WaterBoundingBoxes = MdlStructs.BoundingBoxStruct.Read( Reader );
VerticalFogBoundingBoxes = MdlStructs.BoundingBoxStruct.Read( Reader );
for( int i = 0; i < ModelHeader.BoneCount; i++ ) BoneBoundingBoxes[ i ] = MdlStructs.BoundingBoxStruct.Read( Reader );
}
}
}
56 changes: 56 additions & 0 deletions src/Lumina/Data/Files/MtrlFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using Lumina.Data.Parsing;
using Lumina.Extensions;

namespace Lumina.Data.Files
{
public class MtrlFile : FileResource
{
public MaterialFileHeader FileHeader;
public MaterialHeader MaterialHeader;
public UvColorSet[] UvColorSets;
public TextureOffset[] TextureOffsets;
public int[] ColorSetOffsets;

// Will have to double check this, this is from TexTools
public ColorSetInfo ColorSetInfo;
public ColorSetDyeInfo ColorSetDyeInfo;

public ShaderKey[] ShaderKeys;
public Constant[] Constants;
public Sampler[] Samplers;

public float[] ShaderValues;
public byte[] Strings;

public override void LoadFile()
{
FileHeader = Reader.ReadStructure<MaterialFileHeader>();
TextureOffsets = Reader.ReadStructuresAsArray< TextureOffset >( FileHeader.TextureCount );

UvColorSets = Reader.ReadStructuresAsArray< UvColorSet >( FileHeader.UvSetCount );

ColorSetOffsets = Reader.ReadStructuresAsArray< Int32 >( FileHeader.ColorSetCount );

Strings = Reader.ReadBytes( FileHeader.StringTableSize );

// This seems to be a struct - do not know what it is
Reader.Seek(Reader.BaseStream.Position + FileHeader.AdditionalDataSize);

if( FileHeader.DataSetSize > 0 )
{
ColorSetInfo = Reader.ReadStructure< ColorSetInfo >();
if (FileHeader.DataSetSize > 512)
ColorSetDyeInfo = Reader.ReadStructure< ColorSetDyeInfo >();
}

MaterialHeader = Reader.ReadStructure< MaterialHeader >();

ShaderKeys = Reader.ReadStructuresAsArray< ShaderKey >( MaterialHeader.ShaderKeyCount );
Constants = Reader.ReadStructuresAsArray< Constant >( MaterialHeader.ConstantCount );
Samplers = Reader.ReadStructuresAsArray< Sampler >( MaterialHeader.SamplerCount );

ShaderValues = Reader.ReadStructuresAsArray< float >( MaterialHeader.ShaderValueListSize / 4 );
}
}
}
48 changes: 48 additions & 0 deletions src/Lumina/Data/Files/TeraFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Numerics;
using Lumina.Extensions;

namespace Lumina.Data.Files
{
struct PlatePos
{
public short x;
public short y;
}

public class TeraFile : FileResource
{
public uint Version;
public uint PlateCount;
public uint PlateSize;
public float ClipDistance;
public float Unknown;
public byte[] Padding;

private PlatePos[] _positions;

public override void LoadFile()
{
Version = Reader.ReadUInt32();
PlateCount = Reader.ReadUInt32();
PlateSize = Reader.ReadUInt32();
ClipDistance = Reader.ReadSingle();
Unknown = Reader.ReadSingle();
Padding = Reader.ReadBytes( 32 );

_positions = Reader.ReadStructuresAsArray< PlatePos >( (int) PlateCount );
}

/// <summary>
/// Retrieve the X and Z coordinates of the specified plate index. Note that
/// the Y coordinate is unnecessary as bg plates each contain all necessary vertical
/// data in their respective plate.
/// </summary>
/// <param name="plateIndex">The index of the bg plate to obtain the coordinates for.</param>
/// <returns></returns>
public Vector2 GetPlatePosition( int plateIndex )
{
var pos = _positions[ plateIndex ];
return new Vector2( PlateSize * ( pos.x + 0.5f ), PlateSize * ( pos.y + 0.5f ) );
}
}
}
Loading

0 comments on commit ac19b2a

Please sign in to comment.