Also interpolate taxi and interactive objects
This commit is contained in:
1 parent
28846b9f25
commit
1ab9f300b6
5 files changed
+213
-28
No files matched your search
+72
-16
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user