Merge branch 'escape001' of gitea.fishrungames.com:salmon-engine-projects/space-game001 into escape001

This commit is contained in:
Vladislav Khorev 2026-04-19 18:46:23 +03:00
commit e4bcf62afa
4 changed files with 160 additions and 9 deletions

View File

@ -0,0 +1,19 @@
{
"cellSize": 0.4,
"agentRadius": 0.45,
"floorY": 0.0,
"objectPadding": 0.25,
"areas": [
{
"name": "main_corridor",
"available": true,
"polygon": [
[26, 9.5],
[14, 9.5],
[14, -8.7],
[26, -8.7]
]
}
]
}

View File

@ -264,11 +264,17 @@ namespace ZL
menuManager.getState() == GameState::HelpScreen ||
menuManager.getState() == GameState::AboutMenu)
{
// Normal UI: show cursor and release grab / relative mode
SDL_ShowCursor(SDL_ENABLE);
SDL_SetRelativeMouseMode(SDL_FALSE);
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_FALSE);
}
else if (menuManager.getState() == GameState::Gameplay)
{
// Gameplay: hide cursor and enable relative mouse mode + window grab
SDL_ShowCursor(SDL_DISABLE);
SDL_SetRelativeMouseMode(SDL_TRUE);
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_TRUE);
}
if (menuManager.getState() != GameState::Gameplay)
@ -428,13 +434,16 @@ namespace ZL
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
if (menuManager.getState() == GameState::Gameplay) {
SDL_SetRelativeMouseMode(SDL_TRUE);
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_TRUE);
} else {
SDL_SetRelativeMouseMode(SDL_FALSE);
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_FALSE);
}
//SDL_SetRelativeMouseMode(SDL_TRUE);
}
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
SDL_SetRelativeMouseMode(SDL_FALSE);
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_FALSE);
}
#ifdef __ANDROID__

View File

