Somehow planet is working

This commit is contained in:
Vladislav Khorev 2025-12-13 20:11:48 +03:00
parent fe361885c0
commit 4afb9d6f4f
7 changed files with 113 additions and 13 deletions

View File

@ -36,4 +36,8 @@ Vector3f Environment::shipPosition = {0,0,0};
float Environment::shipVelocity = 0.f;
const float Environment::CONST_Z_NEAR = 10.f;
const float Environment::CONST_Z_FAR = 10000.f;
} // namespace ZL

View File

@ -37,6 +37,10 @@ public:
static Vector3f shipPosition;
static float shipVelocity;
static const float CONST_Z_NEAR;
static const float CONST_Z_FAR;
};

View File

@ -280,7 +280,7 @@ namespace ZL
renderer.EnableVertexAttribArray(vPositionName);
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
1, 1000);
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
renderer.PushMatrix();
renderer.LoadIdentity();
renderer.RotateMatrix(Environment::inverseShipMatrix);
@ -316,7 +316,7 @@ namespace ZL
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
1, 1000);
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
renderer.PushMatrix();
renderer.LoadIdentity();
@ -351,7 +351,7 @@ namespace ZL
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
1, 1000);
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
for (int i = 0; i < boxCoordsArr.size(); i++)
{
@ -612,11 +612,11 @@ namespace ZL
{
if (event.key.keysym.sym == SDLK_i)
{
Environment::shipVelocity += 5.f;
Environment::shipVelocity += 5000.f;
}
if (event.key.keysym.sym == SDLK_k)
{
Environment::shipVelocity -= 5.f;
Environment::shipVelocity -= 5000.f;
}
}
}

View File

