mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 21:24:18 +01:00
Calculate primary BoundingBox
This commit is contained in:
parent
eb02d2a7a7
commit
4b81b065aa
4 changed files with 60 additions and 1 deletions
33
Penumbra/Import/Models/Import/BoundingBox.cs
Normal file
33
Penumbra/Import/Models/Import/BoundingBox.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Lumina.Data.Parsing;
|
||||||
|
|
||||||
|
namespace Penumbra.Import.Models.Import;
|
||||||
|
|
||||||
|
/// <summary> Mutable representation of the bounding box surrouding a collection of vertices. </summary>
|
||||||
|
public class BoundingBox
|
||||||
|
{
|
||||||
|
private Vector3 _minimum = Vector3.Zero;
|
||||||
|
private Vector3 _maximum = Vector3.Zero;
|
||||||
|
|
||||||
|
/// <summary> Use the specified position to update this bounding box, expanding it if necessary. </summary>
|
||||||
|
public void Merge(Vector3 position)
|
||||||
|
{
|
||||||
|
_minimum = Vector3.Min(_minimum, position);
|
||||||
|
_maximum = Vector3.Max(_maximum, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Merge the provided bounding box into this one, expanding it if necessary. </summary>
|
||||||
|
/// <param name="other"></param>
|
||||||
|
public void Merge(BoundingBox other)
|
||||||
|
{
|
||||||
|
_minimum = Vector3.Min(_minimum, other._minimum);
|
||||||
|
_maximum = Vector3.Max(_maximum, other._maximum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Convert this bounding box to the struct format used in .mdl data structures. </summary>
|
||||||
|
public MdlStructs.BoundingBoxStruct ToStruct()
|
||||||
|
=> new MdlStructs.BoundingBoxStruct
|
||||||
|
{
|
||||||
|
Min = [_minimum.X, _minimum.Y, _minimum.Z, 1],
|
||||||
|
Max = [_maximum.X, _maximum.Y, _maximum.Z, 1],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,8 @@ public class MeshImporter(IEnumerable<Node> nodes)
|
||||||
|
|
||||||
public List<string>? Bones;
|
public List<string>? Bones;
|
||||||
|
|
||||||
|
public BoundingBox BoundingBox;
|
||||||
|
|
||||||
public List<string> MetaAttributes;
|
public List<string> MetaAttributes;
|
||||||
|
|
||||||
public List<MeshShapeKey> ShapeKeys;
|
public List<MeshShapeKey> ShapeKeys;
|
||||||
|
|
@ -50,6 +52,8 @@ public class MeshImporter(IEnumerable<Node> nodes)
|
||||||
|
|
||||||
private List<string>? _bones;
|
private List<string>? _bones;
|
||||||
|
|
||||||
|
private readonly BoundingBox _boundingBox = new BoundingBox();
|
||||||
|
|
||||||
private readonly List<string> _metaAttributes = [];
|
private readonly List<string> _metaAttributes = [];
|
||||||
|
|
||||||
private readonly Dictionary<string, List<MdlStructs.ShapeValueStruct>> _shapeValues = [];
|
private readonly Dictionary<string, List<MdlStructs.ShapeValueStruct>> _shapeValues = [];
|
||||||
|
|
@ -87,6 +91,7 @@ public class MeshImporter(IEnumerable<Node> nodes)
|
||||||
VertexBuffer = _streams[0].Concat(_streams[1]).Concat(_streams[2]),
|
VertexBuffer = _streams[0].Concat(_streams[1]).Concat(_streams[2]),
|
||||||
Indices = _indices,
|
Indices = _indices,
|
||||||
Bones = _bones,
|
Bones = _bones,
|
||||||
|
BoundingBox = _boundingBox,
|
||||||
MetaAttributes = _metaAttributes,
|
MetaAttributes = _metaAttributes,
|
||||||
ShapeKeys = _shapeValues
|
ShapeKeys = _shapeValues
|
||||||
.Select(pair => new MeshShapeKey()
|
.Select(pair => new MeshShapeKey()
|
||||||
|
|
@ -154,6 +159,8 @@ public class MeshImporter(IEnumerable<Node> nodes)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_boundingBox.Merge(subMesh.BoundingBox);
|
||||||
|
|
||||||
// And finally, merge in the sub-mesh struct itself.
|
// And finally, merge in the sub-mesh struct itself.
|
||||||
_subMeshes.Add(subMesh.SubMeshStruct with
|
_subMeshes.Add(subMesh.SubMeshStruct with
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ public partial class ModelImporter(ModelRoot model)
|
||||||
private readonly List<string> _bones = [];
|
private readonly List<string> _bones = [];
|
||||||
private readonly List<MdlStructs.BoneTableStruct> _boneTables = [];
|
private readonly List<MdlStructs.BoneTableStruct> _boneTables = [];
|
||||||
|
|
||||||
|
private readonly BoundingBox _boundingBox = new BoundingBox();
|
||||||
|
|
||||||
private readonly List<string> _metaAttributes = [];
|
private readonly List<string> _metaAttributes = [];
|
||||||
|
|
||||||
private readonly Dictionary<string, List<MdlStructs.ShapeMeshStruct>> _shapeMeshes = [];
|
private readonly Dictionary<string, List<MdlStructs.ShapeMeshStruct>> _shapeMeshes = [];
|
||||||
|
|
@ -95,9 +97,10 @@ public partial class ModelImporter(ModelRoot model)
|
||||||
|
|
||||||
Materials = [.. materials],
|
Materials = [.. materials],
|
||||||
|
|
||||||
|
BoundingBoxes = _boundingBox.ToStruct(),
|
||||||
|
|
||||||
// TODO: Would be good to calculate all of this up the tree.
|
// TODO: Would be good to calculate all of this up the tree.
|
||||||
Radius = 1,
|
Radius = 1,
|
||||||
BoundingBoxes = MdlFile.EmptyBoundingBox,
|
|
||||||
BoneBoundingBoxes = Enumerable.Repeat(MdlFile.EmptyBoundingBox, _bones.Count).ToArray(),
|
BoneBoundingBoxes = Enumerable.Repeat(MdlFile.EmptyBoundingBox, _bones.Count).ToArray(),
|
||||||
RemainingData = [.._vertexBuffer, ..indexBuffer],
|
RemainingData = [.._vertexBuffer, ..indexBuffer],
|
||||||
};
|
};
|
||||||
|
|
@ -156,6 +159,8 @@ public partial class ModelImporter(ModelRoot model)
|
||||||
.ToArray(),
|
.ToArray(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_boundingBox.Merge(mesh.BoundingBox);
|
||||||
|
|
||||||
_subMeshes.AddRange(mesh.SubMeshStructs.Select(m => m with
|
_subMeshes.AddRange(mesh.SubMeshStructs.Select(m => m with
|
||||||
{
|
{
|
||||||
AttributeIndexMask = Utility.GetMergedAttributeMask(
|
AttributeIndexMask = Utility.GetMergedAttributeMask(
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ public class SubMeshImporter
|
||||||
|
|
||||||
public ushort[] Indices;
|
public ushort[] Indices;
|
||||||
|
|
||||||
|
public BoundingBox BoundingBox;
|
||||||
|
|
||||||
public string[] MetaAttributes;
|
public string[] MetaAttributes;
|
||||||
|
|
||||||
public Dictionary<string, List<MdlStructs.ShapeValueStruct>> ShapeValues;
|
public Dictionary<string, List<MdlStructs.ShapeValueStruct>> ShapeValues;
|
||||||
|
|
@ -44,6 +46,8 @@ public class SubMeshImporter
|
||||||
|
|
||||||
private ushort[]? _indices;
|
private ushort[]? _indices;
|
||||||
|
|
||||||
|
private BoundingBox _boundingBox = new BoundingBox();
|
||||||
|
|
||||||
private string[]? _metaAttributes;
|
private string[]? _metaAttributes;
|
||||||
|
|
||||||
private readonly List<string>? _morphNames;
|
private readonly List<string>? _morphNames;
|
||||||
|
|
@ -90,9 +94,11 @@ public class SubMeshImporter
|
||||||
private SubMesh Create()
|
private SubMesh Create()
|
||||||
{
|
{
|
||||||
// Build all the data we'll need.
|
// Build all the data we'll need.
|
||||||
|
// TODO: This structure is verging on a little silly. Reconsider.
|
||||||
BuildIndices();
|
BuildIndices();
|
||||||
BuildVertexAttributes();
|
BuildVertexAttributes();
|
||||||
BuildVertices();
|
BuildVertices();
|
||||||
|
BuildBoundingBox();
|
||||||
BuildMetaAttributes();
|
BuildMetaAttributes();
|
||||||
|
|
||||||
ArgumentNullException.ThrowIfNull(_indices);
|
ArgumentNullException.ThrowIfNull(_indices);
|
||||||
|
|
@ -133,6 +139,7 @@ public class SubMeshImporter
|
||||||
Strides = _strides,
|
Strides = _strides,
|
||||||
Streams = _streams,
|
Streams = _streams,
|
||||||
Indices = _indices,
|
Indices = _indices,
|
||||||
|
BoundingBox = _boundingBox,
|
||||||
MetaAttributes = _metaAttributes,
|
MetaAttributes = _metaAttributes,
|
||||||
ShapeValues = _shapeValues,
|
ShapeValues = _shapeValues,
|
||||||
};
|
};
|
||||||
|
|
@ -255,6 +262,13 @@ public class SubMeshImporter
|
||||||
_shapeValues = morphShapeValues;
|
_shapeValues = morphShapeValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BuildBoundingBox()
|
||||||
|
{
|
||||||
|
var positions = _primitive.VertexAccessors["POSITION"].AsVector3Array();
|
||||||
|
foreach (var position in positions)
|
||||||
|
_boundingBox.Merge(position);
|
||||||
|
}
|
||||||
|
|
||||||
private void BuildMetaAttributes()
|
private void BuildMetaAttributes()
|
||||||
{
|
{
|
||||||
// We consider any "extras" key with a boolean value set to `true` to be an attribute.
|
// We consider any "extras" key with a boolean value set to `true` to be an attribute.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue