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
@@ -5,6 +5,8 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
namespace FRG {
|
||||
@@ -68,8 +70,72 @@ namespace FRG {
|
||||
}
|
||||
|
||||
|
||||
void InteractiveObject::capturePresentationState()
|
||||
{
|
||||
PresentationSample sample;
|
||||
sample.position = state.position;
|
||||
sample.rotationY = state.rotationY;
|
||||
sample.scale = state.scale;
|
||||
sample.alpha = state.alpha;
|
||||
sample.isActive = state.isActive;
|
||||
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const bool largeGap = hasPresentationSample_ &&
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now - lastPresentationUpdate_).count() > 250;
|
||||
if (!hasPresentationSample_ || largeGap ||
|
||||
currentPresentationSample_.isActive != sample.isActive) {
|
||||
previousPresentationSample_ = sample;
|
||||
} else {
|
||||
previousPresentationSample_ = currentPresentationSample_;
|
||||
}
|
||||
currentPresentationSample_ = sample;
|
||||
lastPresentationUpdate_ = now;
|
||||
hasPresentationSample_ = true;
|
||||
}
|
||||
|
||||
InteractiveObject::PresentationSample
|
||||
InteractiveObject::interpolatedPresentationState() const
|
||||
{
|
||||
PresentationSample result;
|
||||
result.position = state.position;
|
||||
result.rotationY = state.rotationY;
|
||||
result.scale = state.scale;
|
||||
result.alpha = state.alpha;
|
||||
result.isActive = state.isActive;
|
||||
if (!hasPresentationSample_) 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() - lastPresentationUpdate_).count());
|
||||
const float alpha = (std::max)(0.0f,
|
||||
(std::min)(1.0f, elapsedMs / kSimulationTickMs));
|
||||
|
||||
result.position = previousPresentationSample_.position +
|
||||
alpha * (currentPresentationSample_.position -
|
||||
previousPresentationSample_.position);
|
||||
result.scale = previousPresentationSample_.scale +
|
||||
alpha * (currentPresentationSample_.scale -
|
||||
previousPresentationSample_.scale);
|
||||
result.alpha = previousPresentationSample_.alpha +
|
||||
alpha * (currentPresentationSample_.alpha -
|
||||
previousPresentationSample_.alpha);
|
||||
|
||||
constexpr float kPi = 3.14159265358979323846f;
|
||||
constexpr float kTwoPi = 2.0f * kPi;
|
||||
float rotationDelta = currentPresentationSample_.rotationY -
|
||||
previousPresentationSample_.rotationY;
|
||||
while (rotationDelta > kPi) rotationDelta -= kTwoPi;
|
||||
while (rotationDelta < -kPi) rotationDelta += kTwoPi;
|
||||
result.rotationY = previousPresentationSample_.rotationY +
|
||||
alpha * rotationDelta;
|
||||
return result;
|
||||
}
|
||||
|
||||
void InteractiveObject::drawDarklands(Renderer& renderer) const {
|
||||
if (!state.isActive || !loadedObject.textureDarklands) return;
|
||||
const PresentationSample presentation = interpolatedPresentationState();
|
||||
|
||||
if (state.alpha < 0.999f) {
|
||||
glEnable(GL_BLEND);
|
||||
@@ -77,16 +143,16 @@ namespace FRG {
|
||||
}
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix(state.position);
|
||||
if (state.rotationY != 0.f) {
|
||||
renderer.TranslateMatrix(presentation.position);
|
||||
if (presentation.rotationY != 0.f) {
|
||||
renderer.TranslateMatrix(state.pivot);
|
||||
renderer.RotateMatrix(Eigen::AngleAxisf(state.rotationY, Eigen::Vector3f::UnitY()).toRotationMatrix());
|
||||
renderer.RotateMatrix(Eigen::AngleAxisf(presentation.rotationY, Eigen::Vector3f::UnitY()).toRotationMatrix());
|
||||
renderer.TranslateMatrix(-state.pivot);
|
||||
}
|
||||
if (state.scale != 1.f)
|
||||
renderer.ScaleMatrix(state.scale);
|
||||
if (presentation.scale != 1.f)
|
||||
renderer.ScaleMatrix(presentation.scale);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
renderer.RenderUniform1f("uAlpha", state.alpha);
|
||||
renderer.RenderUniform1f("uAlpha", presentation.alpha);
|
||||
glBindTexture(GL_TEXTURE_2D, loadedObject.textureDarklands->getTexID());
|
||||
renderer.DrawVertexRenderStruct(loadedObject.mesh);
|
||||
renderer.PopMatrix();
|
||||
@@ -96,6 +162,7 @@ namespace FRG {
|
||||
|
||||
void InteractiveObject::draw(Renderer& renderer) const {
|
||||
if (!state.isActive || !loadedObject.texture) return;
|
||||
const PresentationSample presentation = interpolatedPresentationState();
|
||||
|
||||
if (state.alpha < 0.999f) {
|
||||
glEnable(GL_BLEND);
|
||||
@@ -103,16 +170,16 @@ namespace FRG {
|
||||
}
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix(state.position);
|
||||
if (state.rotationY != 0.f) {
|
||||
renderer.TranslateMatrix(presentation.position);
|
||||
if (presentation.rotationY != 0.f) {
|
||||
renderer.TranslateMatrix(state.pivot);
|
||||
renderer.RotateMatrix(Eigen::AngleAxisf(state.rotationY, Eigen::Vector3f::UnitY()).toRotationMatrix());
|
||||
renderer.RotateMatrix(Eigen::AngleAxisf(presentation.rotationY, Eigen::Vector3f::UnitY()).toRotationMatrix());
|
||||
renderer.TranslateMatrix(-state.pivot);
|
||||
}
|
||||
if (state.scale != 1.f)
|
||||
renderer.ScaleMatrix(state.scale);
|
||||
if (presentation.scale != 1.f)
|
||||
renderer.ScaleMatrix(presentation.scale);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
renderer.RenderUniform1f("uAlpha", state.alpha);
|
||||
renderer.RenderUniform1f("uAlpha", presentation.alpha);
|
||||
glBindTexture(GL_TEXTURE_2D, loadedObject.texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(loadedObject.mesh);
|
||||
renderer.PopMatrix();
|
||||
@@ -120,4 +187,23 @@ namespace FRG {
|
||||
renderer.RenderUniform1f("uAlpha", 1.0f);
|
||||
}
|
||||
|
||||
void InteractiveObject::drawShadowDepth(Renderer& renderer) const
|
||||
{
|
||||
if (!state.isActive) return;
|
||||
const PresentationSample presentation = interpolatedPresentationState();
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix(presentation.position);
|
||||
if (presentation.rotationY != 0.f) {
|
||||
renderer.TranslateMatrix(state.pivot);
|
||||
renderer.RotateMatrix(Eigen::AngleAxisf(
|
||||
presentation.rotationY, Eigen::Vector3f::UnitY()).toRotationMatrix());
|
||||
renderer.TranslateMatrix(-state.pivot);
|
||||
}
|
||||
if (presentation.scale != 1.f)
|
||||
renderer.ScaleMatrix(presentation.scale);
|
||||
renderer.DrawVertexRenderStruct(loadedObject.mesh);
|
||||
renderer.PopMatrix();
|
||||
}
|
||||
|
||||
} // namespace FRG
|
||||
Reference in new issue
Block a user