@ -12,7 +12,19 @@
#include <cfloat>
#include "GameConstants.h"
namespace {
Eigen::Matrix4f lookAt(const Eigen::Vector3f& eye, const Eigen::Vector3f& target, const Eigen::Vector3f& up) {
Eigen::Vector3f f = (target - eye).normalized();
Eigen::Vector3f s = f.cross(up).normalized();
Eigen::Vector3f u = s.cross(f);
Eigen::Matrix4f result;
result << s.x(), s.y(), s.z(), -s.dot(eye),
u.x(), u.y(), u.z(), -u.dot(eye),
-f.x(), -f.y(), -f.z(), f.dot(eye),
0, 0, 0, 1;
return result;
}
}
namespace ZL
{
@ -276,6 +288,9 @@ void Location::setup()
dialogueSystem.init(renderer, CONST_ZIP_FILE);
dialogueSystem.loadDatabase("resources/dialogue/sample_dialogues.json");
buildingFirstPersonZone = Eigen::AlignedBox<float, 2>(Eigen::Vector2f(14.0f, -8.7f), Eigen::Vector2f(26.0f, 9.5f));
firstPersonMode = false;
std::cout << "[BARK] Setup complete, loaded " << gameObjects.size() << " models" << std::endl;
}
@ -579,7 +594,7 @@ void Location::setup()
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
renderer.PushMatrix();
renderer.LoadIdentity();
/*renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraInclination, Eigen::Vector3f::UnitX())).toRotationMatrix());
@ -588,6 +603,36 @@ void Location::setup()
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
renderer.TranslateMatrix({ 0, -1.3f, 0 });
*/
if (firstPersonMode && !inCar && player) {
const float eyeHeight = 1.6f;
Eigen::Vector3f eye = player->position + Eigen::Vector3f(0.0f, eyeHeight, 0.0f);
float yaw = cameraAzimuth;
float pitch = cameraInclination;
Eigen::Vector3f forward(std::sin(yaw), 0.0f, -std::cos(yaw));
Eigen::Vector3f direction = Eigen::Quaternionf(Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitX())) * forward;
direction.normalize();
Eigen::Vector3f target = eye + direction;
Eigen::Vector3f up(0.0f, 1.0f, 0.0f);
Eigen::Matrix4f view = lookAt(eye, target, up);
renderer.PushSpecialMatrix(view); // (2) добавляем матрицу первого лица в стек
}
else {
// Стандартная камера от третьего лица (без дополнительного Push)
renderer.LoadIdentity();
renderer.TranslateMatrix({ 0, 0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraInclination, Eigen::Vector3f::UnitX())).toRotationMatrix());
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraAzimuth, Eigen::Vector3f::UnitY())).toRotationMatrix());
Eigen::Vector3f camTarget = inCar ? carPosition : (player ? player->position : Eigen::Vector3f::Zero());
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
const float cameraYOffset = firstPersonMode ? -0.2f : -1.3f;
renderer.TranslateMatrix({ 0, cameraYOffset, 0 });
}
for (int i = -7; i <= 7; i++)
{
for (int j = -7; j <= 7; j++)
@ -680,7 +725,8 @@ void Location::setup()
drawNpcCar();
if (player && !inCar) player->draw(renderer);
// Don't draw the player mesh when in first-person mode
if (player && !inCar && !firstPersonMode) player->draw(renderer);
if (girlfriend && !girlfriendInCar && girlfriendRescued)
{
@ -709,10 +755,19 @@ void Location::setup()
//drawDebugForbidden();
//#endif
renderer.PopMatrix();
// renderer.PopMatrix();
// renderer.PopProjectionMatrix();
// renderer.shaderManager.PopShader();
// Восстанавливаем стек матриц
if (firstPersonMode && !inCar && player) {
renderer.PopMatrix(); // убираем (2) матрицу первого лица
}
renderer.PopMatrix(); // убираем (1) исходную матрицу
renderer.PopProjectionMatrix();
renderer.shaderManager.PopShader();
}
@ -781,7 +836,8 @@ void Location::setup()
}
// Draw characters (they handle their own skinning shader switch internally)
if (player) player->drawShadowDepth(renderer);
// Draw player shadow depth only if not in first-person (so depth won't be duplicated)
if (player && !firstPersonMode) player->drawShadowDepth(renderer);
if (girlfriend && !girlfriendInCar)
{
@ -835,13 +891,39 @@ void Location::setup()
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
renderer.PushMatrix();
renderer.LoadIdentity();
/*renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraInclination, Eigen::Vector3f::UnitX())).toRotationMatrix());
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraAzimuth, Eigen::Vector3f::UnitY())).toRotationMatrix());
const Eigen::Vector3f& camTarget = player ? player->position : Eigen::Vector3f::Zero();
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
*/
if (firstPersonMode && !inCar && player) {
const float eyeHeight = 1.6f;
Eigen::Vector3f eye = player->position + Eigen::Vector3f(0.0f, eyeHeight, 0.0f);
float yaw = cameraAzimuth;
float pitch = cameraInclination;
Eigen::Vector3f forward(std::sin(yaw), 0.0f, -std::cos(yaw));
Eigen::Vector3f direction = Eigen::Quaternionf(Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitX())) * forward;
direction.normalize();
Eigen::Vector3f target = eye + direction;
Eigen::Vector3f up(0.0f, 1.0f, 0.0f);
Eigen::Matrix4f view = lookAt(eye, target, up);
renderer.PushSpecialMatrix(view); // (2)
}
else {
// стандартная камера третьего лица
renderer.LoadIdentity();
renderer.TranslateMatrix({ 0, 0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraInclination, Eigen::Vector3f::UnitX())).toRotationMatrix());
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraAzimuth, Eigen::Vector3f::UnitY())).toRotationMatrix());
Eigen::Vector3f camTarget = inCar ? carPosition : (player ? player->position : Eigen::Vector3f::Zero());
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
const float cameraYOffset = firstPersonMode ? -0.2f : -1.3f;
renderer.TranslateMatrix({ 0, cameraYOffset, 0 });
}
// Capture the camera view matrix and compute uLightFromCamera
cameraViewMatrix = renderer.GetCurrentModelViewMatrix();
@ -887,7 +969,8 @@ void Location::setup()
// Characters use their own shadow-aware shaders
CheckGlError(__FILE__, __LINE__);
if (player) player->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
// don't draw player with shadow shader if in first-person mode
if (player && !firstPersonMode) player->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
CheckGlError(__FILE__, __LINE__);
for (auto& npc : npcs) npc->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
@ -897,7 +980,16 @@ void Location::setup()
drawDebugNavigation();
drawDebugForbidden();
renderer.PopMatrix();
// renderer.PopMatrix();
// renderer.PopProjectionMatrix();
// renderer.shaderManager.PopShader();
// Восстанавливаем стек
if (firstPersonMode && !inCar && player) {
renderer.PopMatrix(); // убираем (2)
}
renderer.PopMatrix(); // убираем (1)
renderer.PopProjectionMatrix();
renderer.shaderManager.PopShader();
}
@ -1075,6 +1167,30 @@ void Location::setup()
const float maxHeightForHide = 3.0f;
azsRoofVisible = !(insideAnyZone && player->position.y() < maxHeightForHide);
}
// --- first-person building zone detection ---
{
const Eigen::Vector2f p2d(player->position.x(), player->position.z());
const bool insideBuilding = buildingFirstPersonZone.contains(p2d);
if (insideBuilding && !firstPersonMode) {
// Enter first-person
firstPersonMode = true;
savedCameraAzimuth = cameraAzimuth;
savedCameraInclination = cameraInclination;
// Align camera to player's facing so feel like first-person
cameraAzimuth = player->targetFacingAngle;
// a moderate inclination (slightly downwards)
cameraInclination = M_PI * 20.f / 180.f;
std::cout << "[FIRSTPERSON] Entered building zone, switching to first-person view" << std::endl;
} else if (!insideBuilding && firstPersonMode) {
// Exit first-person: restore camera
firstPersonMode = false;
cameraAzimuth = savedCameraAzimuth;
cameraInclination = savedCameraInclination;
std::cout << "[FIRSTPERSON] Exited building zone, restoring camera and third-person view" << std::endl;
}
}
// --- end first-person detection ---
}
if (girlfriend)

View File

@ -219,6 +219,13 @@ namespace ZL
bool isPointInCarFootprint(const Eigen::Vector3f& point, const Eigen::Vector3f& center, float rotation) const;
bool doesPlayerCarCollideWithNpcCar(const Eigen::Vector3f& center, float rotation) const;
void pushOutOfNpcCarFootprint(Eigen::Vector3f& position) const;
// --- FIRST PERSON BUILDING ZONE ---
bool firstPersonMode = false;
Eigen::AlignedBox<float, 2> buildingFirstPersonZone; // X,Z min/max
float savedCameraAzimuth = 0.f;
float savedCameraInclination = 0.f;
// -----------------------------------
};
} // namespace ZL