Switch to Vec3fp and fp variables for character
This commit is contained in:
1 parent
8df016c0a4
commit
889c6d465b
23 files changed
+384
-406
No files matched your search
+114
-84
@@ -9,7 +9,13 @@ namespace {
|
||||
// Tick counts are authoritative and therefore independent of render rate.
|
||||
constexpr float ATTACK_COOLDOWN_TIME = 1.6f;
|
||||
constexpr float HOME_DRIFT_CHECK_INTERVAL = 5.0f;
|
||||
fp HOME_DRIFT_CHECK_INTERVAL_FP = static_cast<fp>(HOME_DRIFT_CHECK_INTERVAL);
|
||||
constexpr float TARGET_REPLAN_THRESHOLD = 0.25f;
|
||||
|
||||
fp TARGET_REPLAN_THRESHOLD_SQUARED = static_cast<fp>(TARGET_REPLAN_THRESHOLD * TARGET_REPLAN_THRESHOLD);
|
||||
|
||||
|
||||
|
||||
constexpr float PI = 3.14159265358979323846f;
|
||||
constexpr int BLOCKED_REPLAN_TICKS = 3;
|
||||
|
||||
@@ -25,8 +31,8 @@ std::uint32_t stableIdHash(const std::string& value)
|
||||
}
|
||||
|
||||
void CharacterState::configureAsPlayer() {
|
||||
walkSpeed = 3.0f;
|
||||
rotationSpeed = 8.0f;
|
||||
walkSpeed = static_cast<fp>(3.0f);
|
||||
rotationSpeed = static_cast < fp>(8.0f);
|
||||
modelScale = 1.f;
|
||||
modelCorrectionRotation = Eigen::Quaternionf(
|
||||
Eigen::AngleAxisf(PI, Eigen::Vector3f::UnitY()) *
|
||||
@@ -66,12 +72,12 @@ void CharacterState::scheduleNextNavigationRetry()
|
||||
}
|
||||
|
||||
bool CharacterState::isMoving() const {
|
||||
Eigen::Vector3f toTarget = walkTarget - position;
|
||||
toTarget.y() = 0.f;
|
||||
return !pathWaypoints.empty() || toTarget.norm() > kWalkThreshold;
|
||||
Vec3fp toTarget = walkTarget - position;
|
||||
toTarget.y = static_cast<fp>(0.f);
|
||||
return !pathWaypoints.empty() || toTarget.normSquared() > kWalkThreshold_SQUARED();
|
||||
}
|
||||
|
||||
Eigen::Vector3f CharacterState::getCurrentNavigationTarget() const {
|
||||
Vec3fp CharacterState::getCurrentNavigationTarget() const {
|
||||
if (!pathWaypoints.empty() && currentWaypointIndex < pathWaypoints.size()) {
|
||||
return pathWaypoints[currentWaypointIndex];
|
||||
}
|
||||
@@ -79,7 +85,7 @@ Eigen::Vector3f CharacterState::getCurrentNavigationTarget() const {
|
||||
}
|
||||
|
||||
void CharacterState::stopInPlace() {
|
||||
walkTarget = Eigen::Vector3f(position.x(), 0.f, position.z());
|
||||
walkTarget = Vec3fp(position.x, static_cast<fp>(0.f), position.z);
|
||||
requestedWalkTarget = walkTarget;
|
||||
pathWaypoints.clear();
|
||||
currentWaypointIndex = 0;
|
||||
@@ -90,20 +96,20 @@ void CharacterState::stopInPlace() {
|
||||
}
|
||||
|
||||
void CharacterState::setTarget(
|
||||
const Eigen::Vector3f& target,
|
||||
const Vec3fp& target,
|
||||
std::string callbackName,
|
||||
const LocationNetworkState& location,
|
||||
const std::string& entityId)
|
||||
{
|
||||
const Eigen::Vector3f normalizedTarget(target.x(), 0.f, target.z());
|
||||
const Vec3fp normalizedTarget(target.x, static_cast<fp>(0.f), target.z);
|
||||
const bool sameRequestedTarget =
|
||||
(normalizedTarget - requestedWalkTarget).norm() <= TARGET_REPLAN_THRESHOLD;
|
||||
(normalizedTarget - requestedWalkTarget).normSquared() <= TARGET_REPLAN_THRESHOLD_SQUARED;
|
||||
const bool alreadyMovingToTarget =
|
||||
!pathWaypoints.empty() ||
|
||||
(walkTarget - normalizedTarget).norm() <= TARGET_REPLAN_THRESHOLD;
|
||||
(walkTarget - normalizedTarget).normSquared() <= TARGET_REPLAN_THRESHOLD_SQUARED;
|
||||
const bool stoppedAfterFailedPath =
|
||||
pathWaypoints.empty() &&
|
||||
(walkTarget - position).norm() <= TARGET_REPLAN_THRESHOLD;
|
||||
(walkTarget - position).normSquared() <= TARGET_REPLAN_THRESHOLD_SQUARED;
|
||||
if (callbackName.empty() && sameRequestedTarget &&
|
||||
(alreadyMovingToTarget || stoppedAfterFailedPath)) {
|
||||
return;
|
||||
@@ -119,12 +125,15 @@ void CharacterState::setTarget(
|
||||
|
||||
currentWaypointIndex = 0;
|
||||
if (!pathWaypoints.empty()) {
|
||||
for (Eigen::Vector3f& waypoint : pathWaypoints) waypoint.y() = 0.f;
|
||||
for (Vec3fp& waypoint : pathWaypoints)
|
||||
{
|
||||
waypoint.y = static_cast<fp>(0.f);
|
||||
}
|
||||
walkTarget = pathWaypoints.back();
|
||||
return;
|
||||
}
|
||||
|
||||
walkTarget = Eigen::Vector3f(position.x(), 0.f, position.z());
|
||||
walkTarget = Vec3fp(position.x, static_cast<fp>(0.f), position.z);
|
||||
if (!isPlayer) scheduleNextNavigationRetry();
|
||||
}
|
||||
|
||||
@@ -132,8 +141,8 @@ void CharacterState::forceReplan(
|
||||
const LocationNetworkState& location,
|
||||
const std::string& entityId)
|
||||
{
|
||||
const Eigen::Vector3f normalizedTarget(
|
||||
requestedWalkTarget.x(), 0.f, requestedWalkTarget.z());
|
||||
const Vec3fp normalizedTarget(
|
||||
requestedWalkTarget.x, static_cast<fp>(0.f), requestedWalkTarget.z);
|
||||
|
||||
pathWaypoints = location.navigationMaps[location.activeNavigationIndex].findPathToNearest(this->position, normalizedTarget);
|
||||
|
||||
@@ -141,13 +150,16 @@ void CharacterState::forceReplan(
|
||||
movementBlockedTicks = 0;
|
||||
navigationRetryTicks = 0;
|
||||
if (!pathWaypoints.empty()) {
|
||||
for (Eigen::Vector3f& waypoint : pathWaypoints) waypoint.y() = 0.f;
|
||||
for (Vec3fp& waypoint : pathWaypoints)
|
||||
{
|
||||
waypoint.y = static_cast<fp>(0.f);
|
||||
}
|
||||
walkTarget = pathWaypoints.back();
|
||||
blockingCharacterId.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
walkTarget = Eigen::Vector3f(position.x(), 0.f, position.z());
|
||||
walkTarget = Vec3fp(position.x, static_cast<fp>(0.f), position.z);
|
||||
if (!isPlayer) scheduleNextNavigationRetry();
|
||||
}
|
||||
|
||||
@@ -209,16 +221,16 @@ CharacterUpdateEvents CharacterState::update(
|
||||
attack = 0;
|
||||
attackTargetId.clear();
|
||||
} else {
|
||||
const float distance = (attackTarget->position - position).norm();
|
||||
if (distance >= visibleRange) {
|
||||
if ((attackTarget->position - requestedWalkTarget).norm() >
|
||||
TARGET_REPLAN_THRESHOLD) {
|
||||
const fp distanceSquared = (attackTarget->position - position).normSquared();
|
||||
if (distanceSquared >= visibleRange* visibleRange) {
|
||||
if ((attackTarget->position - requestedWalkTarget).normSquared() >
|
||||
TARGET_REPLAN_THRESHOLD_SQUARED) {
|
||||
events.navigationRequested = true;
|
||||
events.navigationTarget = attackTarget->position;
|
||||
}
|
||||
battle_state = 0;
|
||||
} else if (distance >= 1.25f) {
|
||||
if ((attackTarget->position - requestedWalkTarget).norm() > TARGET_REPLAN_THRESHOLD) {
|
||||
} else if (distanceSquared >= static_cast<fp>(1.25f*1.25f)) {
|
||||
if ((attackTarget->position - requestedWalkTarget).normSquared() > TARGET_REPLAN_THRESHOLD_SQUARED) {
|
||||
events.navigationRequested = true;
|
||||
events.navigationTarget = attackTarget->position;
|
||||
}
|
||||
@@ -228,21 +240,22 @@ CharacterUpdateEvents CharacterState::update(
|
||||
}
|
||||
}
|
||||
|
||||
const Eigen::Vector3f activeTarget = getCurrentNavigationTarget();
|
||||
const Eigen::Vector3f lookTarget =
|
||||
const Vec3fp activeTarget = getCurrentNavigationTarget();
|
||||
const Vec3fp lookTarget =
|
||||
battle_state == 1 && attackTarget ? attackTarget->position : activeTarget;
|
||||
|
||||
if (currentState == AnimationState::WALK || currentState == AnimationState::STAND) {
|
||||
Eigen::Vector3f toTarget = activeTarget - position;
|
||||
toTarget.y() = 0.f;
|
||||
const float distance = toTarget.norm();
|
||||
if (distance > kWalkThreshold) {
|
||||
const Eigen::Vector3f direction = toTarget / distance;
|
||||
const float moveAmount = walkSpeed * static_cast<float>(deltaMs) / 1000.f;
|
||||
Eigen::Vector3f candidate =
|
||||
Vec3fp toTarget = activeTarget - position;
|
||||
toTarget.y = static_cast<fp>(0.f);
|
||||
const fp distanceSquared = toTarget.normSquared();
|
||||
if (distanceSquared > kWalkThreshold_SQUARED()) {
|
||||
fp distance = sqrt(distanceSquared); //FP SQRT
|
||||
const Vec3fp direction = toTarget / distance;
|
||||
const fp moveAmount = walkSpeed * static_cast<fp>(deltaMs) / static_cast < fp>(1000.f);
|
||||
Vec3fp candidate =
|
||||
moveAmount >= distance ? activeTarget : position + direction * moveAmount;
|
||||
candidate.y() = 0.f;
|
||||
const CharacterMovementObstacle* blocker = nullptr;
|
||||
candidate.y = static_cast<fp>(0.f);
|
||||
/*const CharacterMovementObstacle* blocker = nullptr;
|
||||
if (context.movementObstacles) {
|
||||
for (const CharacterMovementObstacle& obstacle :
|
||||
*context.movementObstacles) {
|
||||
@@ -296,15 +309,15 @@ CharacterUpdateEvents CharacterState::update(
|
||||
navigationPausedThisTick = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else*/{
|
||||
movedLastTick =
|
||||
(candidate - position).squaredNorm() > 1e-8f;
|
||||
(candidate - position).normSquared() > static_cast<fp>(1e-8f);
|
||||
position = candidate;
|
||||
movementBlockedTicks = 0;
|
||||
blockingCharacterId.clear();
|
||||
}
|
||||
targetFacingAngle = std::atan2(direction.x(), -direction.z());
|
||||
if (!blocker) currentState = AnimationState::WALK;
|
||||
targetFacingAngle = fpm::atan2(direction.x, -direction.z);
|
||||
currentState = AnimationState::WALK;
|
||||
} else {
|
||||
currentState = AnimationState::STAND;
|
||||
const bool completedPath = !pathWaypoints.empty();
|
||||
@@ -316,8 +329,8 @@ CharacterUpdateEvents CharacterState::update(
|
||||
pathWaypoints.clear();
|
||||
currentWaypointIndex = 0;
|
||||
if (completedPath &&
|
||||
(requestedWalkTarget - position).norm() >
|
||||
TARGET_REPLAN_THRESHOLD &&
|
||||
(requestedWalkTarget - position).normSquared() >
|
||||
TARGET_REPLAN_THRESHOLD_SQUARED &&
|
||||
!isPlayer)
|
||||
scheduleNextNavigationRetry();
|
||||
if (completedPath && !onArrivedCallbackName.empty()) {
|
||||
@@ -327,11 +340,11 @@ CharacterUpdateEvents CharacterState::update(
|
||||
}
|
||||
|
||||
if (faceTarget) {
|
||||
Eigen::Vector3f toFace = faceTarget->position - position;
|
||||
toFace.y() = 0.f;
|
||||
const float distanceToFace = toFace.norm();
|
||||
targetFacingAngle = distanceToFace > 1e-3f
|
||||
? std::atan2(toFace.x() / distanceToFace, -toFace.z() / distanceToFace)
|
||||
Vec3fp toFace = faceTarget->position - position;
|
||||
toFace.y = static_cast<fp>(0.f);
|
||||
const fp distanceToFace = sqrt(toFace.normSquared()); //FP SQRT
|
||||
targetFacingAngle = distanceToFace > static_cast<fp>(1e-3f)
|
||||
? fpm::atan2(toFace.x / distanceToFace, -toFace.z / distanceToFace)
|
||||
: facingAngle;
|
||||
} else if (!faceTargetId.empty()) {
|
||||
faceTargetId.clear();
|
||||
@@ -340,7 +353,7 @@ CharacterUpdateEvents CharacterState::update(
|
||||
}
|
||||
|
||||
if (!isPlayer && !navigationPausedThisTick && pathWaypoints.empty() &&
|
||||
(requestedWalkTarget - position).norm() > TARGET_REPLAN_THRESHOLD &&
|
||||
(requestedWalkTarget - position).normSquared() > TARGET_REPLAN_THRESHOLD_SQUARED &&
|
||||
!events.navigationRequested) {
|
||||
if (navigationRetryTicks > 0) --navigationRetryTicks;
|
||||
if (navigationRetryTicks == 0) {
|
||||
@@ -359,8 +372,8 @@ CharacterUpdateEvents CharacterState::update(
|
||||
attackTargetId.clear();
|
||||
}
|
||||
} else if (battle_state == 1 && attackTarget) {
|
||||
targetFacingAngle = std::atan2(
|
||||
lookTarget.x() - position.x(), -(lookTarget.z() - position.z()));
|
||||
targetFacingAngle = fpm::atan2(
|
||||
lookTarget.x - position.x, -(lookTarget.z - position.z));
|
||||
if (currentState == AnimationState::STAND || currentState == AnimationState::WALK) {
|
||||
currentState = AnimationState::STAND_TO_ACTION;
|
||||
resetAnim = true;
|
||||
@@ -384,24 +397,25 @@ CharacterUpdateEvents CharacterState::update(
|
||||
resetAnim = true;
|
||||
}
|
||||
|
||||
float angleDiff = targetFacingAngle - facingAngle;
|
||||
while (angleDiff > PI) angleDiff -= 2.f * PI;
|
||||
while (angleDiff < -PI) angleDiff += 2.f * PI;
|
||||
const float rotationStep = rotationSpeed * static_cast<float>(deltaMs) / 1000.f;
|
||||
if (std::fabs(angleDiff) <= rotationStep) {
|
||||
fp angleDiff = targetFacingAngle - facingAngle;
|
||||
const fp PIfp = static_cast<fp>(PI);
|
||||
while (angleDiff > PIfp) angleDiff -= static_cast<fp>(2.f) * PIfp;
|
||||
while (angleDiff < -PIfp) angleDiff += static_cast<fp>(2.f) * PIfp;
|
||||
const fp rotationStep = rotationSpeed * static_cast<fp>(deltaMs) / static_cast<fp>(1000.f);
|
||||
if (fpm::abs(angleDiff) <= rotationStep) {
|
||||
facingAngle = targetFacingAngle;
|
||||
faceTargetId.clear();
|
||||
} else {
|
||||
facingAngle += angleDiff > 0.f ? rotationStep : -rotationStep;
|
||||
facingAngle += angleDiff > static_cast<fp>(0.f) ? rotationStep : -rotationStep;
|
||||
}
|
||||
|
||||
if (!isPlayer && hp > 0.f && battle_state == 0 && maxHomeDrift > 0.f) {
|
||||
homeDriftCheckTimer -= static_cast<float>(deltaMs) / 1000.f;
|
||||
if (homeDriftCheckTimer <= 0.f) {
|
||||
homeDriftCheckTimer = HOME_DRIFT_CHECK_INTERVAL;
|
||||
Eigen::Vector3f toHome = homePosition - position;
|
||||
toHome.y() = 0.f;
|
||||
if (!isMoving() && toHome.norm() > maxHomeDrift) {
|
||||
if (!isPlayer && hp > 0.f && battle_state == 0 && maxHomeDriftSquared > static_cast<fp>(0.f)) {
|
||||
homeDriftCheckTimer -= static_cast<fp>(deltaMs) / static_cast<fp>(1000.f);
|
||||
if (homeDriftCheckTimer <= static_cast <fp>(0.f)) {
|
||||
homeDriftCheckTimer = HOME_DRIFT_CHECK_INTERVAL_FP;
|
||||
Vec3fp toHome = homePosition - position;
|
||||
toHome.y = static_cast<fp>(0.f);
|
||||
if (!isMoving() && toHome.normSquared() > maxHomeDriftSquared) {
|
||||
events.navigationRequested = true;
|
||||
events.navigationTarget = homePosition;
|
||||
}
|
||||
@@ -424,10 +438,18 @@ CharacterUpdateEvents CharacterState::update(
|
||||
events.attackImpact = true;
|
||||
events.attackTargetId = attackTargetId;
|
||||
events.attackDirection = attackTarget->position - position;
|
||||
events.attackDirection.y() = 0.f;
|
||||
const float length = events.attackDirection.norm();
|
||||
if (length > 1e-3f) events.attackDirection /= length;
|
||||
else events.attackDirection = Eigen::Vector3f::Zero();
|
||||
events.attackDirection.y = static_cast<fp>(0.f);
|
||||
const fp lengthSquared = fpm::sqrt(events.attackDirection.normSquared());
|
||||
if (lengthSquared > static_cast<fp>(1e-3f * 1e-3f))
|
||||
{
|
||||
const fp length = fpm::sqrt(lengthSquared); //FP SQRT
|
||||
|
||||
events.attackDirection = events.attackDirection / length;
|
||||
}
|
||||
else
|
||||
{
|
||||
events.attackDirection = Vec3fp{};
|
||||
}
|
||||
}
|
||||
|
||||
showWeapon =
|
||||
@@ -463,9 +485,9 @@ CharacterUpdateEvents CharacterState::update(
|
||||
|
||||
void CharacterState::save(nlohmann::json& out) const
|
||||
{
|
||||
out["position"] = { position.x(), position.y(), position.z() };
|
||||
out["facingAngle"] = facingAngle;
|
||||
out["targetFacingAngle"] = targetFacingAngle;
|
||||
out["position"] = { static_cast<double>(position.x), static_cast<double>(position.y), static_cast<double>(position.z) };
|
||||
out["facingAngle"] = static_cast<double>(facingAngle);
|
||||
out["targetFacingAngle"] = static_cast<double>(targetFacingAngle);
|
||||
out["hp"] = hp;
|
||||
out["enabled"] = enabled;
|
||||
out["battle_state"] = battle_state;
|
||||
@@ -474,16 +496,16 @@ void CharacterState::save(nlohmann::json& out) const
|
||||
out["showWeapon"] = showWeapon;
|
||||
out["attackTargetId"] = attackTargetId;
|
||||
out["faceTargetId"] = faceTargetId;
|
||||
out["homePosition"] = { homePosition.x(), homePosition.y(), homePosition.z() };
|
||||
out["walkTarget"] = { walkTarget.x(), walkTarget.y(), walkTarget.z() };
|
||||
out["requestedWalkTarget"] = { requestedWalkTarget.x(), requestedWalkTarget.y(), requestedWalkTarget.z() };
|
||||
out["homePosition"] = { static_cast<double>(homePosition.x), static_cast<double>(homePosition.y), static_cast<double>(homePosition.z) };
|
||||
out["walkTarget"] = { static_cast<double>(walkTarget.x), static_cast<double>(walkTarget.y), static_cast<double>(walkTarget.z) };
|
||||
out["requestedWalkTarget"] = { static_cast<double>(requestedWalkTarget.x), static_cast<double>(requestedWalkTarget.y), static_cast<double>(requestedWalkTarget.z) };
|
||||
nlohmann::json wpArr = nlohmann::json::array();
|
||||
for (const auto& wp : pathWaypoints) {
|
||||
wpArr.push_back({ wp.x(), wp.y(), wp.z() });
|
||||
wpArr.push_back({ static_cast<double>(wp.x), static_cast<double>(wp.y), static_cast<double>(wp.z) });
|
||||
}
|
||||
out["pathWaypoints"] = std::move(wpArr);
|
||||
out["currentWaypointIndex"] = currentWaypointIndex;
|
||||
out["homeDriftCheckTimer"] = homeDriftCheckTimer;
|
||||
out["homeDriftCheckTimer"] = static_cast<double>(homeDriftCheckTimer);
|
||||
out["movementBlockedTicks"] = movementBlockedTicks;
|
||||
out["navigationRetryTicks"] = navigationRetryTicks;
|
||||
out["movedLastTick"] = movedLastTick;
|
||||
@@ -492,7 +514,7 @@ void CharacterState::save(nlohmann::json& out) const
|
||||
if (!blockingCharacterId.empty())
|
||||
out["blockingCharacterId"] = blockingCharacterId;
|
||||
out["animationFrame"] = animationFrame;
|
||||
out["visibleRange"] = visibleRange;
|
||||
out["visibleRange"] = static_cast<double>(visibleRange);
|
||||
if (!onArrivedCallbackName.empty())
|
||||
out["onArrivedCallbackName"] = onArrivedCallbackName;
|
||||
}
|
||||
@@ -505,11 +527,19 @@ void CharacterState::load(const nlohmann::json& in)
|
||||
return def;
|
||||
};
|
||||
|
||||
if (in.contains("position")) position = readVec3(in["position"], position);
|
||||
facingAngle = in.value("facingAngle", facingAngle);
|
||||
targetFacingAngle = in.value("targetFacingAngle", targetFacingAngle);
|
||||
auto readVec3fp = [](const nlohmann::json& j, Vec3fp def) -> Vec3fp {
|
||||
if (j.is_array() && j.size() == 3)
|
||||
return Vec3fp{ static_cast<fp>(j[0].get<double>()), static_cast<fp>(j[1].get<double>()), static_cast<fp>(j[2].get<double>()) };
|
||||
return def;
|
||||
};
|
||||
|
||||
if (in.contains("position")) {
|
||||
position = readVec3fp(in["position"], position);
|
||||
}
|
||||
facingAngle = static_cast<fp>(in.value("facingAngle", static_cast<double>(facingAngle)));
|
||||
targetFacingAngle = static_cast<fp>(in.value("targetFacingAngle", static_cast<double>(targetFacingAngle)));
|
||||
hp = in.value("hp", hp);
|
||||
visibleRange = in.value("visibleRange", visibleRange);
|
||||
visibleRange = static_cast<fp>(in.value("visibleRange", static_cast<double>(visibleRange)));
|
||||
enabled = in.value("enabled", enabled);
|
||||
battle_state = in.value("battle_state", battle_state);
|
||||
currentState = static_cast<AnimationState>(in.value("currentState", static_cast<int>(currentState)));
|
||||
@@ -517,17 +547,17 @@ void CharacterState::load(const nlohmann::json& in)
|
||||
showWeapon = in.value("showWeapon", showWeapon);
|
||||
attackTargetId = in.value("attackTargetId", attackTargetId);
|
||||
faceTargetId = in.value("faceTargetId", faceTargetId);
|
||||
if (in.contains("homePosition")) homePosition = readVec3(in["homePosition"], homePosition);
|
||||
if (in.contains("walkTarget")) walkTarget = readVec3(in["walkTarget"], walkTarget);
|
||||
if (in.contains("requestedWalkTarget")) requestedWalkTarget = readVec3(in["requestedWalkTarget"], requestedWalkTarget);
|
||||
if (in.contains("homePosition")) homePosition = readVec3fp(in["homePosition"], homePosition);
|
||||
if (in.contains("walkTarget")) walkTarget = readVec3fp(in["walkTarget"], walkTarget);
|
||||
if (in.contains("requestedWalkTarget")) requestedWalkTarget = readVec3fp(in["requestedWalkTarget"], requestedWalkTarget);
|
||||
pathWaypoints.clear();
|
||||
if (in.contains("pathWaypoints") && in["pathWaypoints"].is_array()) {
|
||||
for (const auto& wp : in["pathWaypoints"]) {
|
||||
pathWaypoints.push_back(readVec3(wp, Eigen::Vector3f::Zero()));
|
||||
pathWaypoints.push_back(readVec3fp(wp, Vec3fp()));
|
||||
}
|
||||
}
|
||||
currentWaypointIndex = in.value("currentWaypointIndex", currentWaypointIndex);
|
||||
homeDriftCheckTimer = in.value("homeDriftCheckTimer", homeDriftCheckTimer);
|
||||
homeDriftCheckTimer = static_cast<fp>(in.value("homeDriftCheckTimer", static_cast<double>(homeDriftCheckTimer)));
|
||||
movementBlockedTicks = in.value("movementBlockedTicks", movementBlockedTicks);
|
||||
navigationRetryTicks = in.value("navigationRetryTicks", navigationRetryTicks);
|
||||
movedLastTick = in.value("movedLastTick", movedLastTick);
|
||||
|
||||
Reference in new issue
Block a user