working
This commit is contained in:
parent
a91d7c04e8
commit
57ff27b0f6
117
PlanetObject.cpp
117
PlanetObject.cpp
@ -49,31 +49,29 @@ namespace ZL {
|
|||||||
return id1 < id2 ? id1 + "_" + id2 : id2 + "_" + id1;
|
return id1 < id2 ? id1 + "_" + id2 : id2 + "_" + id1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<float, float> calculateZRange(const Vector3f& shipPosition) {
|
std::pair<float, float> PlanetObject::calculateZRange(const Vector3f& shipPosition) {
|
||||||
|
|
||||||
// 1. Вычисление расстояния до поверхности планеты
|
// 1. Вычисление расстояния до поверхности планеты
|
||||||
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
const float dToPlanetSurface = distanceToPlanetSurface();
|
||||||
const float distanceToPlanetCenter = (planetWorldPosition - shipPosition).length();
|
std::cout << "distanceToPlanetSurface " << dToPlanetSurface << std::endl;
|
||||||
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
|
||||||
std::cout << "distanceToPlanetSurface " << distanceToPlanetSurface << std::endl;
|
|
||||||
|
|
||||||
float currentZNear;
|
float currentZNear;
|
||||||
float currentZFar;
|
float currentZFar;
|
||||||
float alpha; // Коэффициент интерполяции для текущего сегмента
|
float alpha; // Коэффициент интерполяции для текущего сегмента
|
||||||
|
|
||||||
// Диапазон I: Далеко (FAR) -> Средне (MIDDLE)
|
// Диапазон I: Далеко (FAR) -> Средне (MIDDLE)
|
||||||
if (distanceToPlanetSurface >= TRANSITION_FAR_START) {
|
if (dToPlanetSurface >= TRANSITION_FAR_START) {
|
||||||
// Полностью дальний диапазон
|
// Полностью дальний диапазон
|
||||||
currentZNear = FAR_Z_NEAR;
|
currentZNear = FAR_Z_NEAR;
|
||||||
currentZFar = FAR_Z_FAR;
|
currentZFar = FAR_Z_FAR;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (distanceToPlanetSurface > TRANSITION_MIDDLE_START) {
|
else if (dToPlanetSurface > TRANSITION_MIDDLE_START) {
|
||||||
// Плавный переход от FAR к MIDDLE
|
// Плавный переход от FAR к MIDDLE
|
||||||
const float transitionLength = TRANSITION_FAR_START - TRANSITION_MIDDLE_START;
|
const float transitionLength = TRANSITION_FAR_START - TRANSITION_MIDDLE_START;
|
||||||
|
|
||||||
// Нормализация расстояния, 0 при TRANSITION_FAR_START (Далеко), 1 при TRANSITION_MIDDLE_START (Близко)
|
// Нормализация расстояния, 0 при TRANSITION_FAR_START (Далеко), 1 при TRANSITION_MIDDLE_START (Близко)
|
||||||
float normalizedDist = (distanceToPlanetSurface - TRANSITION_MIDDLE_START) / transitionLength;
|
float normalizedDist = (dToPlanetSurface - TRANSITION_MIDDLE_START) / transitionLength;
|
||||||
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
||||||
|
|
||||||
// Интерполяция: FAR * (1-alpha) + MIDDLE * alpha
|
// Интерполяция: FAR * (1-alpha) + MIDDLE * alpha
|
||||||
@ -82,12 +80,12 @@ namespace ZL {
|
|||||||
|
|
||||||
// Диапазон II: Средне (MIDDLE) -> Близко (NEAR)
|
// Диапазон II: Средне (MIDDLE) -> Близко (NEAR)
|
||||||
}
|
}
|
||||||
else if (distanceToPlanetSurface > TRANSITION_NEAR_END) {
|
else if (dToPlanetSurface > TRANSITION_NEAR_END) {
|
||||||
// Плавный переход от MIDDLE к NEAR
|
// Плавный переход от MIDDLE к NEAR
|
||||||
const float transitionLength = TRANSITION_MIDDLE_START - TRANSITION_NEAR_END;
|
const float transitionLength = TRANSITION_MIDDLE_START - TRANSITION_NEAR_END;
|
||||||
|
|
||||||
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
|
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
|
||||||
float normalizedDist = (distanceToPlanetSurface - TRANSITION_NEAR_END) / transitionLength;
|
float normalizedDist = (dToPlanetSurface - TRANSITION_NEAR_END) / transitionLength;
|
||||||
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
||||||
|
|
||||||
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
|
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
|
||||||
@ -95,12 +93,12 @@ namespace ZL {
|
|||||||
currentZFar = MIDDLE_Z_FAR * (1.0f - alpha) + NEAR_Z_FAR * alpha;
|
currentZFar = MIDDLE_Z_FAR * (1.0f - alpha) + NEAR_Z_FAR * alpha;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (distanceToPlanetSurface > TRANSITION_SUPER_NEAR_END) {
|
else if (dToPlanetSurface > TRANSITION_SUPER_NEAR_END) {
|
||||||
// Плавный переход от MIDDLE к NEAR
|
// Плавный переход от MIDDLE к NEAR
|
||||||
const float transitionLength = TRANSITION_NEAR_END - TRANSITION_SUPER_NEAR_END;
|
const float transitionLength = TRANSITION_NEAR_END - TRANSITION_SUPER_NEAR_END;
|
||||||
|
|
||||||
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
|
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
|
||||||
float normalizedDist = (distanceToPlanetSurface - TRANSITION_SUPER_NEAR_END) / transitionLength;
|
float normalizedDist = (dToPlanetSurface - TRANSITION_SUPER_NEAR_END) / transitionLength;
|
||||||
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
||||||
|
|
||||||
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
|
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
|
||||||
@ -109,7 +107,7 @@ namespace ZL {
|
|||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Полностью ближний диапазон (distanceToPlanetSurface <= TRANSITION_NEAR_END)
|
// Полностью ближний диапазон (distancdToPlanetSurfaceeToPlanetSurface <= TRANSITION_NEAR_END)
|
||||||
currentZNear = SUPER_NEAR_Z_NEAR;
|
currentZNear = SUPER_NEAR_Z_NEAR;
|
||||||
currentZFar = SUPER_NEAR_Z_FAR;
|
currentZFar = SUPER_NEAR_Z_FAR;
|
||||||
}
|
}
|
||||||
@ -180,8 +178,8 @@ namespace ZL {
|
|||||||
|
|
||||||
// Масштабируем: хотим отклонение от 1.0 до 1.1
|
// Масштабируем: хотим отклонение от 1.0 до 1.1
|
||||||
// Значит амплитуда = 0.1
|
// Значит амплитуда = 0.1
|
||||||
float height = 1.0f; // * 0.2 даст вариацию высоты
|
//float height = 1.0f; // * 0.2 даст вариацию высоты
|
||||||
//float height = 1.0f - (noiseValue * 0.01f); // * 0.2 даст вариацию высоты
|
float height = 1.0f - (noiseValue * 0.02f); // * 0.2 даст вариацию высоты
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
@ -197,13 +195,81 @@ namespace ZL {
|
|||||||
return distanceToPlanetSurface > 0.1*TRANSITION_MIDDLE_START;
|
return distanceToPlanetSurface > 0.1*TRANSITION_MIDDLE_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Находит ближайшую точку на плоскости, содержащей треугольник (A, B, C).
|
||||||
|
* Это проекция точки P на плоскость.
|
||||||
|
* @return Точка на плоскости (но не обязательно внутри треугольника).
|
||||||
|
*/
|
||||||
|
Vector3f projectPointOnPlane(const Vector3f& P, const Vector3f& A, const Vector3f& B, const Vector3f& C) {
|
||||||
|
Vector3f AB = B + A * (-1.0f);
|
||||||
|
Vector3f AC = C + A * (-1.0f);
|
||||||
|
Vector3f N = AB.cross(AC).normalized(); // Нормаль к плоскости треугольника
|
||||||
|
Vector3f AP = P + A * (-1.0f);
|
||||||
|
|
||||||
|
// Расстояние (со знаком) от P до плоскости: d = N . AP
|
||||||
|
float distance = N.dot(AP);
|
||||||
|
|
||||||
|
// Проекция: P_proj = P - d * N
|
||||||
|
Vector3f P_proj = P + N * (-distance);
|
||||||
|
return P_proj;
|
||||||
|
}
|
||||||
|
|
||||||
float PlanetObject::distanceToPlanetSurface()
|
float PlanetObject::distanceToPlanetSurface()
|
||||||
{
|
{
|
||||||
|
// 1. Смещение позиции корабля в локальные координаты планеты
|
||||||
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
||||||
const float distanceToPlanetCenter = (planetWorldPosition - Environment::shipPosition).length();
|
Vector3f shipLocalPosition = Environment::shipPosition - planetWorldPosition;
|
||||||
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
|
||||||
return distanceToPlanetSurface;
|
|
||||||
|
|
||||||
|
// 2. Находим индекс треугольника, над которым находится корабль
|
||||||
|
// Используем максимальный LOD для наивысшей точности
|
||||||
|
std::vector<int> targetTriangles = triangleUnderCamera(currentLod);
|
||||||
|
|
||||||
|
if (targetTriangles.empty()) {
|
||||||
|
// Если не удалось найти треугольник (например, ошибка в triangleUnderCamera
|
||||||
|
// или корабль очень далеко от сетки), возвращаем старую оценку.
|
||||||
|
return (shipLocalPosition.length() - PLANET_RADIUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Берем первый найденный треугольник (в пограничных случаях будет выбрана одна сторона)
|
||||||
|
int tri_index = targetTriangles[0];
|
||||||
|
|
||||||
|
// 3. Извлекаем вершины
|
||||||
|
const auto& posData = planetMeshLods[currentLod].vertexData.PositionData;
|
||||||
|
|
||||||
|
// Индексы в плоском массиве PositionData
|
||||||
|
size_t data_index = tri_index * 3;
|
||||||
|
if (data_index + 2 >= posData.size()) {
|
||||||
|
// Ошибка данных
|
||||||
|
return (shipLocalPosition.length() - PLANET_RADIUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector3f& A = posData[data_index];
|
||||||
|
const Vector3f& B = posData[data_index + 1];
|
||||||
|
const Vector3f& C = posData[data_index + 2];
|
||||||
|
|
||||||
|
// 4. Находим ближайшую точку на плоскости треугольника
|
||||||
|
Vector3f P_proj = projectPointOnPlane(shipLocalPosition, A, B, C);
|
||||||
|
|
||||||
|
// 5. Проверяем, находится ли P_proj внутри треугольника (используя барицентрические координаты)
|
||||||
|
|
||||||
|
// ВАЖНОЕ УПРОЩЕНИЕ: В контексте геосферы, если корабль находится "над" треугольником
|
||||||
|
// (что гарантируется triangleUnderCamera), ближайшая точка на плоскости (P_proj)
|
||||||
|
// почти всегда будет лежать внутри треугольника A, B, C.
|
||||||
|
// Если P_ship находится очень далеко от поверхности (что обычно так),
|
||||||
|
// P_proj почти точно совпадет с P_closest.
|
||||||
|
|
||||||
|
// Для высокой точности, нам бы понадобилась полная функция closestPointOnTriangle,
|
||||||
|
// но для оценки расстояния в LOD-системах, где P_ship находится далеко от граней,
|
||||||
|
// P_closest = P_proj — это приемлемая аппроксимация.
|
||||||
|
|
||||||
|
// P_closest = closestPointOnTriangle(shipLocalPosition, A, B, C);
|
||||||
|
Vector3f P_closest = P_proj; // Используем аппроксимацию P_proj
|
||||||
|
|
||||||
|
// 6. Вычисляем точное расстояние
|
||||||
|
// Расстояние = |shipLocalPosition - P_closest|
|
||||||
|
float exactDistance = (shipLocalPosition - P_closest).length();
|
||||||
|
|
||||||
|
return exactDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -328,7 +394,7 @@ namespace ZL {
|
|||||||
{
|
{
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName2);
|
renderer.shaderManager.PushShader(defaultShaderName2);
|
||||||
//renderer.RenderUniform1i(textureUniformName, 0);
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
|
|
||||||
|
|
||||||
@ -343,6 +409,8 @@ namespace ZL {
|
|||||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||||
renderer.TranslateMatrix(-Environment::shipPosition);
|
renderer.TranslateMatrix(-Environment::shipPosition);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
||||||
|
|
||||||
Vector3f color1 = { 1.0, 0.0, 0.0 };
|
Vector3f color1 = { 1.0, 0.0, 0.0 };
|
||||||
Vector3f color2 = { 1.0, 1.0, 0.0 };
|
Vector3f color2 = { 1.0, 1.0, 0.0 };
|
||||||
renderer.RenderUniform3fv("uColor", &color1.v[0]);
|
renderer.RenderUniform3fv("uColor", &color1.v[0]);
|
||||||
@ -532,6 +600,16 @@ namespace ZL {
|
|||||||
|
|
||||||
result.vertexData.PositionData.reserve(geometry.size() * 3);
|
result.vertexData.PositionData.reserve(geometry.size() * 3);
|
||||||
result.vertexData.NormalData.reserve(geometry.size() * 3);
|
result.vertexData.NormalData.reserve(geometry.size() * 3);
|
||||||
|
result.vertexData.TexCoordData.reserve(geometry.size() * 3); // <-- РЕЗЕРВИРУЕМ
|
||||||
|
//buffer.TexCoord3Data.reserve(triangles.size() * 3); // <-- РЕЗЕРВИРУЕМ
|
||||||
|
|
||||||
|
// Стандартные UV-координаты для покрытия одного треугольника
|
||||||
|
// Покрывает текстурой всю грань.
|
||||||
|
const std::array<Vector2f, 3> triangleUVs = {
|
||||||
|
Vector2f(0.0f, 0.0f),
|
||||||
|
Vector2f(1.0f, 0.0f),
|
||||||
|
Vector2f(0.0f, 1.0f)
|
||||||
|
};
|
||||||
result.VertexIDs.reserve(geometry.size() * 3); // Заполняем ID здесь
|
result.VertexIDs.reserve(geometry.size() * 3); // Заполняем ID здесь
|
||||||
|
|
||||||
for (const auto& t : geometry) {
|
for (const auto& t : geometry) {
|
||||||
@ -541,6 +619,7 @@ namespace ZL {
|
|||||||
|
|
||||||
// Заполняем NormalData (нормаль = нормализованная позиция на сфере)
|
// Заполняем NormalData (нормаль = нормализованная позиция на сфере)
|
||||||
result.vertexData.NormalData.push_back(t.data[i].normalized());
|
result.vertexData.NormalData.push_back(t.data[i].normalized());
|
||||||
|
result.vertexData.TexCoordData.push_back(triangleUVs[i]);
|
||||||
|
|
||||||
// Заполняем VertexIDs
|
// Заполняем VertexIDs
|
||||||
result.VertexIDs.push_back(t.ids[i]);
|
result.VertexIDs.push_back(t.ids[i]);
|
||||||
|
|||||||
@ -109,6 +109,7 @@ namespace ZL {
|
|||||||
Vector3f calculateSurfaceNormal(Vector3f p_sphere);
|
Vector3f calculateSurfaceNormal(Vector3f p_sphere);
|
||||||
LodLevel trianglesToVertices(const std::vector<Triangle>& triangles);
|
LodLevel trianglesToVertices(const std::vector<Triangle>& triangles);
|
||||||
LodLevel generateSphere(int subdivisions);
|
LodLevel generateSphere(int subdivisions);
|
||||||
|
std::pair<float, float> calculateZRange(const Vector3f& shipPosition);
|
||||||
|
|
||||||
std::vector<int> triangleUnderCamera(int lod);
|
std::vector<int> triangleUnderCamera(int lod);
|
||||||
std::vector<int> findNeighbors(int index, int lod);
|
std::vector<int> findNeighbors(int index, int lod);
|
||||||
|
|||||||
@ -102,5 +102,5 @@ void main()
|
|||||||
gl_FragColor = mix(vec4(finalColor.rgb, 0.5), FOG_COLOR, fogFactor);
|
gl_FragColor = mix(vec4(finalColor.rgb, 0.5), FOG_COLOR, fogFactor);
|
||||||
//gl_FragColor = vec4((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.0,0.0, 1.0);
|
//gl_FragColor = vec4((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.0,0.0, 1.0);
|
||||||
//gl_FragColor = vec4(fogFactor, 0.5,0.5, 1.0);
|
//gl_FragColor = vec4(fogFactor, 0.5,0.5, 1.0);
|
||||||
gl_FragColor = vec4(uColor, 1.0);
|
gl_FragColor = vec4(uColor*textureColor.rgb, 1.0);
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user