Added some rocks
This commit is contained in:
parent
0464bed4cf
commit
854a425d85
175
Game.cpp
175
Game.cpp
@ -17,6 +17,173 @@ namespace ZL
|
|||||||
const char* CONST_ZIP_FILE = "";
|
const char* CONST_ZIP_FILE = "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Вспомогательная функция для получения случайного числа в диапазоне [min, max]
|
||||||
|
float getRandomFloat(std::mt19937& gen, float min, float max) {
|
||||||
|
std::uniform_real_distribution<> distrib(min, max);
|
||||||
|
return static_cast<float>(distrib(gen));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Икосаэдр (на основе золотого сечения phi)
|
||||||
|
// Координаты могут быть вычислены заранее для константного икосаэдра.
|
||||||
|
// Здесь только объявление, чтобы показать идею.
|
||||||
|
|
||||||
|
VertexDataStruct CreateConvexPolyhedron(uint64_t seed) {
|
||||||
|
|
||||||
|
// --- КОНСТАНТЫ ПАРАМЕТРОВ (как вы просили) ---
|
||||||
|
const float BASE_SCALE = 3.0f; // Общий размер камня
|
||||||
|
const float MIN_AXIS_SCALE = 0.5f; // Минимальное растяжение/сжатие по оси
|
||||||
|
const float MAX_AXIS_SCALE = 1.5f; // Максимальное растяжение/сжатие по оси
|
||||||
|
const float MIN_PERTURBATION = 0.05f; // Минимальное радиальное возмущение вершины
|
||||||
|
const float MAX_PERTURBATION = 0.25f; // Максимальное радиальное возмущение вершины
|
||||||
|
// const size_t SUBDIVISION_LEVEL = 1; // Уровень подразделения (для более круглого камня, пока опустим)
|
||||||
|
|
||||||
|
std::mt19937 engine(static_cast<unsigned int>(seed));
|
||||||
|
|
||||||
|
// Золотое сечение
|
||||||
|
const float t = (1.0f + std::sqrt(5.0f)) / 2.0f;
|
||||||
|
|
||||||
|
// 12 вершин икосаэдра
|
||||||
|
std::vector<Vector3f> initialVertices = {
|
||||||
|
{ -1, t, 0 }, { 1, t, 0 }, { -1, -t, 0 }, { 1, -t, 0 },
|
||||||
|
{ 0, -1, t }, { 0, 1, t }, { 0, -1, -t }, { 0, 1, -t },
|
||||||
|
{ t, 0, -1 }, { t, 0, 1 }, { -t, 0, -1 }, { -t, 0, 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 20 треугольных граней (индексы вершин)
|
||||||
|
std::vector<std::array<int, 3>> faces = {
|
||||||
|
// 5 треугольников вокруг вершины 0
|
||||||
|
{0, 11, 5}, {0, 5, 1}, {0, 1, 7}, {0, 7, 10}, {0, 10, 11},
|
||||||
|
// 5 смежных полос
|
||||||
|
{1, 5, 9}, {5, 11, 4}, {11, 10, 2}, {10, 7, 6}, {7, 1, 8},
|
||||||
|
// 5 треугольников вокруг вершины 3
|
||||||
|
{3, 9, 4}, {3, 4, 2}, {3, 2, 6}, {3, 6, 8}, {3, 8, 9},
|
||||||
|
// 5 смежных полос
|
||||||
|
{4, 9, 5}, {2, 4, 11}, {6, 2, 10}, {8, 6, 7}, {9, 8, 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 1. Нормализация и Возмущение (Perturbation)
|
||||||
|
for (Vector3f& v : initialVertices) {
|
||||||
|
v = v.normalized() * BASE_SCALE; // Нормализация к сфере радиуса BASE_SCALE
|
||||||
|
|
||||||
|
// Радиальное возмущение:
|
||||||
|
float perturbation = getRandomFloat(engine, MIN_PERTURBATION, MAX_PERTURBATION);
|
||||||
|
v = v * (1.0f + perturbation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Трансформация (Масштабирование и Поворот)
|
||||||
|
|
||||||
|
// Случайные масштабы по осям
|
||||||
|
Vector3f scaleFactors = {
|
||||||
|
getRandomFloat(engine, MIN_AXIS_SCALE, MAX_AXIS_SCALE),
|
||||||
|
getRandomFloat(engine, MIN_AXIS_SCALE, MAX_AXIS_SCALE),
|
||||||
|
getRandomFloat(engine, MIN_AXIS_SCALE, MAX_AXIS_SCALE)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Применяем масштабирование
|
||||||
|
for (Vector3f& v : initialVertices) {
|
||||||
|
v.v[0] *= scaleFactors.v[0];
|
||||||
|
v.v[1] *= scaleFactors.v[1];
|
||||||
|
v.v[2] *= scaleFactors.v[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Случайный поворот (например, вокруг трех осей)
|
||||||
|
Vector4f qx = QuatFromRotateAroundX(getRandomFloat(engine, 0.0f, 360.0f));
|
||||||
|
Vector4f qy = QuatFromRotateAroundY(getRandomFloat(engine, 0.0f, 360.0f));
|
||||||
|
Vector4f qz = QuatFromRotateAroundZ(getRandomFloat(engine, 0.0f, 360.0f));
|
||||||
|
Vector4f qFinal = slerp(qx, qy, 0.5f); // Простой пример комбинирования
|
||||||
|
qFinal = slerp(qFinal, qz, 0.5f).normalized();
|
||||||
|
Matrix3f rotationMatrix = QuatToMatrix(qFinal);
|
||||||
|
|
||||||
|
for (Vector3f& v : initialVertices) {
|
||||||
|
v = MultMatrixVector(rotationMatrix, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Сглаженные Нормали и Формирование Mesh
|
||||||
|
VertexDataStruct result;
|
||||||
|
// Карта для накопления нормалей по уникальным позициям вершин
|
||||||
|
// (Требует определенного оператора < для Vector3f в ZLMath.h, который у вас есть)
|
||||||
|
std::map<Vector3f, Vector3f> smoothNormalsMap;
|
||||||
|
|
||||||
|
// Предварительное заполнение карты нормалями
|
||||||
|
for (const auto& face : faces) {
|
||||||
|
Vector3f p1 = initialVertices[face[0]];
|
||||||
|
Vector3f p2 = initialVertices[face[1]];
|
||||||
|
Vector3f p3 = initialVertices[face[2]];
|
||||||
|
|
||||||
|
// Нормаль грани: (p2 - p1) x (p3 - p1)
|
||||||
|
Vector3f faceNormal = (p2 - p1).cross(p3 - p1).normalized();
|
||||||
|
|
||||||
|
smoothNormalsMap[p1] = smoothNormalsMap[p1] + faceNormal;
|
||||||
|
smoothNormalsMap[p2] = smoothNormalsMap[p2] + faceNormal;
|
||||||
|
smoothNormalsMap[p3] = smoothNormalsMap[p3] + faceNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нормализация накопленных нормалей
|
||||||
|
for (auto& pair : smoothNormalsMap) {
|
||||||
|
pair.second = pair.second.normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 4. Финальное заполнение VertexDataStruct и Текстурные Координаты
|
||||||
|
for (const auto& face : faces) {
|
||||||
|
Vector3f p1 = initialVertices[face[0]];
|
||||||
|
Vector3f p2 = initialVertices[face[1]];
|
||||||
|
Vector3f p3 = initialVertices[face[2]];
|
||||||
|
|
||||||
|
// Позиции
|
||||||
|
result.PositionData.push_back(p1);
|
||||||
|
result.PositionData.push_back(p2);
|
||||||
|
result.PositionData.push_back(p3);
|
||||||
|
|
||||||
|
// Сглаженные Нормали (из карты)
|
||||||
|
result.NormalData.push_back(smoothNormalsMap[p1]);
|
||||||
|
result.NormalData.push_back(smoothNormalsMap[p2]);
|
||||||
|
result.NormalData.push_back(smoothNormalsMap[p3]);
|
||||||
|
|
||||||
|
// Текстурные Координаты (Планарная проекция на плоскость грани)
|
||||||
|
// p1 -> (0, 0), p2 -> (L_12, 0), p3 -> (L_13 * cos(angle), L_13 * sin(angle))
|
||||||
|
// Где L_xy - длина вектора, angle - угол между p2-p1 и p3-p1
|
||||||
|
|
||||||
|
Vector3f uAxis = (p2 - p1).normalized();
|
||||||
|
Vector3f vRaw = p3 - p1;
|
||||||
|
|
||||||
|
// Проекция vRaw на uAxis
|
||||||
|
float uProjLen = vRaw.dot(uAxis);
|
||||||
|
|
||||||
|
// Вектор V перпендикулярный U: vRaw - uProj
|
||||||
|
Vector3f vAxisRaw = vRaw - (uAxis * uProjLen);
|
||||||
|
|
||||||
|
// Длина оси V
|
||||||
|
float vLen = vAxisRaw.length();
|
||||||
|
|
||||||
|
// Нормализованная ось V
|
||||||
|
Vector3f vAxis = vAxisRaw.normalized();
|
||||||
|
|
||||||
|
// Координаты (u, v) для p1, p2, p3 относительно p1
|
||||||
|
Vector2f uv1 = { 0.0f, 0.0f };
|
||||||
|
Vector2f uv2 = { (p2 - p1).length(), 0.0f }; // p2-p1 вдоль оси U
|
||||||
|
Vector2f uv3 = { uProjLen, vLen }; // p3-p1: u-компонента = uProjLen, v-компонента = vLen
|
||||||
|
|
||||||
|
// Находим максимальный размер, чтобы масштабировать в [0, 1]
|
||||||
|
float maxUV = max( uv2.v[0], uv3.v[0], uv3.v[1] );
|
||||||
|
|
||||||
|
if (maxUV > 0.000001f) {
|
||||||
|
// Масштабируем:
|
||||||
|
result.TexCoordData.push_back(uv1);
|
||||||
|
result.TexCoordData.push_back(uv2 * (1.f/ maxUV));
|
||||||
|
result.TexCoordData.push_back(uv3 * (1.f/ maxUV));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Предотвращение деления на ноль для вырожденных граней
|
||||||
|
result.TexCoordData.push_back({ 0.0f, 0.0f });
|
||||||
|
result.TexCoordData.push_back({ 0.0f, 0.0f });
|
||||||
|
result.TexCoordData.push_back({ 0.0f, 0.0f });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Vector4f generateRandomQuaternion(std::mt19937& gen)
|
Vector4f generateRandomQuaternion(std::mt19937& gen)
|
||||||
{
|
{
|
||||||
// Ðàñïðåäåëåíèå äëÿ ãåíåðàöèè ñëó÷àéíûõ êîîðäèíàò êâàòåðíèîíà
|
// Ðàñïðåäåëåíèå äëÿ ãåíåðàöèè ñëó÷àéíûõ êîîðäèíàò êâàòåðíèîíà
|
||||||
@ -197,7 +364,8 @@ namespace ZL
|
|||||||
|
|
||||||
for (int i = 0; i < boxCoordsArr.size(); i++)
|
for (int i = 0; i < boxCoordsArr.size(); i++)
|
||||||
{
|
{
|
||||||
boxRenderArr[i].AssignFrom(boxBase);
|
//boxRenderArr[i].AssignFrom(boxBase);
|
||||||
|
boxRenderArr[i].data = CreateConvexPolyhedron(1999);
|
||||||
boxRenderArr[i].RefreshVBO();
|
boxRenderArr[i].RefreshVBO();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +436,8 @@ namespace ZL
|
|||||||
|
|
||||||
planetObject.init();
|
planetObject.init();
|
||||||
|
|
||||||
|
rockTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", ""));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::drawCubemap(float skyPercent)
|
void Game::drawCubemap(float skyPercent)
|
||||||
@ -370,7 +540,8 @@ namespace ZL
|
|||||||
renderer.TranslateMatrix(boxCoordsArr[i].pos);
|
renderer.TranslateMatrix(boxCoordsArr[i].pos);
|
||||||
renderer.RotateMatrix(boxCoordsArr[i].m);
|
renderer.RotateMatrix(boxCoordsArr[i].m);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID());
|
//glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID());
|
||||||
|
glBindTexture(GL_TEXTURE_2D, rockTexture->getTexID());
|
||||||
renderer.DrawVertexRenderStruct(boxRenderArr[i]);
|
renderer.DrawVertexRenderStruct(boxRenderArr[i]);
|
||||||
|
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
|
|||||||
3
Game.h
3
Game.h
@ -44,6 +44,9 @@ namespace ZL {
|
|||||||
size_t newTickCount;
|
size_t newTickCount;
|
||||||
size_t lastTickCount;
|
size_t lastTickCount;
|
||||||
|
|
||||||
|
std::shared_ptr<Texture> rockTexture;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<BoxCoords> boxCoordsArr;
|
std::vector<BoxCoords> boxCoordsArr;
|
||||||
std::vector<VertexRenderStruct> boxRenderArr;
|
std::vector<VertexRenderStruct> boxRenderArr;
|
||||||
|
|||||||
10
ZLMath.cpp
10
ZLMath.cpp
@ -609,6 +609,16 @@ namespace ZL {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2f operator*(Vector2f v, float scale)
|
||||||
|
{
|
||||||
|
Vector2f r = v;
|
||||||
|
|
||||||
|
r.v[0] = v.v[0] * scale;
|
||||||
|
r.v[1] = v.v[1] * scale;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3f operator*(Vector3f v, float scale)
|
Vector3f operator*(Vector3f v, float scale)
|
||||||
{
|
{
|
||||||
Vector3f r = v;
|
Vector3f r = v;
|
||||||
|
|||||||
1
ZLMath.h
1
ZLMath.h
@ -164,6 +164,7 @@ namespace ZL {
|
|||||||
Vector4f QuatFromRotateAroundY(float angle);
|
Vector4f QuatFromRotateAroundY(float angle);
|
||||||
Vector4f QuatFromRotateAroundZ(float angle);
|
Vector4f QuatFromRotateAroundZ(float angle);
|
||||||
|
|
||||||
|
Vector2f operator*(Vector2f v, float scale);
|
||||||
Vector3f operator*(Vector3f v, float scale);
|
Vector3f operator*(Vector3f v, float scale);
|
||||||
Vector4f operator*(Vector4f v, float scale);
|
Vector4f operator*(Vector4f v, float scale);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user