You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/EMotionFX/Code/Tests/AnimGraphSyncTrackTests.cpp

499 lines
17 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "SystemComponentFixture.h"
#include "TestAssetCode/MotionEvent.h"
#include <EMotionFX/Source/EventManager.h>
#include <EMotionFX/Source/MotionEventTable.h>
#include <EMotionFX/Source/MotionManager.h>
#include <EMotionFX/Source/Motion.h>
#include <EMotionFX/Source/TwoStringEventData.h>
#include <EMotionFX/Source/MotionData/NonUniformMotionData.h>
namespace EMotionFX
{
struct FindEventIndicesParams
{
void (*m_eventFactory)(MotionEventTrack* track);
float m_timeValue;
size_t m_expectedLeft;
size_t m_expectedRight;
};
void PrintTo(FindEventIndicesParams const object, ::std::ostream* os)
{
if (object.m_eventFactory == &MakeNoEvents)
{
*os << "Events: 0";
}
else if (object.m_eventFactory == &MakeOneEvent)
{
*os << "Events: 1";
}
else if (object.m_eventFactory == &MakeTwoEvents)
{
*os << "Events: 2";
}
else if (object.m_eventFactory == &MakeThreeEvents)
{
*os << "Events: 3";
}
else
{
*os << "Events: Unknown";
}
*os << " Time value: " << object.m_timeValue
<< " Expected left: " << object.m_expectedLeft
<< " Expected right: " << object.m_expectedRight
;
}
class TestFindEventIndicesFixture : public SystemComponentFixture,
public ::testing::WithParamInterface<FindEventIndicesParams>
{
void SetUp() override
{
SystemComponentFixture::SetUp();
m_motion = aznew Motion("TestFindEventIndicesMotion");
m_motion->SetMotionData(aznew NonUniformMotionData());
m_motion->GetMotionData()->SetDuration(2.0f);
m_motion->GetEventTable()->AutoCreateSyncTrack(m_motion);
m_syncTrack = m_motion->GetEventTable()->GetSyncTrack();
const FindEventIndicesParams& params = GetParam();
params.m_eventFactory(m_syncTrack);
}
void TearDown() override
{
m_motion->Destroy();
SystemComponentFixture::TearDown();
}
protected:
Motion* m_motion = nullptr;
AnimGraphSyncTrack* m_syncTrack = nullptr;
};
TEST_P(TestFindEventIndicesFixture, TestFindEventIndices)
{
const FindEventIndicesParams& params = GetParam();
size_t indexLeft, indexRight;
m_syncTrack->FindEventIndices(params.m_timeValue, &indexLeft, &indexRight);
EXPECT_EQ(indexLeft, params.m_expectedLeft);
EXPECT_EQ(indexRight, params.m_expectedRight);
}
INSTANTIATE_TEST_CASE_P(TestFindEventIndices, TestFindEventIndicesFixture,
::testing::ValuesIn(std::vector<FindEventIndicesParams> {
{
MakeNoEvents,
0.5f,
InvalidIndex,
InvalidIndex
},
{
MakeOneEvent,
0.0f,
0,
0
},
{
MakeOneEvent,
0.5f,
0,
0
},
{
MakeTwoEvents,
0.0f,
1,
0
},
{
MakeTwoEvents,
0.5f,
0,
1
},
{
MakeTwoEvents,
1.0f,
1,
0
},
{
MakeThreeEvents,
0.0f,
2,
0
},
{
MakeThreeEvents,
0.5f,
0,
1
},
{
MakeThreeEvents,
1.0f,
1,
2
},
{
MakeThreeEvents,
1.5f,
2,
0
},
{
[](MotionEventTrack* track)
{
MakeTwoEvents(track);
MakeTwoEvents(track);
},
0.25,
1,
2
},
});
);
struct FindMatchingEventsParams
{
void (*m_eventFactory)(MotionEventTrack* track);
size_t m_startingIndex;
size_t m_inEventAIndex;
size_t m_inEventBIndex;
size_t m_expectedEventA;
size_t m_expectedEventB;
bool m_mirrorInput;
bool m_mirrorOutput;
bool m_forward;
};
void PrintTo(FindMatchingEventsParams const object, ::std::ostream* os)
{
if (object.m_eventFactory == &MakeNoEvents)
{
*os << "Events: 0";
}
else if (object.m_eventFactory == &MakeOneEvent)
{
*os << "Events: 1";
}
else if (object.m_eventFactory == &MakeTwoLeftRightEvents)
{
*os << "Events: LRLR";
}
else
{
*os << "Events: Unknown";
}
*os << " Start index: " << object.m_startingIndex
<< " In Event A: " << object.m_inEventAIndex
<< " In Event B: " << object.m_inEventBIndex
<< " Expected Event A: " << object.m_expectedEventA
<< " Expected Event B: " << object.m_expectedEventB
<< " Mirror Input: " << object.m_mirrorInput
<< " Mirror Output: " << object.m_mirrorOutput
<< " Play direction: " << (object.m_forward ? "Forward" : "Backward")
;
}
class TestFindMatchingEventsFixture : public SystemComponentFixture,
public ::testing::WithParamInterface<FindMatchingEventsParams>
{
void SetUp() override
{
SystemComponentFixture::SetUp();
m_motion = aznew Motion("TestFindMatchingEventsMotion");
m_motion->SetMotionData(aznew NonUniformMotionData());
m_motion->GetMotionData()->SetDuration(4.0f);
m_motion->GetEventTable()->AutoCreateSyncTrack(m_motion);
m_syncTrack = m_motion->GetEventTable()->GetSyncTrack();
const FindMatchingEventsParams& params = GetParam();
params.m_eventFactory(m_syncTrack);
}
void TearDown() override
{
m_motion->Destroy();
SystemComponentFixture::TearDown();
}
protected:
Motion* m_motion = nullptr;
AnimGraphSyncTrack* m_syncTrack = nullptr;
};
TEST_P(TestFindMatchingEventsFixture, TestFindMatchingEvents)
{
const FindMatchingEventsParams& params = GetParam();
// Make sure we have an event to get the id of
const size_t eventCount = m_syncTrack->GetNumEvents();
const size_t eventAID = eventCount ? m_syncTrack->GetEvent(params.m_inEventAIndex).HashForSyncing(params.m_mirrorInput) : 0;
const size_t eventBID = eventCount ? m_syncTrack->GetEvent(params.m_inEventBIndex).HashForSyncing(params.m_mirrorInput) : 0;
size_t outLeft, outRight;
m_syncTrack->FindMatchingEvents(
params.m_startingIndex,
eventAID,
eventBID,
&outLeft,
&outRight,
params.m_forward,
params.m_mirrorOutput
);
EXPECT_EQ(outLeft, params.m_expectedEventA);
EXPECT_EQ(outRight, params.m_expectedEventB);
}
INSTANTIATE_TEST_CASE_P(TestFindMatchingEvents, TestFindMatchingEventsFixture,
::testing::ValuesIn(std::vector<FindMatchingEventsParams> {
// With no events, it shouldn't matter what we put in, we'll get
// back invalid indices
{
MakeNoEvents,
0, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
InvalidIndex, // expectedEventA
InvalidIndex, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
// With just one event, we'll always get back indices (0,0)
{
MakeOneEvent,
0, // startingIndex
0, // inEventAIndex
0, // inEventBIndex
0, // expectedEventA
0, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
// When forward is true
// Look for L->R events. The L->R event pairs are (0,1) and (2,3)
// (expectedEventA will be 0 or 2 and expectedEventB will be 1 or 3)
{
// Starting at event 0[L], looking for events L->R, should find events 0 and 1
MakeTwoLeftRightEvents,
0, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
0, // expectedEventA
1, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
{
// Starting at event 1[R], looking for events L->R, should find events 2 and 3
MakeTwoLeftRightEvents,
1, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
2, // expectedEventA
3, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
{
// Starting at event 2[L], looking for events L->R, should find events 2 and 3
MakeTwoLeftRightEvents,
2, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
2, // expectedEventA
3, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
{
// Starting at event 3[R], looking for events L->R, should find events 0 and 1
MakeTwoLeftRightEvents,
3, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
0, // expectedEventA
1, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
// Look for R->L events. The R->R event pairs are (1,2) and (3,0)
// (expectedEventA will be 1 or 3 and expectedEventB will be 2 or 0)
{
// Starting at event 0[L], looking for events R->L, should find events 1 and 2
MakeTwoLeftRightEvents,
0, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
1, // expectedEventA
2, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
{
// Starting at event 1[R], looking for events R->L, should find events 1 and 2
MakeTwoLeftRightEvents,
1, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
1, // expectedEventA
2, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
{
// Starting at event 2[L], looking for events R->L, should find events 3 and 0
MakeTwoLeftRightEvents,
2, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
3, // expectedEventA
0, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
{
// Starting at event 3[R], looking for events R->L, should find events 3 and 0
MakeTwoLeftRightEvents,
3, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
3, // expectedEventA
0, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
true // forward
},
// When forward is false
// Look for L->R events. The L->R event pairs are (0,1) and (2,3)
// (expectedEventA will be 0 or 2 and expectedEventB will be 1 or 3)
{
// Starting at event 0[L], looking for events L->R, going backward, should find events 2 and 3
MakeTwoLeftRightEvents,
0, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
2, // expectedEventA
3, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
{
// Starting at event 1[R], looking for events L->R, going backward, should find events 0 and 1
MakeTwoLeftRightEvents,
1, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
0, // expectedEventA
1, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
{
// Starting at event 2[L], looking for events L->R, going backward, should find events 0 and 1
MakeTwoLeftRightEvents,
2, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
0, // expectedEventA
1, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
{
// Starting at event 3[R], looking for events L->R, going backward, should find events 2 and 3
MakeTwoLeftRightEvents,
3, // startingIndex
0, // inEventAIndex
1, // inEventBIndex
2, // expectedEventA
3, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
// Look for R->L events. The R->R event pairs are (1,2) and (3,0)
// (expectedEventA will be 1 or 3 and expectedEventB will be 2 or 0)
{
// Starting at event 0[L], looking for events R->L, going backward, should find events 3 and 0
MakeTwoLeftRightEvents,
0, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
3, // expectedEventA
0, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
{
// Starting at event 1[R], looking for events R->L, going backward, should find events 3 and 0
MakeTwoLeftRightEvents,
1, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
3, // expectedEventA
0, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
{
// Starting at event 2[L], looking for events R->L, going backward, should find events 1 and 2
MakeTwoLeftRightEvents,
2, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
1, // expectedEventA
2, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
},
{
// Starting at event 3[R], looking for events R->L, going backward, should find events 1 and 2
MakeTwoLeftRightEvents,
3, // startingIndex
1, // inEventAIndex
2, // inEventBIndex
1, // expectedEventA
2, // expectedEventB
false, // mirrorInput
false, // mirrorOutput
false // forward
}
})
);
} // end namespace EMotionFX