@ -6,6 +6,85 @@
namespace ZL {
static constexpr float PLANET_RADIUS = 1000000.f;
static Vector3f PLANET_CENTER_OFFSET = Vector3f{ 0.f, 0.f, -2250000.f };
// --- 1. Дальний диапазон (FAR) ---
static constexpr float FAR_Z_NEAR = 50000.0f;
static constexpr float FAR_Z_FAR = 10000000.0f;
// Дистанция, где НАЧИНАЕТСЯ переход FAR -> MIDDLE
static constexpr float TRANSITION_FAR_START = 400000.0f;
// --- 2. Средний диапазон (MIDDLE) ---
static constexpr float MIDDLE_Z_NEAR = 500.f;
static constexpr float MIDDLE_Z_FAR = 50000.f;
// Дистанция, где ЗАВЕРШАЕТСЯ переход FAR -> MIDDLE и НАЧИНАЕТСЯ MIDDLE -> NEAR
static constexpr float TRANSITION_MIDDLE_START = 10000.f;
// --- 3. Ближний диапазон (NEAR) ---
// Новые константы для максимальной точности
static constexpr float NEAR_Z_NEAR = 50.0f;
static constexpr float NEAR_Z_FAR = 50000.0f;
// Дистанция, где ЗАВЕРШАЕТСЯ переход MIDDLE -> NEAR
static constexpr float TRANSITION_NEAR_END = 10.f;
std::pair<float, float> calculateZRange(const Vector3f& shipPosition) {
// 1. Вычисление расстояния до поверхности планеты
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
const float distanceToPlanetCenter = (planetWorldPosition - shipPosition).length();
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
std::cout << "distanceToPlanetSurface " << distanceToPlanetSurface << std::endl;
float currentZNear;
float currentZFar;
float alpha; // Коэффициент интерполяции для текущего сегмента
// Диапазон I: Далеко (FAR) -> Средне (MIDDLE)
if (distanceToPlanetSurface >= TRANSITION_FAR_START) {
// Полностью дальний диапазон
currentZNear = FAR_Z_NEAR;
currentZFar = FAR_Z_FAR;
}
else if (distanceToPlanetSurface > TRANSITION_MIDDLE_START) {
// Плавный переход от FAR к MIDDLE
const float transitionLength = TRANSITION_FAR_START - TRANSITION_MIDDLE_START;
// Нормализация расстояния, 0 при TRANSITION_FAR_START (Далеко), 1 при TRANSITION_MIDDLE_START (Близко)
float normalizedDist = (distanceToPlanetSurface - TRANSITION_MIDDLE_START) / transitionLength;
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
// Интерполяция: FAR * (1-alpha) + MIDDLE * alpha
currentZNear = FAR_Z_NEAR * (1.0f - alpha) + MIDDLE_Z_NEAR * alpha;
currentZFar = FAR_Z_FAR * (1.0f - alpha) + MIDDLE_Z_FAR * alpha;
// Диапазон II: Средне (MIDDLE) -> Близко (NEAR)
}
else if (distanceToPlanetSurface > TRANSITION_NEAR_END) {
// Плавный переход от MIDDLE к NEAR
const float transitionLength = TRANSITION_MIDDLE_START - TRANSITION_NEAR_END;
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
float normalizedDist = (distanceToPlanetSurface - TRANSITION_NEAR_END) / transitionLength;
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
currentZNear = MIDDLE_Z_NEAR * (1.0f - alpha) + NEAR_Z_NEAR * alpha;
currentZFar = MIDDLE_Z_FAR * (1.0f - alpha) + NEAR_Z_FAR * alpha;
}
else {
// Полностью ближний диапазон (distanceToPlanetSurface <= TRANSITION_NEAR_END)
currentZNear = NEAR_Z_NEAR;
currentZFar = NEAR_Z_FAR;
}
return { currentZNear, currentZFar };
}
PerlinNoise::PerlinNoise() {
p.resize(256);
@ -64,11 +143,11 @@ namespace ZL {
float noiseValue = noise(pos.v[0] * frequency, pos.v[1] * frequency, pos.v[2] * frequency);
// Переводим из диапазона [-1, 1] в [0, 1]
noiseValue = (noiseValue + 1.0f) * 0.5f;
//noiseValue = (noiseValue + 1.0f) * 0.5f;
// Масштабируем: хотим отклонение от 1.0 до 1.1
// Значит амплитуда = 0.1
float height = 1.0f + (noiseValue * 0.1f); // * 0.2 даст вариацию высоты
float height = 1.0f + (noiseValue * 0.002f); // * 0.2 даст вариацию высоты
return height;
}
@ -85,10 +164,10 @@ namespace ZL {
void PlanetObject::init() {
planetMesh = generateSphere(7);
planetMesh = generateSphere(8);
planetMesh.Scale(300.f);
planetMesh.Move({ 0,0,-600 });
planetMesh.Scale(PLANET_RADIUS);
planetMesh.Move(PLANET_CENTER_OFFSET);
planetRenderStruct.data = planetMesh;
planetRenderStruct.RefreshVBO();
@ -123,9 +202,16 @@ namespace ZL {
renderer.EnableVertexAttribArray(vNormalName);
renderer.EnableVertexAttribArray(vTexCoordName);
//renderer.EnableVertexAttribArray(vTexCoord3Name);
const auto zRange = calculateZRange(Environment::shipPosition);
const float currentZNear = zRange.first;
const float currentZFar = zRange.second;
// 2. Применяем динамическую матрицу проекции
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
1, 1000);
currentZNear, currentZFar);
renderer.PushMatrix();
renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });

View File

@ -66,7 +66,6 @@ namespace ZL {
std::vector<Triangle> subdivideTriangles(const std::vector<Triangle>& inputTriangles);
Vector3f calculateSurfaceNormal(Vector3f p_sphere);
VertexDataStruct trianglesToVertices(const std::vector<Triangle>& triangles);
VertexDataStruct generateOctahedron();
VertexDataStruct generateSphere(int subdivisions);
};

View File

@ -2,6 +2,8 @@
#include <random>
#include <cmath>
#include "OpenGlExtensions.h"
#include "Environment.h"
namespace ZL {
@ -125,7 +127,7 @@ namespace ZL {
renderer.EnableVertexAttribArray(vTexCoordName);
float aspectRatio = static_cast<float>(screenWidth) / static_cast<float>(screenHeight);
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, aspectRatio, 1, 1000);
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, aspectRatio, Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
glBindTexture(GL_TEXTURE_2D, texture->getTexID());

View File

@ -56,6 +56,11 @@ namespace ZL {
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
}
float length() const
{
return sqrt(squaredNorm());
}
float dot(const Vector3f& other) const {
return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2];
}