Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: MovingPlatformComponent and subcomponents #1421

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Expand tests to cover path types and edge cases
  • Loading branch information
aronwk-aaron committed Feb 17, 2024
commit 92696606e121b61609a4b767e66fc3e13711782e
67 changes: 40 additions & 27 deletions dGame/dComponents/MovingPlatformComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "CDClientManager.h"
#include "CDMovingPlatformComponentTable.h"
#include "Zone.h"
#include "StringifiedEnum.h"

//------------- PlatformSubComponent begin --------------

Expand Down Expand Up @@ -84,22 +85,10 @@
}

void PlatformSubComponent::AdvanceToNextWaypoint() {
uint32_t numWaypoints = m_Path->pathWaypoints.size();
m_CurrentWaypointIndex = m_NextWaypointIndex;
m_ParentComponent->GetParent()->SetPosition(GetCurrentWaypoint().position);
m_ParentComponent->GetParent()->SetRotation(GetCurrentWaypoint().rotation);
uint32_t nextWaypointIndex = m_CurrentWaypointIndex + 1;
if (numWaypoints <= nextWaypointIndex) {
PathBehavior behavior = m_Path->pathBehavior;
if (behavior == PathBehavior::Once) {
nextWaypointIndex = m_Path->pathWaypoints.size() - 1;
} else if (behavior == PathBehavior::Bounce) {
nextWaypointIndex = m_Path->pathWaypoints.size() - 2;
m_InReverse = true;
} else {
m_NextWaypointIndex = 0;
}
}
int32_t nextWaypointIndex = FindNextWaypointIndex();
m_NextWaypointIndex = nextWaypointIndex;
m_DesiredWaypointIndex = nextWaypointIndex;
UpdateLinearVelocity();
Expand All @@ -108,22 +97,10 @@
}

void PlatformSubComponent::AdvanceToNextReverseWaypoint() {
uint32_t numWaypoints = m_Path->pathWaypoints.size();
m_ParentComponent->GetParent()->SetPosition(GetCurrentWaypoint().position);
m_ParentComponent->GetParent()->SetRotation(GetCurrentWaypoint().rotation);
m_CurrentWaypointIndex = m_NextWaypointIndex;
int32_t nextWaypointIndex = m_CurrentWaypointIndex - 1;
if (nextWaypointIndex < 0) {
PathBehavior behavior = m_Path->pathBehavior;
if (behavior == PathBehavior::Once) {
nextWaypointIndex = 0;
} else if (behavior == PathBehavior::Bounce) {
nextWaypointIndex = 1;
m_InReverse = false;
} else {
nextWaypointIndex = m_Path->pathWaypoints.size() - 1;
}
}
int32_t nextWaypointIndex = FindNextReversedWaypointIndex();
m_NextWaypointIndex = nextWaypointIndex;
m_DesiredWaypointIndex = nextWaypointIndex;
UpdateLinearVelocity();
Expand All @@ -141,13 +118,49 @@
m_InReverse = startsInReverse;
m_CurrentWaypointIndex = startingWaypointIndex;
m_TimeBasedMovement = m_Path->movingPlatform.timeBasedMovement;
m_NextWaypointIndex = m_InReverse ? m_CurrentWaypointIndex - 1 : m_CurrentWaypointIndex + 1;
m_NextWaypointIndex = m_InReverse ? FindNextReversedWaypointIndex() : FindNextWaypointIndex();
}

const PathWaypoint& PlatformSubComponent::GetNextWaypoint() const {
DluAssert(m_Path != nullptr);
return m_Path->pathWaypoints.at(m_NextWaypointIndex);
}
const int32_t PlatformSubComponent::FindNextWaypointIndex() {
DluAssert(m_Path != nullptr);
uint32_t numWaypoints = m_Path->pathWaypoints.size();
uint32_t nextWaypointIndex = m_CurrentWaypointIndex + 1;
if (numWaypoints <= nextWaypointIndex) {
PathBehavior behavior = m_Path->pathBehavior;
if (behavior == PathBehavior::Once) {
nextWaypointIndex = m_Path->pathWaypoints.size() - 1;
} else if (behavior == PathBehavior::Bounce) {
nextWaypointIndex = m_Path->pathWaypoints.size() - 2;
m_InReverse = true;
} else {
nextWaypointIndex = 0;
}
}
return nextWaypointIndex;
}

const int32_t PlatformSubComponent::FindNextReversedWaypointIndex() {
DluAssert(m_Path != nullptr);
uint32_t numWaypoints = m_Path->pathWaypoints.size();
int32_t nextWaypointIndex = m_CurrentWaypointIndex - 1;
if (nextWaypointIndex < 0) {
PathBehavior behavior = m_Path->pathBehavior;
if (behavior == PathBehavior::Once) {
nextWaypointIndex = 0;
} else if (behavior == PathBehavior::Bounce) {
nextWaypointIndex = 1;
m_InReverse = false;
} else {
nextWaypointIndex = m_Path->pathWaypoints.size() - 1;
}
}
return nextWaypointIndex;
}


