mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Suppress movement after teleport/portal, add shadow distance slider
- Add movementSuppressTimer to camera controller that forces all movement keys to read as false, preventing held W key from carrying through loading screens (fixes always-running-forward after instance portals) - Increase shadow frustum default from 60 to 72 units (+20%) - Make shadow distance configurable via setShadowDistance() (40-200 range) - Add shadow distance slider in Video settings tab (persisted to config)
This commit is contained in:
parent
e4d94e5d7c
commit
e001aaa2b6
7 changed files with 47 additions and 14 deletions
|
|
@ -97,6 +97,7 @@ public:
|
|||
void setExternalMoving(bool moving) { externalMoving_ = moving; }
|
||||
void setFacingYaw(float yaw) { facingYaw = yaw; } // For taxi/scripted movement
|
||||
void clearMovementInputs();
|
||||
void suppressMovementFor(float seconds) { movementSuppressTimer_ = seconds; }
|
||||
|
||||
// Trigger mount jump (applies vertical velocity for physics hop)
|
||||
void triggerMountJump();
|
||||
|
|
@ -211,6 +212,9 @@ private:
|
|||
static constexpr float SWIM_SINK_SPEED = -3.0f;
|
||||
static constexpr float WATER_SURFACE_OFFSET = 0.9f;
|
||||
|
||||
// Movement input suppression (after teleport/portal, ignore held keys)
|
||||
float movementSuppressTimer_ = 0.0f;
|
||||
|
||||
// State
|
||||
bool enabled = true;
|
||||
bool sitting = false;
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ private:
|
|||
glm::vec3 shadowCenter = glm::vec3(0.0f);
|
||||
bool shadowCenterInitialized = false;
|
||||
bool shadowsEnabled = true;
|
||||
float shadowDistance_ = 72.0f; // Shadow frustum half-extent (default: 72 units)
|
||||
uint32_t shadowFrameCounter_ = 0;
|
||||
|
||||
|
||||
|
|
@ -254,6 +255,8 @@ public:
|
|||
|
||||
void setShadowsEnabled(bool enabled) { shadowsEnabled = enabled; }
|
||||
bool areShadowsEnabled() const { return shadowsEnabled; }
|
||||
void setShadowDistance(float dist) { shadowDistance_ = glm::clamp(dist, 40.0f, 200.0f); }
|
||||
float getShadowDistance() const { return shadowDistance_; }
|
||||
void setMsaaSamples(VkSampleCountFlagBits samples);
|
||||
|
||||
void setWaterRefractionEnabled(bool enabled);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ private:
|
|||
bool pendingVsync = false;
|
||||
int pendingResIndex = 0;
|
||||
bool pendingShadows = true;
|
||||
float pendingShadowDistance = 72.0f;
|
||||
bool pendingWaterRefraction = false;
|
||||
int pendingMasterVolume = 100;
|
||||
int pendingMusicVolume = 30;
|
||||
|
|
|
|||
|
|
@ -1555,8 +1555,10 @@ void Application::setupUICallbacks() {
|
|||
taxiLandingClampTimer_ = 0.0f;
|
||||
lastTaxiFlight_ = false;
|
||||
// Stop any movement that was active before the teleport
|
||||
if (renderer->getCameraController())
|
||||
if (renderer->getCameraController()) {
|
||||
renderer->getCameraController()->clearMovementInputs();
|
||||
renderer->getCameraController()->suppressMovementFor(0.5f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1573,8 +1575,10 @@ void Application::setupUICallbacks() {
|
|||
taxiLandingClampTimer_ = 0.0f;
|
||||
lastTaxiFlight_ = false;
|
||||
// Stop any movement that was active before the teleport
|
||||
if (renderer && renderer->getCameraController())
|
||||
if (renderer && renderer->getCameraController()) {
|
||||
renderer->getCameraController()->clearMovementInputs();
|
||||
renderer->getCameraController()->suppressMovementFor(1.0f);
|
||||
}
|
||||
loadOnlineWorldTerrain(mapId, x, y, z);
|
||||
// loadedMapId_ is set inside loadOnlineWorldTerrain (including
|
||||
// any deferred entries it processes), so we must NOT override it here.
|
||||
|
|
|
|||
|
|
@ -200,16 +200,22 @@ void CameraController::update(float deltaTime) {
|
|||
// Don't process keyboard input when UI text input (e.g. chat box) has focus
|
||||
bool uiWantsKeyboard = ImGui::GetIO().WantTextInput;
|
||||
|
||||
// Suppress movement input after teleport/portal (keys may still be held)
|
||||
if (movementSuppressTimer_ > 0.0f) {
|
||||
movementSuppressTimer_ -= deltaTime;
|
||||
}
|
||||
bool movementSuppressed = movementSuppressTimer_ > 0.0f;
|
||||
|
||||
// Determine current key states
|
||||
bool keyW = !uiWantsKeyboard && !sitting && input.isKeyPressed(SDL_SCANCODE_W);
|
||||
bool keyS = !uiWantsKeyboard && !sitting && input.isKeyPressed(SDL_SCANCODE_S);
|
||||
bool keyA = !uiWantsKeyboard && !sitting && input.isKeyPressed(SDL_SCANCODE_A);
|
||||
bool keyD = !uiWantsKeyboard && !sitting && input.isKeyPressed(SDL_SCANCODE_D);
|
||||
bool keyQ = !uiWantsKeyboard && !sitting && input.isKeyPressed(SDL_SCANCODE_Q);
|
||||
bool keyE = !uiWantsKeyboard && !sitting && input.isKeyPressed(SDL_SCANCODE_E);
|
||||
bool keyW = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_W);
|
||||
bool keyS = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_S);
|
||||
bool keyA = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_A);
|
||||
bool keyD = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_D);
|
||||
bool keyQ = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_Q);
|
||||
bool keyE = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_E);
|
||||
bool shiftDown = !uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_LSHIFT) || input.isKeyPressed(SDL_SCANCODE_RSHIFT));
|
||||
bool ctrlDown = !uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_LCTRL) || input.isKeyPressed(SDL_SCANCODE_RCTRL));
|
||||
bool nowJump = !uiWantsKeyboard && !sitting && input.isKeyJustPressed(SDL_SCANCODE_SPACE);
|
||||
bool nowJump = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyJustPressed(SDL_SCANCODE_SPACE);
|
||||
|
||||
// Idle camera: any input resets the timer; timeout triggers a slow orbit pan
|
||||
bool anyInput = leftMouseDown || rightMouseDown || keyW || keyS || keyA || keyD || keyQ || keyE || nowJump;
|
||||
|
|
|
|||
|
|
@ -3766,10 +3766,10 @@ void Renderer::renderHUD() {
|
|||
// in createPerFrameResources() as part of the Vulkan shadow infrastructure.
|
||||
|
||||
glm::mat4 Renderer::computeLightSpaceMatrix() {
|
||||
constexpr float kShadowHalfExtent = 60.0f;
|
||||
constexpr float kShadowLightDistance = 200.0f;
|
||||
const float kShadowHalfExtent = shadowDistance_;
|
||||
const float kShadowLightDistance = shadowDistance_ * 3.0f;
|
||||
constexpr float kShadowNearPlane = 1.0f;
|
||||
constexpr float kShadowFarPlane = 450.0f;
|
||||
const float kShadowFarPlane = shadowDistance_ * 6.5f;
|
||||
|
||||
// Use active lighting direction so shadow projection matches main shading.
|
||||
// Fragment shaders derive lighting with `ldir = normalize(-lightDir.xyz)`,
|
||||
|
|
@ -3973,7 +3973,7 @@ void Renderer::renderShadowPass() {
|
|||
vkCmdSetScissor(currentCmd, 0, 1, &sc);
|
||||
|
||||
// Phase 7/8: render shadow casters
|
||||
const float shadowCullRadius = 80.0f;
|
||||
const float shadowCullRadius = shadowDistance_ * 1.35f;
|
||||
if (wmoRenderer) {
|
||||
wmoRenderer->renderShadow(currentCmd, lightSpaceMatrix, shadowCenter, shadowCullRadius);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6180,6 +6180,7 @@ void GameScreen::renderSettingsWindow() {
|
|||
pendingVsync = window->isVsyncEnabled();
|
||||
if (renderer) {
|
||||
renderer->setShadowsEnabled(pendingShadows);
|
||||
renderer->setShadowDistance(pendingShadowDistance);
|
||||
// Read non-volume settings from actual state (volumes come from saved settings)
|
||||
if (auto* cameraController = renderer->getCameraController()) {
|
||||
pendingMouseSensitivity = cameraController->getMouseSensitivity();
|
||||
|
|
@ -6246,6 +6247,14 @@ void GameScreen::renderSettingsWindow() {
|
|||
if (renderer) renderer->setShadowsEnabled(pendingShadows);
|
||||
saveSettings();
|
||||
}
|
||||
if (pendingShadows) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(150.0f);
|
||||
if (ImGui::SliderFloat("Distance##shadow", &pendingShadowDistance, 40.0f, 200.0f, "%.0f")) {
|
||||
if (renderer) renderer->setShadowDistance(pendingShadowDistance);
|
||||
saveSettings();
|
||||
}
|
||||
}
|
||||
if (ImGui::Checkbox("Water Refraction", &pendingWaterRefraction)) {
|
||||
if (renderer) renderer->setWaterRefractionEnabled(pendingWaterRefraction);
|
||||
saveSettings();
|
||||
|
|
@ -6339,6 +6348,7 @@ void GameScreen::renderSettingsWindow() {
|
|||
pendingFullscreen = kDefaultFullscreen;
|
||||
pendingVsync = kDefaultVsync;
|
||||
pendingShadows = kDefaultShadows;
|
||||
pendingShadowDistance = 72.0f;
|
||||
pendingGroundClutterDensity = kDefaultGroundClutterDensity;
|
||||
pendingAntiAliasing = 0;
|
||||
pendingNormalMapping = true;
|
||||
|
|
@ -6350,7 +6360,10 @@ void GameScreen::renderSettingsWindow() {
|
|||
window->setVsync(pendingVsync);
|
||||
window->applyResolution(kResolutions[pendingResIndex][0], kResolutions[pendingResIndex][1]);
|
||||
pendingWaterRefraction = false;
|
||||
if (renderer) renderer->setShadowsEnabled(pendingShadows);
|
||||
if (renderer) {
|
||||
renderer->setShadowsEnabled(pendingShadows);
|
||||
renderer->setShadowDistance(pendingShadowDistance);
|
||||
}
|
||||
if (renderer) renderer->setWaterRefractionEnabled(pendingWaterRefraction);
|
||||
if (renderer) renderer->setMsaaSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||
if (renderer) {
|
||||
|
|
@ -7364,6 +7377,7 @@ void GameScreen::saveSettings() {
|
|||
out << "auto_loot=" << (pendingAutoLoot ? 1 : 0) << "\n";
|
||||
out << "ground_clutter_density=" << pendingGroundClutterDensity << "\n";
|
||||
out << "shadows=" << (pendingShadows ? 1 : 0) << "\n";
|
||||
out << "shadow_distance=" << pendingShadowDistance << "\n";
|
||||
out << "water_refraction=" << (pendingWaterRefraction ? 1 : 0) << "\n";
|
||||
out << "antialiasing=" << pendingAntiAliasing << "\n";
|
||||
out << "normal_mapping=" << (pendingNormalMapping ? 1 : 0) << "\n";
|
||||
|
|
@ -7449,6 +7463,7 @@ void GameScreen::loadSettings() {
|
|||
else if (key == "auto_loot") pendingAutoLoot = (std::stoi(val) != 0);
|
||||
else if (key == "ground_clutter_density") pendingGroundClutterDensity = std::clamp(std::stoi(val), 0, 150);
|
||||
else if (key == "shadows") pendingShadows = (std::stoi(val) != 0);
|
||||
else if (key == "shadow_distance") pendingShadowDistance = std::clamp(std::stof(val), 40.0f, 200.0f);
|
||||
else if (key == "water_refraction") pendingWaterRefraction = (std::stoi(val) != 0);
|
||||
else if (key == "antialiasing") pendingAntiAliasing = std::clamp(std::stoi(val), 0, 3);
|
||||
else if (key == "normal_mapping") pendingNormalMapping = (std::stoi(val) != 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue