Also interpolate taxi and interactive objects

This commit is contained in:
Vladislav Khorev committed 2026-11-06 15:33:15 +06:00
1 parent 28846b9f25
commit 1ab9f300b6
5 files changed
+213 -28

No files matched your search

+72 -16
View File
@@ -1134,12 +1134,8 @@ namespace FRG
drawInstancedStatics("shadow_depth_inst", InstancedTexture::None);
for (auto& intObj : interactiveObjects) {
if (intObj.state.castShadow && intObj.loadedObject.texture) {
renderer.PushMatrix();
renderer.TranslateMatrix(intObj.state.position);
renderer.DrawVertexRenderStruct(intObj.loadedObject.mesh);
renderer.PopMatrix();
}
if (intObj.state.castShadow)
intObj.drawShadowDepth(renderer);
}
// Draw characters (they handle their own skinning shader switch internally)
@@ -1431,12 +1427,8 @@ namespace FRG
}
drawInstancedStatics("shadow_depth_inst", InstancedTexture::None);
for (auto& intObj : interactiveObjects) {
if (intObj.state.castShadowNight && intObj.loadedObject.texture) {
renderer.PushMatrix();
renderer.TranslateMatrix(intObj.state.position);
renderer.DrawVertexRenderStruct(intObj.loadedObject.mesh);
renderer.PopMatrix();
}
if (intObj.state.castShadowNight)
intObj.drawShadowDepth(renderer);
}
if (player) player->drawShadowDepth(renderer);
for (auto& [id, remote] : remotePlayers_)
@@ -1453,14 +1445,75 @@ namespace FRG
shadowMap->unbind();
}
void Location::captureNpcCarPresentation(const NpcCar& car)
{
NpcCarPresentationSample sample;
sample.position = car.position;
sample.rotation = car.rotation;
sample.wheelAngle = car.wheelAngle;
sample.steeringAngle = car.steeringAngle;
const auto now = std::chrono::steady_clock::now();
const bool largeGap = hasNpcCarPresentationSample_ &&
std::chrono::duration_cast<std::chrono::milliseconds>(
now - lastNpcCarPresentationUpdate_).count() > 250;
if (!hasNpcCarPresentationSample_ || largeGap) {
previousNpcCarPresentation_ = sample;
} else {
previousNpcCarPresentation_ = currentNpcCarPresentation_;
}
currentNpcCarPresentation_ = sample;
lastNpcCarPresentationUpdate_ = now;
hasNpcCarPresentationSample_ = true;
}
Location::NpcCarPresentationSample
Location::interpolatedNpcCarPresentation(const NpcCar& car) const
{
NpcCarPresentationSample result;
result.position = car.position;
result.rotation = car.rotation;
result.wheelAngle = car.wheelAngle;
result.steeringAngle = car.steeringAngle;
if (!hasNpcCarPresentationSample_) return result;
constexpr float kSimulationTickMs = 100.0f;
const float elapsedMs = static_cast<float>(
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - lastNpcCarPresentationUpdate_).count());
const float alpha = (std::max)(0.0f,
(std::min)(1.0f, elapsedMs / kSimulationTickMs));
result.position = previousNpcCarPresentation_.position +
alpha * (currentNpcCarPresentation_.position -
previousNpcCarPresentation_.position);
result.wheelAngle = previousNpcCarPresentation_.wheelAngle +
alpha * (currentNpcCarPresentation_.wheelAngle -
previousNpcCarPresentation_.wheelAngle);
result.steeringAngle = previousNpcCarPresentation_.steeringAngle +
alpha * (currentNpcCarPresentation_.steeringAngle -
previousNpcCarPresentation_.steeringAngle);
constexpr float kPi = 3.14159265358979323846f;
constexpr float kTwoPi = 2.0f * kPi;
float rotationDelta = currentNpcCarPresentation_.rotation -
previousNpcCarPresentation_.rotation;
while (rotationDelta > kPi) rotationDelta -= kTwoPi;
while (rotationDelta < -kPi) rotationDelta += kTwoPi;
result.rotation = previousNpcCarPresentation_.rotation + alpha * rotationDelta;
return result;
}
void Location::drawNpcCar()
{
auto locationState = stateSnapshot();
if (!locationState) return;
const NpcCarPresentationSample car =
interpolatedNpcCarPresentation(locationState->taxiCar);
renderer.PushMatrix();
renderer.TranslateMatrix(locationState->taxiCar.position);
renderer.TranslateMatrix(car.position);
renderer.TranslateMatrix({ 0, 0.7f - 0.25f +x, 0 });
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(locationState->taxiCar.rotation, Eigen::Vector3f::UnitY())).toRotationMatrix());
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(car.rotation, Eigen::Vector3f::UnitY())).toRotationMatrix());
glBindTexture(GL_TEXTURE_2D, carTexture->getTexID());
renderer.DrawVertexRenderStruct(carMesh);
@@ -1480,10 +1533,10 @@ namespace FRG
for (int i = 0; i < 4; ++i) {
renderer.PushMatrix();
renderer.TranslateMatrix(wheelPositions[i]);
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(locationState->taxiCar.wheelAngle, -Eigen::Vector3f::UnitX())).toRotationMatrix());
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(car.wheelAngle, -Eigen::Vector3f::UnitX())).toRotationMatrix());
if (isFront[i]) {
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(locationState->taxiCar.steeringAngle, Eigen::Vector3f::UnitY())).toRotationMatrix());
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(car.steeringAngle, Eigen::Vector3f::UnitY())).toRotationMatrix());
}
renderer.DrawVertexRenderStruct(carWheelMesh);
renderer.PopMatrix();
@@ -1800,6 +1853,7 @@ namespace FRG
if (!locationState) return;
auto gameSnapshot = gameServer_.snapshot();
if (!gameSnapshot) return;
captureNpcCarPresentation(locationState->taxiCar);
if (events.taxiArrived)
scriptEngine.callCallTaxiCallback();
@@ -1936,6 +1990,8 @@ namespace FRG
}
}
for (auto& intObj : interactiveObjects)
intObj.capturePresentationState();
}
void Location::handleDown(int64_t fingerId, int eventX, int eventY, int mx, int my)