camera in barn
This commit is contained in:
parent
c9324bd30b
commit
1a6410dc12
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]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -246,11 +246,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)
|
||||
@ -406,12 +412,15 @@ 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);
|
||||
}
|
||||
}
|
||||
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__
|
||||
|
||||
134
src/Location.cpp
134
src/Location.cpp
@ -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
|
||||
{
|
||||
@ -270,6 +282,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;
|
||||
}
|
||||
|
||||
@ -571,7 +586,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());
|
||||
@ -580,6 +595,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++)
|
||||
@ -661,7 +706,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)
|
||||
{
|
||||
@ -690,10 +736,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();
|
||||
|
||||
}
|
||||
@ -762,7 +817,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)
|
||||
{
|
||||
@ -816,13 +872,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();
|
||||
@ -868,7 +950,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);
|
||||
@ -878,7 +961,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();
|
||||
}
|
||||
@ -1056,6 +1148,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)
|
||||
|
||||
@ -203,6 +203,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
|
||||
Loading…
Reference in New Issue
Block a user