Working on multi-threading, including web
This commit is contained in:
parent
b055faf882
commit
648acf8938
@ -474,6 +474,8 @@ add_executable(space-game001
|
|||||||
src/planet/PlanetData.h
|
src/planet/PlanetData.h
|
||||||
src/utils/Perlin.cpp
|
src/utils/Perlin.cpp
|
||||||
src/utils/Perlin.h
|
src/utils/Perlin.h
|
||||||
|
src/utils/TaskManager.cpp
|
||||||
|
src/utils/TaskManager.h
|
||||||
src/planet/StoneObject.cpp
|
src/planet/StoneObject.cpp
|
||||||
src/planet/StoneObject.h
|
src/planet/StoneObject.h
|
||||||
src/render/FrameBuffer.cpp
|
src/render/FrameBuffer.cpp
|
||||||
@ -491,6 +493,7 @@ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT s
|
|||||||
target_include_directories(space-game001 PRIVATE
|
target_include_directories(space-game001 PRIVATE
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/external"
|
"${CMAKE_CURRENT_SOURCE_DIR}/external"
|
||||||
|
"C:/Boost/include/boost-1_84"
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(space-game001 PROPERTIES
|
set_target_properties(space-game001 PROPERTIES
|
||||||
@ -501,6 +504,7 @@ set_target_properties(space-game001 PROPERTIES
|
|||||||
# PNG_ENABLED – включает код PNG в TextureManager
|
# PNG_ENABLED – включает код PNG в TextureManager
|
||||||
# SDL_MAIN_HANDLED – отключает переопределение main -> SDL_main
|
# SDL_MAIN_HANDLED – отключает переопределение main -> SDL_main
|
||||||
target_compile_definitions(space-game001 PRIVATE
|
target_compile_definitions(space-game001 PRIVATE
|
||||||
|
WIN32_LEAN_AND_MEAN
|
||||||
PNG_ENABLED
|
PNG_ENABLED
|
||||||
SDL_MAIN_HANDLED
|
SDL_MAIN_HANDLED
|
||||||
SIMPLIFIED
|
SIMPLIFIED
|
||||||
|
|||||||
@ -157,7 +157,7 @@ emrun --no_browser --port 8080 .
|
|||||||
|
|
||||||
# Emscripten new
|
# Emscripten new
|
||||||
```
|
```
|
||||||
emcc src/main.cpp src/Game.cpp src/Environment.cpp src/BoneAnimatedModel.cpp src/TextModel.cpp src/Projectile.cpp src/SparkEmitter.cpp src/UiManager.cpp src/render/Renderer.cpp src/render/ShaderManager.cpp src/render/TextureManager.cpp src/render/FrameBuffer.cpp src/render/OpenGlExtensions.cpp src/utils/Utils.cpp src/utils/Perlin.cpp src/planet/PlanetData.cpp src/planet/PlanetObject.cpp src/planet/StoneObject.cpp -O2 -std=c++17 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty1/eigen-5.0.0 -I./src -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 -DSIMPLIFIED=1 --preload-file space-game001x.zip -o space-game001.html
|
emcc src/main.cpp src/Game.cpp src/Environment.cpp src/BoneAnimatedModel.cpp src/TextModel.cpp src/Projectile.cpp src/SparkEmitter.cpp src/UiManager.cpp src/render/Renderer.cpp src/render/ShaderManager.cpp src/render/TextureManager.cpp src/render/FrameBuffer.cpp src/render/OpenGlExtensions.cpp src/utils/Utils.cpp src/utils/TaskManager.cpp src/utils/Perlin.cpp src/planet/PlanetData.cpp src/planet/PlanetObject.cpp src/planet/StoneObject.cpp -O2 -std=c++17 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -fexceptions -I./thirdparty1/eigen-5.0.0 -I./src -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -IC:/Boost/include/boost-1_84 -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 -DSIMPLIFIED=1 --preload-file space-game001.zip -o space-game001.html
|
||||||
```
|
```
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
const char* CONST_ZIP_FILE = "space-game001a.zip";
|
const char* CONST_ZIP_FILE = "space-game001.zip";
|
||||||
#else
|
#else
|
||||||
const char* CONST_ZIP_FILE = "";
|
const char* CONST_ZIP_FILE = "";
|
||||||
#endif
|
#endif
|
||||||
@ -343,6 +343,8 @@ namespace ZL
|
|||||||
std::cout << "Init step 6 " << std::endl;
|
std::cout << "Init step 6 " << std::endl;
|
||||||
planetObject.init();
|
planetObject.init();
|
||||||
|
|
||||||
|
planetObject.taskManager = &taskManager;
|
||||||
|
|
||||||
std::cout << "Init step 7 " << std::endl;
|
std::cout << "Init step 7 " << std::endl;
|
||||||
//rockTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
//rockTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
#include "planet/PlanetObject.h"
|
#include "planet/PlanetObject.h"
|
||||||
#include "UiManager.h"
|
#include "UiManager.h"
|
||||||
#include "Projectile.h"
|
#include "Projectile.h"
|
||||||
|
#include "utils/TaskManager.h"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
@ -103,6 +105,11 @@ namespace ZL {
|
|||||||
uint64_t lastProjectileFireTime = 0;
|
uint64_t lastProjectileFireTime = 0;
|
||||||
int maxProjectiles = 32;
|
int maxProjectiles = 32;
|
||||||
std::vector<Vector3f> shipLocalEmissionPoints;
|
std::vector<Vector3f> shipLocalEmissionPoints;
|
||||||
|
|
||||||
|
TaskManager taskManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -51,12 +51,9 @@ namespace ZL {
|
|||||||
planetMeshLods[i].Move(PLANET_CENTER_OFFSET);
|
planetMeshLods[i].Move(PLANET_CENTER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
|
||||||
planetAtmosphereLod = generateSphere(5, 0);
|
planetAtmosphereLod = generateSphere(5, 0);
|
||||||
planetAtmosphereLod.Scale(PLANET_RADIUS * 1.03);
|
planetAtmosphereLod.Scale(PLANET_RADIUS * 1.03);
|
||||||
planetAtmosphereLod.Move(PLANET_CENTER_OFFSET);
|
planetAtmosphereLod.Move(PLANET_CENTER_OFFSET);
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const LodLevel& PlanetData::getLodLevel(int level) const {
|
const LodLevel& PlanetData::getLodLevel(int level) const {
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace ZL {
|
|||||||
VertexID generateEdgeID(const VertexID& id1, const VertexID& id2);
|
VertexID generateEdgeID(const VertexID& id1, const VertexID& id2);
|
||||||
|
|
||||||
#ifdef SIMPLIFIED
|
#ifdef SIMPLIFIED
|
||||||
constexpr static int MAX_LOD_LEVELS = 1;
|
constexpr static int MAX_LOD_LEVELS = 6;
|
||||||
#else
|
#else
|
||||||
constexpr static int MAX_LOD_LEVELS = 6;
|
constexpr static int MAX_LOD_LEVELS = 6;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include "render/OpenGlExtensions.h"
|
#include "render/OpenGlExtensions.h"
|
||||||
#include "Environment.h"
|
#include "Environment.h"
|
||||||
#include "StoneObject.h"
|
#include "StoneObject.h"
|
||||||
|
#include "utils/TaskManager.h"
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
@ -77,20 +77,18 @@ namespace ZL {
|
|||||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", CONST_ZIP_FILE));
|
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", CONST_ZIP_FILE));
|
||||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
||||||
|
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
|
||||||
// Атмосфера
|
// Атмосфера
|
||||||
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
||||||
if (planetAtmosphereRenderStruct.data.PositionData.size() > 0)
|
if (planetAtmosphereRenderStruct.data.PositionData.size() > 0)
|
||||||
{
|
{
|
||||||
planetAtmosphereRenderStruct.RefreshVBO();
|
planetAtmosphereRenderStruct.RefreshVBO();
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
planetStones = CreateStoneGroupData(778, planetData.getLodLevel(lodIndex));
|
planetStones = CreateStoneGroupData(778, planetData.getLodLevel(lodIndex));
|
||||||
|
|
||||||
stonesToRender = planetStones.inflate(planetStones.allInstances.size());
|
//stonesToRender = planetStones.inflate(planetStones.allInstances.size());
|
||||||
|
stonesToRender.resize(planetStones.allInstances.size());
|
||||||
|
planetStones.initStatuses();
|
||||||
|
|
||||||
stoneToBake = planetStones.inflateOne(0, 0.75);
|
stoneToBake = planetStones.inflateOne(0, 0.75);
|
||||||
}
|
}
|
||||||
@ -98,6 +96,75 @@ namespace ZL {
|
|||||||
|
|
||||||
void PlanetObject::update(float deltaTimeMs) {
|
void PlanetObject::update(float deltaTimeMs) {
|
||||||
|
|
||||||
|
// 1. Проверка порога движения (оптимизация из текущего кода)
|
||||||
|
float movementThreshold = 1.0f;
|
||||||
|
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold
|
||||||
|
&& !triangleIndicesToDraw.empty()) {
|
||||||
|
processMainThreadTasks(); // Все равно обрабатываем очередь OpenGL задач
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastUpdatePos = Environment::shipPosition;
|
||||||
|
|
||||||
|
// 2. Получаем список видимых треугольников
|
||||||
|
auto newIndices = planetData.getTrianglesUnderCameraNew2(Environment::shipPosition);
|
||||||
|
std::sort(newIndices.begin(), newIndices.end());
|
||||||
|
|
||||||
|
// 3. Анализируем, что нужно загрузить
|
||||||
|
for (int triIdx : newIndices) {
|
||||||
|
if (planetStones.statuses[triIdx] == ChunkStatus::Empty) {
|
||||||
|
// Помечаем, чтобы не спамить задачами
|
||||||
|
planetStones.statuses[triIdx] = ChunkStatus::Generating;
|
||||||
|
|
||||||
|
// Отправляем тяжелую математику в TaskManager
|
||||||
|
taskManager->EnqueueBackgroundTask([this, triIdx]() {
|
||||||
|
// Выполняется в фоновом потоке: только генерация геометрии в RAM
|
||||||
|
float scaleModifier = 1.0f;
|
||||||
|
VertexDataStruct generatedData = planetStones.inflateOneDataOnly(triIdx, scaleModifier);
|
||||||
|
|
||||||
|
// Передаем задачу на загрузку в GPU в очередь главного потока
|
||||||
|
this->EnqueueMainThreadTask([this, triIdx, data = std::move(generatedData)]() mutable {
|
||||||
|
// Проверяем актуальность: если треугольник всё еще в списке видимых
|
||||||
|
auto it = std::find(triangleIndicesToDraw.begin(), triangleIndicesToDraw.end(), triIdx);
|
||||||
|
if (it != triangleIndicesToDraw.end()) {
|
||||||
|
stonesToRender[triIdx].data = std::move(data);
|
||||||
|
stonesToRender[triIdx].RefreshVBO(); // OpenGL вызов
|
||||||
|
planetStones.statuses[triIdx] = ChunkStatus::Live;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Если уже не нужен — просто сбрасываем статус
|
||||||
|
planetStones.statuses[triIdx] = ChunkStatus::Empty;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Очистка (Unload)
|
||||||
|
// Если статус Live, но треугольника нет в новых индексах — освобождаем GPU память
|
||||||
|
for (size_t i = 0; i < planetStones.statuses.size(); ++i) {
|
||||||
|
if (planetStones.statuses[i] == ChunkStatus::Live) {
|
||||||
|
bool isVisible = std::binary_search(newIndices.begin(), newIndices.end(), (int)i);
|
||||||
|
if (!isVisible) {
|
||||||
|
// Очищаем данные и VBO (деструкторы shared_ptr в VertexRenderStruct сделают glDeleteBuffers)
|
||||||
|
stonesToRender[i].data.PositionData.clear();
|
||||||
|
stonesToRender[i].vao.reset();
|
||||||
|
stonesToRender[i].positionVBO.reset();
|
||||||
|
stonesToRender[i].normalVBO.reset();
|
||||||
|
stonesToRender[i].tangentVBO.reset();
|
||||||
|
stonesToRender[i].binormalVBO.reset();
|
||||||
|
stonesToRender[i].colorVBO.reset();
|
||||||
|
stonesToRender[i].texCoordVBO.reset();
|
||||||
|
|
||||||
|
planetStones.statuses[i] = ChunkStatus::Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triangleIndicesToDraw = std::move(newIndices);
|
||||||
|
|
||||||
|
// 5. Выполняем одну задачу из очереди OpenGL (RefreshVBO и т.д.)
|
||||||
|
processMainThreadTasks();
|
||||||
|
/*
|
||||||
float movementThreshold = 1.0f;
|
float movementThreshold = 1.0f;
|
||||||
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold && !triangleIndicesToDraw.empty()) {
|
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold && !triangleIndicesToDraw.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -111,7 +178,7 @@ namespace ZL {
|
|||||||
|
|
||||||
if (newIndices != triangleIndicesToDraw) {
|
if (newIndices != triangleIndicesToDraw) {
|
||||||
triangleIndicesToDraw = std::move(newIndices);
|
triangleIndicesToDraw = std::move(newIndices);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -205,7 +272,6 @@ namespace ZL {
|
|||||||
|
|
||||||
void PlanetObject::draw(Renderer& renderer) {
|
void PlanetObject::draw(Renderer& renderer) {
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
|
||||||
{
|
{
|
||||||
if (stoneMapFB == nullptr)
|
if (stoneMapFB == nullptr)
|
||||||
{
|
{
|
||||||
@ -221,10 +287,6 @@ namespace ZL {
|
|||||||
stoneMapFB->GenerateMipmaps();
|
stoneMapFB->GenerateMipmaps();
|
||||||
|
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
//bakeStoneTexture(renderer);
|
|
||||||
|
|
||||||
glViewport(0, 0, Environment::width, Environment::height);
|
glViewport(0, 0, Environment::width, Environment::height);
|
||||||
//--------------------------
|
//--------------------------
|
||||||
@ -232,10 +294,7 @@ namespace ZL {
|
|||||||
|
|
||||||
drawPlanet(renderer);
|
drawPlanet(renderer);
|
||||||
drawStones(renderer);
|
drawStones(renderer);
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
|
||||||
drawAtmosphere(renderer);
|
drawAtmosphere(renderer);
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetObject::drawPlanet(Renderer& renderer)
|
void PlanetObject::drawPlanet(Renderer& renderer)
|
||||||
@ -382,7 +441,7 @@ namespace ZL {
|
|||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
||||||
|
|
||||||
|
/*
|
||||||
for (int i : triangleIndicesToDraw)
|
for (int i : triangleIndicesToDraw)
|
||||||
//for (int i = 0; i < stonesToRender.size(); i++)
|
//for (int i = 0; i < stonesToRender.size(); i++)
|
||||||
{
|
{
|
||||||
@ -390,7 +449,20 @@ namespace ZL {
|
|||||||
{
|
{
|
||||||
renderer.DrawVertexRenderStruct(stonesToRender[i]);
|
renderer.DrawVertexRenderStruct(stonesToRender[i]);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
for (int i : triangleIndicesToDraw) {
|
||||||
|
// КРИТИЧЕСКОЕ ИЗМЕНЕНИЕ:
|
||||||
|
// Проверяем, что данные не просто существуют, а загружены в GPU
|
||||||
|
if (planetStones.statuses[i] == ChunkStatus::Live) {
|
||||||
|
// Дополнительная проверка на наличие данных (на всякий случай)
|
||||||
|
if (stonesToRender[i].data.PositionData.size() > 0) {
|
||||||
|
renderer.DrawVertexRenderStruct(stonesToRender[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Если статус Generating или Empty — мы просто пропускаем этот индекс.
|
||||||
|
// Камни появятся на экране плавно, как только отработает TaskManager и RefreshVBO.
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|||||||
@ -16,8 +16,11 @@
|
|||||||
#include "PlanetData.h"
|
#include "PlanetData.h"
|
||||||
#include "StoneObject.h"
|
#include "StoneObject.h"
|
||||||
#include "render/FrameBuffer.h"
|
#include "render/FrameBuffer.h"
|
||||||
|
#include <queue>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
class TaskManager;
|
||||||
|
|
||||||
class PlanetObject {
|
class PlanetObject {
|
||||||
public:
|
public:
|
||||||
@ -39,6 +42,8 @@ namespace ZL {
|
|||||||
|
|
||||||
Vector3f lastUpdatePos;
|
Vector3f lastUpdatePos;
|
||||||
|
|
||||||
|
TaskManager* taskManager = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PlanetObject();
|
PlanetObject();
|
||||||
|
|
||||||
@ -51,6 +56,32 @@ namespace ZL {
|
|||||||
void drawAtmosphere(Renderer& renderer);
|
void drawAtmosphere(Renderer& renderer);
|
||||||
|
|
||||||
float distanceToPlanetSurface(const Vector3f& viewerPosition);
|
float distanceToPlanetSurface(const Vector3f& viewerPosition);
|
||||||
|
|
||||||
|
std::queue<std::function<void()>> mainThreadTasks;
|
||||||
|
std::mutex mainThreadMutex;
|
||||||
|
|
||||||
|
void EnqueueMainThreadTask(std::function<void()> task) {
|
||||||
|
std::lock_guard<std::mutex> lock(mainThreadMutex);
|
||||||
|
mainThreadTasks.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Выполнение задач по одной (или пачкой) за кадр
|
||||||
|
void processMainThreadTasks() {
|
||||||
|
std::function<void()> task;
|
||||||
|
|
||||||
|
// Извлекаем только одну задачу, чтобы не блокировать update надолго
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mainThreadMutex);
|
||||||
|
if (!mainThreadTasks.empty()) {
|
||||||
|
task = std::move(mainThreadTasks.front());
|
||||||
|
mainThreadTasks.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task) {
|
||||||
|
task(); // Здесь выполняется RefreshVBO или загрузка текстуры
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
@ -16,13 +16,20 @@ namespace ZL {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef SIMPLIFIED
|
#ifdef SIMPLIFIED
|
||||||
|
const float StoneParams::BASE_SCALE = 10.0f; // Общий размер камня
|
||||||
|
const float StoneParams::MIN_AXIS_SCALE = 1.0f; // Минимальное растяжение/сжатие по оси
|
||||||
|
const float StoneParams::MAX_AXIS_SCALE = 1.0f; // Максимальное растяжение/сжатие по оси
|
||||||
|
const float StoneParams::MIN_PERTURBATION = 0.0f; // Минимальное радиальное возмущение вершины
|
||||||
|
const float StoneParams::MAX_PERTURBATION = 0.0f; // Максимальное радиальное возмущение вершины
|
||||||
|
const int StoneParams::STONES_PER_TRIANGLE = 40;
|
||||||
|
/*
|
||||||
const float StoneParams::BASE_SCALE = 1000.0f; // Общий размер камня
|
const float StoneParams::BASE_SCALE = 1000.0f; // Общий размер камня
|
||||||
const float StoneParams::MIN_AXIS_SCALE = 1.0f; // Минимальное растяжение/сжатие по оси
|
const float StoneParams::MIN_AXIS_SCALE = 1.0f; // Минимальное растяжение/сжатие по оси
|
||||||
const float StoneParams::MAX_AXIS_SCALE = 1.0f; // Максимальное растяжение/сжатие по оси
|
const float StoneParams::MAX_AXIS_SCALE = 1.0f; // Максимальное растяжение/сжатие по оси
|
||||||
const float StoneParams::MIN_PERTURBATION = 0.0f; // Минимальное радиальное возмущение вершины
|
const float StoneParams::MIN_PERTURBATION = 0.0f; // Минимальное радиальное возмущение вершины
|
||||||
const float StoneParams::MAX_PERTURBATION = 0.0f; // Максимальное радиальное возмущение вершины
|
const float StoneParams::MAX_PERTURBATION = 0.0f; // Максимальное радиальное возмущение вершины
|
||||||
const int StoneParams::STONES_PER_TRIANGLE = 2;
|
const int StoneParams::STONES_PER_TRIANGLE = 2;
|
||||||
|
*/
|
||||||
#else
|
#else
|
||||||
const float StoneParams::BASE_SCALE = 10.0f; // Общий размер камня
|
const float StoneParams::BASE_SCALE = 10.0f; // Общий размер камня
|
||||||
const float StoneParams::MIN_AXIS_SCALE = 1.0f; // Минимальное растяжение/сжатие по оси
|
const float StoneParams::MIN_AXIS_SCALE = 1.0f; // Минимальное растяжение/сжатие по оси
|
||||||
@ -297,34 +304,12 @@ namespace ZL {
|
|||||||
|
|
||||||
std::vector<VertexRenderStruct> StoneGroup::inflate(int count)
|
std::vector<VertexRenderStruct> StoneGroup::inflate(int count)
|
||||||
{
|
{
|
||||||
//static VertexDataStruct baseStone = CreateBaseConvexPolyhedron(1337);
|
|
||||||
|
|
||||||
std::vector<VertexRenderStruct> result;
|
std::vector<VertexRenderStruct> result;
|
||||||
result.resize(count);
|
result.resize(count);
|
||||||
|
|
||||||
for (int tIdx = 0; tIdx < count; tIdx++)
|
for (int tIdx = 0; tIdx < count; tIdx++)
|
||||||
{
|
{
|
||||||
result[tIdx] = inflateOne(tIdx, 1.0f);
|
result[tIdx] = inflateOne(tIdx, 1.0f);
|
||||||
/*
|
|
||||||
for (const auto& inst : allInstances[tIdx]) {
|
|
||||||
Matrix3f rotMat = QuatToMatrix(inst.rotation);
|
|
||||||
|
|
||||||
for (size_t j = 0; j < baseStone.PositionData.size(); ++j) {
|
|
||||||
Vector3f p = baseStone.PositionData[j];
|
|
||||||
Vector3f n = baseStone.NormalData[j];
|
|
||||||
|
|
||||||
p.v[0] *= inst.scale.v[0];
|
|
||||||
p.v[1] *= inst.scale.v[1];
|
|
||||||
p.v[2] *= inst.scale.v[2];
|
|
||||||
|
|
||||||
result[tIdx].data.PositionData.push_back(MultMatrixVector(rotMat, p) + inst.position);
|
|
||||||
result[tIdx].data.NormalData.push_back(MultMatrixVector(rotMat, n));
|
|
||||||
result[tIdx].data.TexCoordData.push_back(baseStone.TexCoordData[j]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
result[tIdx].RefreshVBO();
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -361,4 +346,33 @@ namespace ZL {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VertexDataStruct StoneGroup::inflateOneDataOnly(int index, float scaleModifier)
|
||||||
|
{
|
||||||
|
static VertexDataStruct baseStone = CreateBaseConvexPolyhedron(1337);
|
||||||
|
|
||||||
|
VertexDataStruct result;
|
||||||
|
|
||||||
|
|
||||||
|
for (const auto& inst : allInstances[index]) {
|
||||||
|
Matrix3f rotMat = inst.rotation.toRotationMatrix();
|
||||||
|
|
||||||
|
for (size_t j = 0; j < baseStone.PositionData.size(); ++j) {
|
||||||
|
Vector3f p = baseStone.PositionData[j];
|
||||||
|
Vector3f n = baseStone.NormalData[j];
|
||||||
|
|
||||||
|
p(0) *= inst.scale(0) * scaleModifier;
|
||||||
|
p(1) *= inst.scale(1) * scaleModifier;
|
||||||
|
p(2) *= inst.scale(2) * scaleModifier;
|
||||||
|
|
||||||
|
result.PositionData.push_back(rotMat * p + inst.position);
|
||||||
|
result.NormalData.push_back(rotMat * n);
|
||||||
|
result.TexCoordData.push_back(baseStone.TexCoordData[j]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
|
|||||||
@ -22,6 +22,13 @@ namespace ZL {
|
|||||||
Eigen::Quaternionf rotation;
|
Eigen::Quaternionf rotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ChunkStatus {
|
||||||
|
Empty, // Äàííûõ íåò
|
||||||
|
Generating, // Çàäà÷à â TaskManager (CPU)
|
||||||
|
ReadyToUpload, // Äàííûå â ïàìÿòè, æäóò î÷åðåäè â ãëàâíûé ïîòîê
|
||||||
|
Live // Çàãðóæåíî â GPU è ãîòîâî ê îòðèñîâêå
|
||||||
|
};
|
||||||
|
|
||||||
struct StoneGroup {
|
struct StoneGroup {
|
||||||
// mesh.PositionData è ïðî÷èå áóäóò çàïîëíÿòüñÿ â inflate()
|
// mesh.PositionData è ïðî÷èå áóäóò çàïîëíÿòüñÿ â inflate()
|
||||||
VertexDataStruct mesh;
|
VertexDataStruct mesh;
|
||||||
@ -32,6 +39,14 @@ namespace ZL {
|
|||||||
std::vector<VertexRenderStruct> inflate(int count);
|
std::vector<VertexRenderStruct> inflate(int count);
|
||||||
|
|
||||||
VertexRenderStruct inflateOne(int index, float scaleModifier);
|
VertexRenderStruct inflateOne(int index, float scaleModifier);
|
||||||
|
VertexDataStruct inflateOneDataOnly(int index, float scaleModifier);
|
||||||
|
|
||||||
|
std::vector<ChunkStatus> statuses;
|
||||||
|
|
||||||
|
// Èíèöèàëèçàöèÿ ñòàòóñîâ ïðè ñîçäàíèè ãðóïïû
|
||||||
|
void initStatuses() {
|
||||||
|
statuses.assign(allInstances.size(), ChunkStatus::Empty);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Òåïåðü âîçâðàùàåò çàãîòîâêó ñî âñåìè ïàðàìåòðàìè, íî áåç òÿæåëîãî ìåøà
|
// Òåïåðü âîçâðàùàåò çàãîòîâêó ñî âñåìè ïàðàìåòðàìè, íî áåç òÿæåëîãî ìåøà
|
||||||
|
|||||||
0
src/utils/TaskManager.cpp
Normal file
0
src/utils/TaskManager.cpp
Normal file
43
src/utils/TaskManager.h
Normal file
43
src/utils/TaskManager.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
class TaskManager {
|
||||||
|
private:
|
||||||
|
boost::asio::io_context ioContext;
|
||||||
|
std::unique_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> workGuard;
|
||||||
|
std::vector<std::thread> workers;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//TaskManager(size_t threadCount = std::thread::hardware_concurrency()) {
|
||||||
|
TaskManager(size_t threadCount = 2) {
|
||||||
|
workGuard = std::make_unique<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>>(ioContext.get_executor());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < threadCount; ++i) {
|
||||||
|
workers.emplace_back([this]() {
|
||||||
|
ioContext.run();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ìåòîä äëÿ äîáàâëåíèÿ ôîíîâîé çàäà÷è
|
||||||
|
void EnqueueBackgroundTask(std::function<void()> task) {
|
||||||
|
boost::asio::post(ioContext, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Graceful shutdown
|
||||||
|
~TaskManager() {
|
||||||
|
workGuard.reset(); // Ðàçðåøàåì ioContext.run() çàâåðøèòüñÿ, êîãäà çàäà÷ íå îñòàíåòñÿ
|
||||||
|
ioContext.stop(); // Îïöèîíàëüíî: íåìåäëåííàÿ îñòàíîâêà
|
||||||
|
for (auto& t : workers) {
|
||||||
|
if (t.joinable()) t.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
Loading…
Reference in New Issue
Block a user