const PathWaypoint& PlatformSubComponent::GetCurrentWaypoint() const {
DluAssert(m_Path != nullptr);
Expand Down Expand Up @@ -205,7 +218,7 @@
if (m_State & eMovementPlatformState::Stopped && (m_State & eMovementPlatformState::ReachedDesiredWaypoint) == 0) {
StartPathing();
}
if (m_State & eMovementPlatformState::Travelling == 0) {

Check failure on line 221 in dGame/dComponents/MovingPlatformComponent.cpp

View workflow job for this annotation

GitHub Actions / Build & Test (macos-13)

& has lower precedence than ==; == will be evaluated first [-Werror,-Wparentheses]
m_State |= eMovementPlatformState::Waiting;
m_State &= ~eMovementPlatformState::Stopped;
m_State &= ~eMovementPlatformState::Travelling;
Expand Down
2 changes: 2 additions & 0 deletions dGame/dComponents/MovingPlatformComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class PlatformSubComponent {
float CalculateSpeed() const;
const PathWaypoint& GetNextWaypoint() const;
const PathWaypoint& GetCurrentWaypoint() const;
const int32_t FindNextWaypointIndex();
const int32_t FindNextReversedWaypointIndex();
void SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse);
void AdvanceToNextWaypoint();
void AdvanceToNextReverseWaypoint();
Expand Down
148 changes: 98 additions & 50 deletions tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ class MovingPlatformComponentTests : public GameDependenciesTest {
std::unique_ptr<Entity> baseEntity;
CBITSTREAM;
uint32_t flags = 0;
Path path;
Path pathOnce;
Path pathBounce;
Path pathLoop;
void SetUp() override {
SetUpDependencies();
path.movingPlatform.timeBasedMovement = false;
path.pathBehavior = PathBehavior::Once;
path.pathName = "ExamplePath";
PathWaypoint waypointStart;
waypointStart.position = NiPoint3(1, 2, 3);
waypointStart.rotation = NiQuaternion(4, 5, 6, 7);
Expand All @@ -36,13 +35,40 @@ class MovingPlatformComponentTests : public GameDependenciesTest {
waypointEnd.position = NiPoint3(4, 5, 7);
waypointEnd.rotation = NiQuaternion(7, 8, 9, 10);
waypointStart.movingPlatform.speed = 16.0f;

path.pathWaypoints.push_back(waypointStart);
path.pathWaypoints.push_back(waypointMiddle);
path.pathWaypoints.push_back(waypointEnd);

Game::zoneManager->GetZone()->AddPath(path);

{
pathOnce.movingPlatform.timeBasedMovement = false;
pathOnce.pathBehavior = PathBehavior::Once;
pathOnce.pathName = "ExampleOncePath";

pathOnce.pathWaypoints.push_back(waypointStart);
pathOnce.pathWaypoints.push_back(waypointMiddle);
pathOnce.pathWaypoints.push_back(waypointEnd);

Game::zoneManager->GetZone()->AddPath(pathOnce);
}
{
pathBounce.movingPlatform.timeBasedMovement = false;
pathBounce.pathBehavior = PathBehavior::Bounce;
pathBounce.pathName = "ExampleBouncePath";

pathBounce.pathWaypoints.push_back(waypointStart);
pathBounce.pathWaypoints.push_back(waypointMiddle);
pathBounce.pathWaypoints.push_back(waypointEnd);

Game::zoneManager->GetZone()->AddPath(pathBounce);
}
{
pathLoop.movingPlatform.timeBasedMovement = false;
pathLoop.pathBehavior = PathBehavior::Loop;
pathLoop.pathName = "ExampleLoopPath";


pathLoop.pathWaypoints.push_back(waypointStart);
pathLoop.pathWaypoints.push_back(waypointMiddle);
pathLoop.pathWaypoints.push_back(waypointEnd);

Game::zoneManager->GetZone()->AddPath(pathLoop);
}
// Set our starting position
info.pos = NiPoint3(25, 26, 27);
info.rot = NiQuaternion(28, 29, 30, 31);
Expand All @@ -61,7 +87,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest {
baseEntity = std::make_unique<Entity>(15, GameDependenciesTest::info);

auto* simplePhysicsComponent = baseEntity->AddComponent<SimplePhysicsComponent>(1);
auto* movingPlatformComponent = baseEntity->AddComponent<MovingPlatformComponent>("ExamplePath");
auto* movingPlatformComponent = baseEntity->AddComponent<MovingPlatformComponent>("ExampleOncePath");
movingPlatformComponent->LoadConfigData();
movingPlatformComponent->LoadDataFromTemplate();
}
Expand Down Expand Up @@ -176,7 +202,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest {
ASSERT_TRUE(bitStream.Read(pathNameLength));
pathName.resize(pathNameLength);
ASSERT_TRUE(bitStream.ReadBits(reinterpret_cast<unsigned char*>(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2));
ASSERT_EQ(pathName, u"ExamplePath");
ASSERT_EQ(pathName, u"ExampleOncePath");

uint32_t pathStartIndex;
ASSERT_TRUE(bitStream.Read(pathStartIndex));
Expand Down Expand Up @@ -229,52 +255,76 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSerializationTest) {
TestSerialization();
}

TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwardTest) {
TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathOnceAdvanceTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExamplePath", 0, false);

moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false);

ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
path.pathBehavior = PathBehavior::Bounce;
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
}

TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceReverseTest) {
TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathBounceAdvanceTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExamplePath", 0, true);

moverPlatformSubComponent.AdvanceToNextReverseWaypoint();
moverPlatformSubComponent.SetupPath("ExampleBouncePath", 0, false);

ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
moverPlatformSubComponent.AdvanceToNextReverseWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0);
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
path.pathBehavior = PathBehavior::Bounce;
moverPlatformSubComponent.AdvanceToNextWaypoint();
moverPlatformSubComponent.AdvanceToNextReverseWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
}

TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) {
TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentLoopAdvanceTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExamplePath", 0, false);

moverPlatformSubComponent.SetupPath("ExampleLoopPath", 0, false);

ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
}

TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentLoopAdvanceReverseTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExampleLoopPath", 0, true);

ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
moverPlatformSubComponent.AdvanceToNextReverseWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
Expand All @@ -284,18 +334,15 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest)
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
moverPlatformSubComponent.AdvanceToNextReverseWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
moverPlatformSubComponent.AdvanceToNextWaypoint();
ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1);
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2);
ASSERT_FALSE(moverPlatformSubComponent.GetInReverse());
ASSERT_TRUE(moverPlatformSubComponent.GetInReverse());
}


TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());

moverPlatformSubComponent.SetupPath("ExamplePath", 0, false);
moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false);

ASSERT_EQ(moverPlatformSubComponent.CalculateSpeed(), 16.0f);
NiPoint3 r = moverPlatformSubComponent.CalculateLinearVelocity();
Expand All @@ -307,7 +354,7 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) {

TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExamplePath", 0, false);
moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false);

ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypoint().position, NiPoint3(1, 2, 3));
ASSERT_EQ(moverPlatformSubComponent.GetNextWaypoint().position, NiPoint3(4, 5, 6));
Expand All @@ -318,29 +365,30 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess)

TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExamplePath", 0, false);
moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false);

path.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f);
path.pathWaypoints.at(0).movingPlatform.speed = 16.0f;
pathOnce.pathWaypoints.at(1).position = NiPoint3(99.296440f, 419.293335f, 207.219498f);
pathOnce.pathWaypoints.at(1).movingPlatform.speed = 16.0f;

path.pathWaypoints.at(1).position = NiPoint3(141.680099f, 419.990051f, 208.680450f);
path.pathWaypoints.at(1).movingPlatform.speed = 16.0f;
pathOnce.pathWaypoints.at(2).position = NiPoint3(141.680099f, 419.990051f, 208.680450f);
pathOnce.pathWaypoints.at(2).movingPlatform.speed = 16.0f;

moverPlatformSubComponent.UpdateLinearVelocity();
moverPlatformSubComponent.Update(2.65f);

auto [x,y,z] = moverPlatformSubComponent.GetPosition();
LOG_TEST("x: %f, y: %f, z: %f", x, y, z);
// just check that its close enough
EXPECT_LT(141.680099f - moverPlatformSubComponent.GetPosition().x, 0.1f);
EXPECT_LT(419.990051f - moverPlatformSubComponent.GetPosition().y, 0.1f);
EXPECT_LT(208.680450f - moverPlatformSubComponent.GetPosition().z, 0.1f);
EXPECT_LT(141.680099f - x, 0.1f);
EXPECT_LT(419.990051f - y, 0.1f);
EXPECT_LT(208.680450f - z, 0.1f);
}

TEST_F(MovingPlatformComponentTests, MovingPlatformPercentBetweenPointsTest) {
MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent<MovingPlatformComponent>());
moverPlatformSubComponent.SetupPath("ExamplePath", 0, false);
moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false);

path.pathWaypoints.at(0).position = NiPoint3(0, 0, 1);
path.pathWaypoints.at(1).position = NiPoint3(0, 0, 3);
pathOnce.pathWaypoints.at(0).position = NiPoint3(0, 0, 1);
pathOnce.pathWaypoints.at(1).position = NiPoint3(0, 0, 3);
// moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 1);
ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f);
// moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 2);
Expand Down
Loading