Merge branch 'escape001' of gitea.fishrungames.com:salmon-engine-projects/space-game001 into escape001
This commit is contained in:
commit
e4bcf62afa
19
resources/config2/navigation3.json
Normal file
19
resources/config2/navigation3.json
Normal 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]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@ -264,11 +264,17 @@ namespace ZL
|
|||||||
menuManager.getState() == GameState::HelpScreen ||
|
menuManager.getState() == GameState::HelpScreen ||
|
||||||
menuManager.getState() == GameState::AboutMenu)
|
menuManager.getState() == GameState::AboutMenu)
|
||||||
{
|
{
|
||||||
|
// Normal UI: show cursor and release grab / relative mode
|
||||||
SDL_ShowCursor(SDL_ENABLE);
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_FALSE);
|
||||||
}
|
}
|
||||||
else if (menuManager.getState() == GameState::Gameplay)
|
else if (menuManager.getState() == GameState::Gameplay)
|
||||||
{
|
{
|
||||||
|
// Gameplay: hide cursor and enable relative mouse mode + window grab
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
|
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menuManager.getState() != GameState::Gameplay)
|
if (menuManager.getState() != GameState::Gameplay)
|
||||||
@ -428,13 +434,16 @@ namespace ZL
|
|||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
||||||
if (menuManager.getState() == GameState::Gameplay) {
|
if (menuManager.getState() == GameState::Gameplay) {
|
||||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
|
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_TRUE);
|
||||||
} else {
|
} else {
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_FALSE);
|
||||||
}
|
}
|
||||||
//SDL_SetRelativeMouseMode(SDL_TRUE);
|
//SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
}
|
}
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
if (Environment::window) SDL_SetWindowGrab(Environment::window, SDL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
|
|||||||
134
src/Location.cpp
134
src/Location.cpp
@ -12,7 +12,19 @@
|
|||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include "GameConstants.h"
|
#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
|
namespace ZL
|
||||||
{
|
{
|
||||||
@ -276,6 +288,9 @@ void Location::setup()
|
|||||||
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
||||||
dialogueSystem.loadDatabase("resources/dialogue/sample_dialogues.json");
|
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;
|
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);
|
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
||||||
renderer.PushMatrix();
|
renderer.PushMatrix();
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
/*renderer.LoadIdentity();
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
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(cameraInclination, Eigen::Vector3f::UnitX())).toRotationMatrix());
|
||||||
@ -588,6 +603,36 @@ void Location::setup()
|
|||||||
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
|
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
|
||||||
renderer.TranslateMatrix({ 0, -1.3f, 0 });
|
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 i = -7; i <= 7; i++)
|
||||||
{
|
{
|
||||||
for (int j = -7; j <= 7; j++)
|
for (int j = -7; j <= 7; j++)
|
||||||
@ -680,7 +725,8 @@ void Location::setup()
|
|||||||
|
|
||||||
drawNpcCar();
|
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)
|
if (girlfriend && !girlfriendInCar && girlfriendRescued)
|
||||||
{
|
{
|
||||||
@ -709,10 +755,19 @@ void Location::setup()
|
|||||||
//drawDebugForbidden();
|
//drawDebugForbidden();
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
renderer.PopMatrix();
|
// renderer.PopMatrix();
|
||||||
|
|
||||||
|
// renderer.PopProjectionMatrix();
|
||||||
|
|
||||||
|
// renderer.shaderManager.PopShader();
|
||||||
|
|
||||||
|
// Восстанавливаем стек матриц
|
||||||
|
if (firstPersonMode && !inCar && player) {
|
||||||
|
renderer.PopMatrix(); // убираем (2) – матрицу первого лица
|
||||||
|
}
|
||||||
|
renderer.PopMatrix(); // убираем (1) – исходную матрицу
|
||||||
|
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
renderer.shaderManager.PopShader();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -781,7 +836,8 @@ void Location::setup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw characters (they handle their own skinning shader switch internally)
|
// 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)
|
if (girlfriend && !girlfriendInCar)
|
||||||
{
|
{
|
||||||
@ -835,13 +891,39 @@ void Location::setup()
|
|||||||
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
||||||
renderer.PushMatrix();
|
renderer.PushMatrix();
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
/*renderer.LoadIdentity();
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
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(cameraInclination, Eigen::Vector3f::UnitX())).toRotationMatrix());
|
||||||
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraAzimuth, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(cameraAzimuth, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||||
const Eigen::Vector3f& camTarget = player ? player->position : Eigen::Vector3f::Zero();
|
const Eigen::Vector3f& camTarget = player ? player->position : Eigen::Vector3f::Zero();
|
||||||
renderer.TranslateMatrix({ -camTarget.x(), -camTarget.y(), -camTarget.z() });
|
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
|
// Capture the camera view matrix and compute uLightFromCamera
|
||||||
cameraViewMatrix = renderer.GetCurrentModelViewMatrix();
|
cameraViewMatrix = renderer.GetCurrentModelViewMatrix();
|
||||||
@ -887,7 +969,8 @@ void Location::setup()
|
|||||||
// Characters use their own shadow-aware shaders
|
// Characters use their own shadow-aware shaders
|
||||||
CheckGlError(__FILE__, __LINE__);
|
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__);
|
CheckGlError(__FILE__, __LINE__);
|
||||||
|
|
||||||
for (auto& npc : npcs) npc->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
|
for (auto& npc : npcs) npc->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
|
||||||
@ -897,7 +980,16 @@ void Location::setup()
|
|||||||
drawDebugNavigation();
|
drawDebugNavigation();
|
||||||
drawDebugForbidden();
|
drawDebugForbidden();
|
||||||
|
|
||||||
renderer.PopMatrix();
|
// renderer.PopMatrix();
|
||||||
|
// renderer.PopProjectionMatrix();
|
||||||
|
// renderer.shaderManager.PopShader();
|
||||||
|
|
||||||
|
// Восстанавливаем стек
|
||||||
|
if (firstPersonMode && !inCar && player) {
|
||||||
|
renderer.PopMatrix(); // убираем (2)
|
||||||
|
}
|
||||||
|
renderer.PopMatrix(); // убираем (1)
|
||||||
|
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
renderer.shaderManager.PopShader();
|
renderer.shaderManager.PopShader();
|
||||||
}
|
}
|
||||||
@ -1075,6 +1167,30 @@ void Location::setup()
|
|||||||
const float maxHeightForHide = 3.0f;
|
const float maxHeightForHide = 3.0f;
|
||||||
azsRoofVisible = !(insideAnyZone && player->position.y() < maxHeightForHide);
|
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)
|
if (girlfriend)
|
||||||
|
|||||||
@ -219,6 +219,13 @@ namespace ZL
|
|||||||
bool isPointInCarFootprint(const Eigen::Vector3f& point, const Eigen::Vector3f& center, float rotation) const;
|
bool isPointInCarFootprint(const Eigen::Vector3f& point, const Eigen::Vector3f& center, float rotation) const;
|
||||||
bool doesPlayerCarCollideWithNpcCar(const Eigen::Vector3f& center, float rotation) const;
|
bool doesPlayerCarCollideWithNpcCar(const Eigen::Vector3f& center, float rotation) const;
|
||||||
void pushOutOfNpcCarFootprint(Eigen::Vector3f& position) 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
|
} // namespace ZL
|
||||||
Loading…
Reference in New Issue
Block a user