fixed rotation moving
This commit is contained in:
parent
fb4a860773
commit
d76342f3fa
108
src/Game.cpp
108
src/Game.cpp
@ -687,48 +687,78 @@ namespace ZL
|
||||
bool joystickActive = isUsingJoystick && joystick && joystick->isActive;
|
||||
|
||||
if (joystickActive) {
|
||||
float joyX = -joystick->getDirectionX(); // -1..1
|
||||
float joyY = joystick->getDirectionY(); // -1..1 (вверх обычно отрицательный)
|
||||
float joyX = joystick->getDirectionX(); // <-- оставляем инверсию X
|
||||
float joyY = joystick->getDirectionY();
|
||||
float magnitude = joystick->getMagnitude();
|
||||
|
||||
const float deadzone = 0.1f;
|
||||
|
||||
Vector3f newMoveDir = Vector3f::Zero();
|
||||
float newMag = 0.0f;
|
||||
|
||||
if (magnitude > deadzone) {
|
||||
|
||||
// forward/right из ТЕКУЩЕГО camYaw (без lock)
|
||||
Vector3f forward(-sinf(camYaw), 0.0f, -cosf(camYaw));
|
||||
Vector3f right(cosf(camYaw), 0.0f, -sinf(camYaw));
|
||||
// Берём ориентацию камеры из view matrix:
|
||||
// view = World -> View, значит Rcw = (Rwv)^T = View -> World
|
||||
Matrix4f viewM = camera.getViewMatrix();
|
||||
Matrix3f Rwv = viewM.block<3, 3>(0, 0);
|
||||
Matrix3f Rcw = Rwv.transpose();
|
||||
|
||||
// joyY: если вверх = отрицательный, то "- forward * joyY" даёт движение вперёд при joyY<0
|
||||
Vector3f worldMove = right * joyX - forward * joyY;
|
||||
Vector3f camRight = (Rcw * Vector3f(1, 0, 0));
|
||||
Vector3f camForward = (Rcw * Vector3f(0, 0, -1)); // куда смотрит камера в мире
|
||||
|
||||
if (camRight.squaredNorm() > 1e-6f) camRight.normalize();
|
||||
if (camForward.squaredNorm() > 1e-6f) camForward.normalize();
|
||||
|
||||
// joystick: X = вправо/влево, Y = вверх/вниз
|
||||
// joyY обычно отрицательный при "вверх", поэтому "- camForward * joyY" даёт "вперёд"
|
||||
Vector3f worldMove = camRight * joyX - camForward * joyY;
|
||||
|
||||
if (worldMove.squaredNorm() > 1e-6f) {
|
||||
worldMove.normalize();
|
||||
|
||||
float ang = atan2f(worldMove.x(), worldMove.z()); // 0 -> +Z
|
||||
int a = (int)std::round(ang * 180.0f / (float)M_PI);
|
||||
if (a < 0) a += 360;
|
||||
a %= 360;
|
||||
|
||||
discreteAngle = a;
|
||||
|
||||
discreteMag = (std::min)(magnitude, 1.0f);
|
||||
discreteMag = std::round(discreteMag * 10.0f) / 10.0f;
|
||||
newMoveDir = worldMove.normalized();
|
||||
newMag = (std::min)(magnitude, 1.0f);
|
||||
newMag = std::round(newMag * 10.0f) / 10.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Применяем в shipState
|
||||
bool changed = false;
|
||||
|
||||
if ((Environment::shipState.currentAngularVelocity - newMoveDir).norm() > 0.001f) {
|
||||
Environment::shipState.currentAngularVelocity = newMoveDir; // <-- теперь это "moveDirWorld"
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (fabs(Environment::shipState.discreteMag - newMag) > 0.001f) {
|
||||
Environment::shipState.discreteMag = newMag; // throttle
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// discreteAngle больше не нужен для движения (можешь оставить -1)
|
||||
if (Environment::shipState.discreteAngle != -1) {
|
||||
Environment::shipState.discreteAngle = -1;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent();
|
||||
networkClient->Send(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Network Update
|
||||
bool changed = false;
|
||||
//bool changed = false;
|
||||
|
||||
if (discreteAngle != Environment::shipState.discreteAngle) {
|
||||
Environment::shipState.discreteAngle = discreteAngle;
|
||||
changed = true;
|
||||
}
|
||||
if (discreteMag != Environment::shipState.discreteMag) {
|
||||
Environment::shipState.discreteMag = discreteMag;
|
||||
changed = true;
|
||||
}
|
||||
//if (discreteAngle != Environment::shipState.discreteAngle) {
|
||||
// Environment::shipState.discreteAngle = discreteAngle;
|
||||
// changed = true;
|
||||
//}
|
||||
//if (discreteMag != Environment::shipState.discreteMag) {
|
||||
// Environment::shipState.discreteMag = discreteMag;
|
||||
// changed = true;
|
||||
//}
|
||||
|
||||
// slider value применяем здесь (ты раньше только newShipVelocity менял)
|
||||
//int newVelInt = (int)newShipVelocity;
|
||||
@ -737,9 +767,27 @@ namespace ZL
|
||||
// changed = true;
|
||||
//}
|
||||
|
||||
if (changed) {
|
||||
std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent();
|
||||
networkClient->Send(msg);
|
||||
//if (changed) {
|
||||
// std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent();
|
||||
// networkClient->Send(msg);
|
||||
//}
|
||||
// Network Update (только если НЕ используем джойстик)
|
||||
if (!joystickActive) {
|
||||
bool changed2 = false;
|
||||
|
||||
if (discreteAngle != Environment::shipState.discreteAngle) {
|
||||
Environment::shipState.discreteAngle = discreteAngle;
|
||||
changed2 = true;
|
||||
}
|
||||
if (discreteMag != Environment::shipState.discreteMag) {
|
||||
Environment::shipState.discreteMag = discreteMag;
|
||||
changed2 = true;
|
||||
}
|
||||
|
||||
if (changed2) {
|
||||
std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent();
|
||||
networkClient->Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -46,11 +46,8 @@ void ClientState::simulate_physics(size_t deltaMs)
|
||||
const float ROT_T = std::clamp(ROTATION_SENSITIVITY * static_cast<float>(deltaMs), 0.0f, 1.0f);
|
||||
// -------------------------------------------
|
||||
|
||||
// We keep this for protocol compatibility, but it no longer affects anything.
|
||||
currentAngularVelocity = Eigen::Vector3f::Zero();
|
||||
|
||||
// Input validity
|
||||
const bool hasInput = (discreteAngle >= 0) && (discreteMag > 0.01f);
|
||||
const bool hasInput = (discreteMag > 0.01f) && (currentAngularVelocity.squaredNorm() > 1e-6f);
|
||||
|
||||
// Speed command:
|
||||
// - Prefer discreteMag (joystick magnitude)
|
||||
@ -75,37 +72,47 @@ void ClientState::simulate_physics(size_t deltaMs)
|
||||
// ang = atan2(worldMove.x, worldMove.z)
|
||||
// So we reconstruct as:
|
||||
// x = sin(rad), z = cos(rad)
|
||||
const float rad = DegToRad(static_cast<float>(discreteAngle));
|
||||
Eigen::Vector3f moveDirWorld = currentAngularVelocity.normalized();
|
||||
|
||||
|
||||
Eigen::Vector3f veccc(0.0f, 0.0f, -1.0f);
|
||||
|
||||
Eigen::Vector3f veccc_rotated = rotation * veccc;
|
||||
|
||||
Eigen::Vector3f moveDirWorld(
|
||||
sinf(rad),
|
||||
0.0f,
|
||||
cosf(rad)
|
||||
);
|
||||
|
||||
if (moveDirWorld.squaredNorm() > 1e-6f) {
|
||||
moveDirWorld.normalize();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move in world
|
||||
position += moveDirWorld * (velocity * dt);
|
||||
//position += moveDirWorld * (velocity * dt);
|
||||
position += veccc_rotated * (velocity * dt);
|
||||
|
||||
// Rotate ship to face movement direction (optional).
|
||||
// Ship local forward is (0,0,-1) (as in your fireProjectiles).
|
||||
// We need yaw so that rotation * (0,0,-1) == moveDirWorld.
|
||||
// That yaw is: yaw = atan2(-dir.x, -dir.z)
|
||||
{
|
||||
float desiredYaw = atan2f(-moveDirWorld.x(), -moveDirWorld.z());
|
||||
Eigen::Vector3f worldUp(0.0f, 1.0f, 0.0f);
|
||||
|
||||
// local forward = (0,0,-1) => значит Z-ось мира должна смотреть в -moveDirWorld
|
||||
Eigen::Vector3f zAxis = -moveDirWorld;
|
||||
Eigen::Vector3f xAxis = worldUp.cross(zAxis);
|
||||
|
||||
if (xAxis.squaredNorm() < 1e-6f) xAxis = Eigen::Vector3f(1, 0, 0);
|
||||
xAxis.normalize();
|
||||
|
||||
Eigen::Vector3f yAxis = zAxis.cross(xAxis).normalized();
|
||||
|
||||
Eigen::Matrix3f R;
|
||||
R.col(0) = xAxis;
|
||||
R.col(1) = yAxis;
|
||||
R.col(2) = zAxis;
|
||||
|
||||
Eigen::Quaternionf qCur(rotation);
|
||||
Eigen::Quaternionf qTar(Eigen::AngleAxisf(desiredYaw, Eigen::Vector3f::UnitY()));
|
||||
Eigen::Quaternionf qTar(R);
|
||||
|
||||
Eigen::Quaternionf qNew = qCur.slerp(ROT_T, qTar).normalized();
|
||||
rotation = qNew.toRotationMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ClientState::apply_lag_compensation(std::chrono::system_clock::time_point nowTime)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user