mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +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 BoundingBox BoundingBox;
|
||||
|
||||
public List<string> MetaAttributes;
|
||||
|
||||
public List<MeshShapeKey> ShapeKeys;
|
||||
|
|
@ -50,6 +52,8 @@ public class MeshImporter(IEnumerable<Node> nodes)
|
|||
|
||||
private List<string>? _bones;
|
||||
|
||||
private readonly BoundingBox _boundingBox = new BoundingBox();
|
||||
|
||||
private readonly List<string> _metaAttributes = [];
|
||||
|
||||
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]),
|
||||
Indices = _indices,
|
||||
Bones = _bones,
|
||||
BoundingBox = _boundingBox,
|
||||
MetaAttributes = _metaAttributes,
|
||||
ShapeKeys = _shapeValues
|
||||
.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.
|
||||
_subMeshes.Add(subMesh.SubMeshStruct with
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ public partial class ModelImporter(ModelRoot model)
|
|||
private readonly List<string> _bones = [];
|
||||
private readonly List<MdlStructs.BoneTableStruct> _boneTables = [];
|
||||
|
||||
private readonly BoundingBox _boundingBox = new BoundingBox();
|
||||
|
||||
private readonly List<string> _metaAttributes = [];
|
||||
|
||||
private readonly Dictionary<string, List<MdlStructs.ShapeMeshStruct>> _shapeMeshes = [];
|
||||
|
|
@ -95,9 +97,10 @@ public partial class ModelImporter(ModelRoot model)
|
|||
|
||||
Materials = [.. materials],
|
||||
|
||||
BoundingBoxes = _boundingBox.ToStruct(),
|
||||
|
||||
// TODO: Would be good to calculate all of this up the tree.
|
||||
Radius = 1,
|
||||
BoundingBoxes = MdlFile.EmptyBoundingBox,
|
||||
BoneBoundingBoxes = Enumerable.Repeat(MdlFile.EmptyBoundingBox, _bones.Count).ToArray(),
|
||||
RemainingData = [.._vertexBuffer, ..indexBuffer],
|
||||
};
|
||||
|
|
@ -156,6 +159,8 @@ public partial class ModelImporter(ModelRoot model)
|
|||
.ToArray(),
|
||||
});
|
||||
|
||||
_boundingBox.Merge(mesh.BoundingBox);
|
||||
|
||||
_subMeshes.AddRange(mesh.SubMeshStructs.Select(m => m with
|
||||
{
|
||||
AttributeIndexMask = Utility.GetMergedAttributeMask(
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public class SubMeshImporter
|
|||
|
||||
public ushort[] Indices;
|
||||
|
||||
public BoundingBox BoundingBox;
|
||||
|
||||
public string[] MetaAttributes;
|
||||
|
||||
public Dictionary<string, List<MdlStructs.ShapeValueStruct>> ShapeValues;
|
||||
|
|
@ -44,6 +46,8 @@ public class SubMeshImporter
|
|||
|
||||
private ushort[]? _indices;
|
||||
|
||||
private BoundingBox _boundingBox = new BoundingBox();
|
||||
|
||||
private string[]? _metaAttributes;
|
||||
|
||||
private readonly List<string>? _morphNames;
|
||||
|
|
@ -90,9 +94,11 @@ public class SubMeshImporter
|
|||
private SubMesh Create()
|
||||
{
|
||||
// Build all the data we'll need.
|
||||
// TODO: This structure is verging on a little silly. Reconsider.
|
||||
BuildIndices();
|
||||
BuildVertexAttributes();
|
||||
BuildVertices();
|
||||
BuildBoundingBox();
|
||||
BuildMetaAttributes();
|
||||
|
||||
ArgumentNullException.ThrowIfNull(_indices);
|
||||
|
|
@ -133,6 +139,7 @@ public class SubMeshImporter
|
|||
Strides = _strides,
|
||||
Streams = _streams,
|
||||
Indices = _indices,
|
||||
BoundingBox = _boundingBox,
|
||||
MetaAttributes = _metaAttributes,
|
||||
ShapeValues = _shapeValues,
|
||||
};
|
||||
|
|
@ -255,6 +262,13 @@ public class SubMeshImporter
|
|||
_shapeValues = morphShapeValues;
|
||||
}
|
||||
|
||||
private void BuildBoundingBox()
|
||||
{
|
||||
var positions = _primitive.VertexAccessors["POSITION"].AsVector3Array();
|
||||
foreach (var position in positions)
|
||||
_boundingBox.Merge(position);
|
||||
}
|
||||
|
||||
private void BuildMetaAttributes()
|
||||
{
|
||||
// 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