mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 17:43:52 +00:00
rendering: fix WMO portal culling and chat message format
- wmo_renderer: pass character position (not camera position) to portal visibility traversal — the 3rd-person camera can orbit outside a WMO while the character is inside, causing interior groups to cull; render() now accepts optional viewerPos that defaults to camPos for compatibility - renderer: pass &characterPosition to wmoRenderer->render() at both main and single-threaded call sites; reflection pass keeps camPos - renderer: apply mount pitch/roll to rider during all flight, not just taxiFlight_ (fixes zero rider tilt during player-controlled flying) - game_screen: format SAY/YELL/WHISPER/EMOTE using WoW-style "Name says:" instead of "[SAY] Name:" bracket prefix
This commit is contained in:
parent
920d6ac120
commit
60ebb565bb
4 changed files with 21 additions and 11 deletions
|
|
@ -150,7 +150,8 @@ public:
|
||||||
*/
|
*/
|
||||||
/** Pre-update mutable state (frame ID, material UBOs) on main thread before parallel render. */
|
/** Pre-update mutable state (frame ID, material UBOs) on main thread before parallel render. */
|
||||||
void prepareRender();
|
void prepareRender();
|
||||||
void render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera);
|
void render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera,
|
||||||
|
const glm::vec3* viewerPos = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize shadow pipeline (Phase 7)
|
* Initialize shadow pipeline (Phase 7)
|
||||||
|
|
|
||||||
|
|
@ -2096,8 +2096,8 @@ void Renderer::updateCharacterAnimation() {
|
||||||
// Rider uses character facing yaw, not mount bone rotation
|
// Rider uses character facing yaw, not mount bone rotation
|
||||||
// (rider faces character direction, seat bone only provides position)
|
// (rider faces character direction, seat bone only provides position)
|
||||||
float yawRad = glm::radians(characterYaw);
|
float yawRad = glm::radians(characterYaw);
|
||||||
float riderPitch = taxiFlight_ ? mountPitch_ * 0.35f : 0.0f;
|
float riderPitch = mountPitch_ * 0.35f;
|
||||||
float riderRoll = taxiFlight_ ? mountRoll_ * 0.35f : 0.0f;
|
float riderRoll = mountRoll_ * 0.35f;
|
||||||
characterRenderer->setInstanceRotation(characterInstanceId, glm::vec3(riderPitch, riderRoll, yawRad));
|
characterRenderer->setInstanceRotation(characterInstanceId, glm::vec3(riderPitch, riderRoll, yawRad));
|
||||||
} else {
|
} else {
|
||||||
// Fallback to old manual positioning if attachment not found
|
// Fallback to old manual positioning if attachment not found
|
||||||
|
|
@ -4737,7 +4737,7 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
||||||
auto t0 = std::chrono::steady_clock::now();
|
auto t0 = std::chrono::steady_clock::now();
|
||||||
VkCommandBuffer cmd = beginSecondary(SEC_WMO);
|
VkCommandBuffer cmd = beginSecondary(SEC_WMO);
|
||||||
setSecondaryViewportScissor(cmd);
|
setSecondaryViewportScissor(cmd);
|
||||||
wmoRenderer->render(cmd, perFrameSet, *camera);
|
wmoRenderer->render(cmd, perFrameSet, *camera, &characterPosition);
|
||||||
vkEndCommandBuffer(cmd);
|
vkEndCommandBuffer(cmd);
|
||||||
return std::chrono::duration<double, std::milli>(
|
return std::chrono::duration<double, std::milli>(
|
||||||
std::chrono::steady_clock::now() - t0).count();
|
std::chrono::steady_clock::now() - t0).count();
|
||||||
|
|
@ -4905,7 +4905,7 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
||||||
if (wmoRenderer && camera && !skipWMO) {
|
if (wmoRenderer && camera && !skipWMO) {
|
||||||
wmoRenderer->prepareRender();
|
wmoRenderer->prepareRender();
|
||||||
auto wmoStart = std::chrono::steady_clock::now();
|
auto wmoStart = std::chrono::steady_clock::now();
|
||||||
wmoRenderer->render(currentCmd, perFrameSet, *camera);
|
wmoRenderer->render(currentCmd, perFrameSet, *camera, &characterPosition);
|
||||||
lastWMORenderMs = std::chrono::duration<double, std::milli>(
|
lastWMORenderMs = std::chrono::duration<double, std::milli>(
|
||||||
std::chrono::steady_clock::now() - wmoStart).count();
|
std::chrono::steady_clock::now() - wmoStart).count();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1356,7 +1356,8 @@ void WMORenderer::prepareRender() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera) {
|
void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera,
|
||||||
|
const glm::vec3* viewerPos) {
|
||||||
if (!opaquePipeline_ || instances.empty()) {
|
if (!opaquePipeline_ || instances.empty()) {
|
||||||
lastDrawCalls = 0;
|
lastDrawCalls = 0;
|
||||||
return;
|
return;
|
||||||
|
|
@ -1380,6 +1381,11 @@ void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 camPos = camera.getPosition();
|
glm::vec3 camPos = camera.getPosition();
|
||||||
|
// For portal culling, use the character/player position when available.
|
||||||
|
// The 3rd-person camera can orbit outside a WMO while the character is inside,
|
||||||
|
// causing the portal traversal to start from outside and cull interior groups.
|
||||||
|
// Passing the actual character position as the viewer fixes this.
|
||||||
|
glm::vec3 portalViewerPos = viewerPos ? *viewerPos : camPos;
|
||||||
bool doPortalCull = portalCulling;
|
bool doPortalCull = portalCulling;
|
||||||
bool doDistanceCull = distanceCulling;
|
bool doDistanceCull = distanceCulling;
|
||||||
|
|
||||||
|
|
@ -1400,7 +1406,7 @@ void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
||||||
bool usePortalCulling = doPortalCull && !model.portals.empty() && !model.portalRefs.empty();
|
bool usePortalCulling = doPortalCull && !model.portals.empty() && !model.portalRefs.empty();
|
||||||
if (usePortalCulling) {
|
if (usePortalCulling) {
|
||||||
std::unordered_set<uint32_t> pvgSet;
|
std::unordered_set<uint32_t> pvgSet;
|
||||||
glm::vec4 localCamPos = instance.invModelMatrix * glm::vec4(camPos, 1.0f);
|
glm::vec4 localCamPos = instance.invModelMatrix * glm::vec4(portalViewerPos, 1.0f);
|
||||||
getVisibleGroupsViaPortals(model, glm::vec3(localCamPos), frustum,
|
getVisibleGroupsViaPortals(model, glm::vec3(localCamPos), frustum,
|
||||||
instance.modelMatrix, pvgSet);
|
instance.modelMatrix, pvgSet);
|
||||||
portalVisibleGroups.assign(pvgSet.begin(), pvgSet.end());
|
portalVisibleGroups.assign(pvgSet.begin(), pvgSet.end());
|
||||||
|
|
|
||||||
|
|
@ -1203,16 +1203,19 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
} else if (msg.type == game::ChatType::TEXT_EMOTE) {
|
} else if (msg.type == game::ChatType::TEXT_EMOTE) {
|
||||||
renderTextWithLinks(tsPrefix + processedMessage, color);
|
renderTextWithLinks(tsPrefix + processedMessage, color);
|
||||||
} else if (!msg.senderName.empty()) {
|
} else if (!msg.senderName.empty()) {
|
||||||
if (msg.type == game::ChatType::MONSTER_SAY || msg.type == game::ChatType::MONSTER_PARTY) {
|
if (msg.type == game::ChatType::SAY ||
|
||||||
|
msg.type == game::ChatType::MONSTER_SAY || msg.type == game::ChatType::MONSTER_PARTY) {
|
||||||
std::string fullMsg = tsPrefix + msg.senderName + " says: " + processedMessage;
|
std::string fullMsg = tsPrefix + msg.senderName + " says: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::MONSTER_YELL) {
|
} else if (msg.type == game::ChatType::YELL || msg.type == game::ChatType::MONSTER_YELL) {
|
||||||
std::string fullMsg = tsPrefix + msg.senderName + " yells: " + processedMessage;
|
std::string fullMsg = tsPrefix + msg.senderName + " yells: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::MONSTER_WHISPER || msg.type == game::ChatType::RAID_BOSS_WHISPER) {
|
} else if (msg.type == game::ChatType::WHISPER ||
|
||||||
|
msg.type == game::ChatType::MONSTER_WHISPER || msg.type == game::ChatType::RAID_BOSS_WHISPER) {
|
||||||
std::string fullMsg = tsPrefix + msg.senderName + " whispers: " + processedMessage;
|
std::string fullMsg = tsPrefix + msg.senderName + " whispers: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::MONSTER_EMOTE || msg.type == game::ChatType::RAID_BOSS_EMOTE) {
|
} else if (msg.type == game::ChatType::EMOTE ||
|
||||||
|
msg.type == game::ChatType::MONSTER_EMOTE || msg.type == game::ChatType::RAID_BOSS_EMOTE) {
|
||||||
std::string fullMsg = tsPrefix + msg.senderName + " " + processedMessage;
|
std::string fullMsg = tsPrefix + msg.senderName + " " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::CHANNEL && !msg.channelName.empty()) {
|
} else if (msg.type == game::ChatType::CHANNEL && !msg.channelName.empty()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue