fix npc
This commit is contained in:
parent
5df2216da6
commit
9793c5bf06
@ -835,7 +835,7 @@ namespace ZL
|
||||
{
|
||||
if (!textRenderer) return;
|
||||
|
||||
#ifdef NETWORK
|
||||
//#ifdef NETWORK
|
||||
// 2D поверх 3D
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
@ -882,7 +882,7 @@ namespace ZL
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
|
||||
void Game::processTickCount() {
|
||||
|
||||
@ -68,7 +68,7 @@ namespace ZL {
|
||||
Eigen::Vector3f LocalClient::generateRandomPosition() {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<> distrib(-50.0, 50.0);
|
||||
std::uniform_real_distribution<> distrib(-500.0, 500.0);
|
||||
|
||||
return Eigen::Vector3f(
|
||||
(float)distrib(gen),
|
||||
@ -79,26 +79,24 @@ namespace ZL {
|
||||
|
||||
void LocalClient::initializeNPCs() {
|
||||
npcs.clear();
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
LocalNPC npc;
|
||||
npc.id = 100 + i;
|
||||
npc.speed = 20.0f + (i * 5.0f);
|
||||
npc.currentState.id = npc.id;
|
||||
npc.currentState.position = generateRandomPosition();
|
||||
npc.currentState.rotation = Eigen::Matrix3f::Identity();
|
||||
npc.currentState.velocity = npc.speed;
|
||||
npc.currentState.velocity = 0.0f;
|
||||
npc.currentState.selectedVelocity = 0;
|
||||
npc.currentState.discreteMag = 0.0f;
|
||||
npc.currentState.discreteAngle = -1;
|
||||
npc.currentState.currentAngularVelocity = Eigen::Vector3f::Zero();
|
||||
|
||||
npc.targetPosition = generateRandomPosition();
|
||||
npc.lastStateUpdateMs = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
npc.stateHistory.add_state(npc.currentState);
|
||||
npcs.push_back(npc);
|
||||
|
||||
std::cout << "LocalClient: Created NPC with id=" << npc.id
|
||||
<< " at pos (" << npc.currentState.position.x() << ", "
|
||||
<< npc.currentState.position.y() << ", "
|
||||
<< npc.currentState.position.z() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,37 +106,76 @@ namespace ZL {
|
||||
|
||||
for (auto& npc : npcs) {
|
||||
uint64_t deltaMs = now_ms - npc.lastStateUpdateMs;
|
||||
float dt = deltaMs / 1000.0f;
|
||||
if (deltaMs == 0) {
|
||||
npc.lastStateUpdateMs = now_ms;
|
||||
continue;
|
||||
}
|
||||
npc.lastStateUpdateMs = now_ms;
|
||||
|
||||
Eigen::Vector3f direction = npc.targetPosition - npc.currentState.position;
|
||||
float distance = direction.norm();
|
||||
Eigen::Vector3f toTarget = npc.targetPosition - npc.currentState.position;
|
||||
float distance = toTarget.norm();
|
||||
|
||||
if (distance < 5.0f) {
|
||||
const float ARRIVAL_THRESHOLD = 100.0f;
|
||||
|
||||
if (distance < ARRIVAL_THRESHOLD) {
|
||||
npc.targetPosition = generateRandomPosition();
|
||||
direction = npc.targetPosition - npc.currentState.position;
|
||||
distance = direction.norm();
|
||||
toTarget = npc.targetPosition - npc.currentState.position;
|
||||
distance = toTarget.norm();
|
||||
}
|
||||
|
||||
if (distance > 0.001f) {
|
||||
direction.normalize();
|
||||
npc.currentState.position += direction * npc.speed * dt;
|
||||
npc.currentState.velocity = npc.speed;
|
||||
Eigen::Vector3f forwardWorld = -npc.currentState.rotation.col(2);
|
||||
forwardWorld.normalize();
|
||||
|
||||
Eigen::Vector3f localForward(0.0f, 0.0f, -1.0f);
|
||||
Eigen::Vector3f worldForward = direction;
|
||||
Eigen::Vector3f desiredDir = (distance > 0.001f) ? toTarget.normalized() : Eigen::Vector3f::UnitZ();
|
||||
float dot = forwardWorld.dot(desiredDir);
|
||||
float angleErrorRad = std::acos(std::clamp(dot, -1.0f, 1.0f));
|
||||
|
||||
Eigen::Vector3f cross = localForward.cross(worldForward);
|
||||
float dot = localForward.dot(worldForward);
|
||||
const float ALIGN_TOLERANCE = 0.15f;
|
||||
|
||||
if (cross.norm() > 0.001f) {
|
||||
float angle = std::atan2(cross.norm(), dot);
|
||||
cross.normalize();
|
||||
Eigen::AngleAxisf aa(angle * 0.05f, cross);
|
||||
npc.currentState.rotation = npc.currentState.rotation * aa.toRotationMatrix();
|
||||
const float HYSTERESIS_FACTOR = 1.35f;
|
||||
const float SOFT_THRUST_ANGLE = ALIGN_TOLERANCE * HYSTERESIS_FACTOR;
|
||||
|
||||
if (angleErrorRad < ALIGN_TOLERANCE) {
|
||||
npc.currentState.selectedVelocity = 1;
|
||||
npc.currentState.discreteMag = 0.0f;
|
||||
}
|
||||
else if (angleErrorRad < SOFT_THRUST_ANGLE) {
|
||||
npc.currentState.selectedVelocity = 1;
|
||||
npc.currentState.discreteMag = std::min(0.50f, (angleErrorRad - ALIGN_TOLERANCE) * 10.0f);
|
||||
}
|
||||
else {
|
||||
npc.currentState.selectedVelocity = 0;
|
||||
|
||||
Eigen::Vector3f localDesired = npc.currentState.rotation.transpose() * desiredDir;
|
||||
float dx = localDesired.x();
|
||||
float dy = localDesired.y();
|
||||
float dz = localDesired.z();
|
||||
|
||||
float turnX = dy;
|
||||
float turnY = -dx;
|
||||
float turnLen = std::sqrt(turnX * turnX + turnY * turnY);
|
||||
|
||||
if (turnLen > 0.0001f) {
|
||||
turnX /= turnLen;
|
||||
turnY /= turnLen;
|
||||
|
||||
float rad = std::atan2(turnX, turnY);
|
||||
int angleDeg = static_cast<int>(std::round(rad * 180.0f / M_PI));
|
||||
if (angleDeg < 0) angleDeg += 360;
|
||||
|
||||
npc.currentState.discreteAngle = angleDeg;
|
||||
npc.currentState.discreteMag = std::min(1.0f, angleErrorRad * 2.2f);
|
||||
}
|
||||
else if (angleErrorRad > 0.1f) {
|
||||
npc.currentState.discreteAngle = 0;
|
||||
npc.currentState.discreteMag = 1.0f;
|
||||
}
|
||||
else {
|
||||
npc.currentState.discreteMag = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
npc.currentState.simulate_physics(static_cast<size_t>(deltaMs));
|
||||
npc.currentState.lastUpdateServerTime = std::chrono::system_clock::time_point(
|
||||
std::chrono::milliseconds(now_ms));
|
||||
npc.stateHistory.add_state(npc.currentState);
|
||||
|
||||
@ -29,7 +29,6 @@ namespace ZL {
|
||||
ClientState currentState;
|
||||
ClientStateInterval stateHistory;
|
||||
Eigen::Vector3f targetPosition;
|
||||
float speed = 30.0f;
|
||||
uint64_t lastStateUpdateMs = 0;
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user