using System.Numerics; using AcDream.Core.Meshing; using AcDream.Core.World; using DatReaderWriter.DBObjs; using DatReaderWriter.Enums; using DatReaderWriter.Types; namespace AcDream.Core.Tests.Meshing; public sealed class EquippedChildAttachmentTests { [Fact] public void TryCompose_CombinesChildPlacementHoldingFrameAndAnimatedHandPart() { var parent = new Setup { HoldingLocations = { [ParentLocation.LeftHand] = new LocationType { PartId = 1, Frame = FrameAt(2, 0, 0), }, }, }; var parentPose = new[] { new MeshRef(1, Matrix4x4.Identity), new MeshRef(2, Matrix4x4.CreateTranslation(10, 0, 0)), }; var child = new Setup { Parts = { 0x01000001u }, DefaultScale = { Vector3.One }, PlacementFrames = { [Placement.LeftHand] = new AnimationFrame(1) { Frames = { FrameAt(3, 0, 0) }, }, }, }; var template = new[] { new MeshRef(0x01000001u, Matrix4x4.Identity) }; bool ok = EquippedChildAttachment.TryCompose( parent, parentPose, child, ParentLocation.LeftHand, Placement.LeftHand, template, 1.0f, out var result); Assert.True(ok); Assert.Equal(15f, Assert.Single(result).PartTransform.Translation.X); } [Fact] public void TryCompose_MissingRequestedPlacementFallsBackToDefault() { var parent = ParentWithRightHand(partId: -1, FrameAt(4, 0, 0)); var child = new Setup { Parts = { 0x01000001u }, PlacementFrames = { [Placement.Default] = new AnimationFrame(1) { Frames = { FrameAt(6, 0, 0) }, }, }, }; bool ok = EquippedChildAttachment.TryCompose( parent, [], child, ParentLocation.RightHand, Placement.RightHandCombat, [new MeshRef(0x01000001u, Matrix4x4.Identity)], 1.0f, out var result); Assert.True(ok); Assert.Equal(10f, Assert.Single(result).PartTransform.Translation.X); } [Fact] public void TryCompose_MissingHoldingLocationRejectsAttachment() { bool ok = EquippedChildAttachment.TryCompose( new Setup(), [], new Setup(), ParentLocation.RightHand, Placement.RightHandCombat, [], 1.0f, out var result); Assert.False(ok); Assert.Empty(result); } private static Setup ParentWithRightHand(int partId, Frame frame) => new() { HoldingLocations = { [ParentLocation.RightHand] = new LocationType { PartId = partId, Frame = frame, }, }, }; private static Frame FrameAt(float x, float y, float z) => new() { Origin = new Vector3(x, y, z), Orientation = Quaternion.Identity, }; }