Added trails to other ships toos

This commit is contained in:
Vladislav Khorev 2026-03-08 21:27:45 +03:00
parent 59b5bea540
commit 24aa7007bb
7 changed files with 128 additions and 88 deletions

View File

@ -1,5 +1,5 @@
{ {
"emissionRate": 0.4, "emissionRate": 1.2,
"maxParticles": 400, "maxParticles": 400,
"particleSize": 0.3, "particleSize": 0.3,
"biasX": 0.3, "biasX": 0.3,

View File

@ -1,5 +1,5 @@
{ {
"emissionRate": 0.4, "emissionRate": 1.2,
"maxParticles": 400, "maxParticles": 400,
"particleSize": 0.3, "particleSize": 0.3,
"biasX": 0.3, "biasX": 0.3,

View File

@ -41,6 +41,10 @@ namespace ZL
const char* CONST_ZIP_FILE = ""; const char* CONST_ZIP_FILE = "";
#endif #endif
float x = 0;
float y = 0;
float z = 0;
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
Game* Game::s_instance = nullptr; Game* Game::s_instance = nullptr;
@ -420,22 +424,6 @@ namespace ZL
handleMotion(ZL::UiManager::MOUSE_FINGER_ID, mx, my); handleMotion(ZL::UiManager::MOUSE_FINGER_ID, mx, my);
} }
/*if (event.type == SDL_MOUSEBUTTONDOWN) {
int mx = event.button.x;
int my = event.button.y;
handleDown(mx, my);
}
if (event.type == SDL_MOUSEBUTTONUP) {
int mx = event.button.x;
int my = event.button.y;
handleUp(mx, my);
}
if (event.type == SDL_MOUSEMOTION) {
int mx = event.motion.x;
int my = event.motion.y;
handleMotion(mx, my);
}*/
if (event.type == SDL_MOUSEWHEEL) { if (event.type == SDL_MOUSEWHEEL) {
static const float zoomstep = 2.0f; static const float zoomstep = 2.0f;
if (event.wheel.y > 0) { if (event.wheel.y > 0) {
@ -465,7 +453,25 @@ namespace ZL
if (event.type == SDL_KEYUP) { if (event.type == SDL_KEYUP) {
if (event.key.keysym.sym == SDLK_a) { if (event.key.keysym.sym == SDLK_a) {
//Environment::shipState.position = { 9466.15820, 1046.00159, 18531.2090 }; x = x + 0.2f;
}
if (event.key.keysym.sym == SDLK_q) {
x = x - 0.2f;
}
if (event.key.keysym.sym == SDLK_s) {
y = y + 0.2f;
}
if (event.key.keysym.sym == SDLK_w) {
y = y - 0.2f;
}
if (event.key.keysym.sym == SDLK_d) {
z = z + 0.2f;
}
if (event.key.keysym.sym == SDLK_e) {
z = z - 0.2f;
}
if (event.key.keysym.sym == SDLK_r) {
std::cout << "Camera position: x=" << x << " y=" << y << " z=" << z << std::endl;
} }
} }
#endif #endif

View File

@ -33,6 +33,8 @@ namespace ZL
extern const char* CONST_ZIP_FILE; extern const char* CONST_ZIP_FILE;
extern float x; extern float x;
extern float y;
extern float z;
Eigen::Quaternionf generateRandomQuaternion(std::mt19937& gen) Eigen::Quaternionf generateRandomQuaternion(std::mt19937& gen)
{ {
@ -507,17 +509,7 @@ namespace ZL
} }
renderer.PushMatrix(); drawShipSparkEmitters();
renderer.RotateMatrix(Environment::inverseShipMatrix);
renderer.TranslateMatrix(- /*0.5 * */ Environment::shipState.position);
std::cout << "Ship pos draw: " << Environment::shipState.position.transpose() << "\n";
if (Environment::shipState.shipType == 1) {
sparkEmitterCargo.draw(renderer, Environment::zoom, Environment::width, Environment::height);
}
else {
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
}
renderer.PopMatrix();
} }
renderer.PopMatrix(); renderer.PopMatrix();
@ -591,16 +583,7 @@ namespace ZL
glViewport(0, 0, Environment::width, Environment::height); glViewport(0, 0, Environment::width, Environment::height);
// Готовим данные всех эмиттеров (CPU + VBO upload) до начала отрисовки, prepareSparkEmittersForDraw();
// чтобы draw() делал только GPU-вызовы без пауз между кораблём и частицами.
sparkEmitter.prepareForDraw(true);
sparkEmitterCargo.prepareForDraw(true);
explosionEmitter.prepareForDraw(false);
for (const auto& p : projectiles) {
if (p && p->isActive()) {
p->projectileEmitter.prepareForDraw(true);
}
}
CheckGlError(); CheckGlError();
@ -1431,6 +1414,89 @@ namespace ZL
targetWasVisible = false; targetWasVisible = false;
} }
void Space::updateSparkEmitters(float deltaMs)
{
// Local ship
SparkEmitter* sparkEmitterPtr;
if (Environment::shipState.shipType == 1) {
sparkEmitterPtr = &sparkEmitterCargo;
static std::vector<Vector3f> emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) };
emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 2.8, -6.5 + 16.0 };
emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 1.5, -6.5 + 16.0 };
sparkEmitterPtr->setEmissionPoints(emissionPoints);
}
else {
sparkEmitterPtr = &sparkEmitter;
static std::vector<Vector3f> emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) };
emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ -0.9, 1.4 - 1.0, -8.5 + 16.0 };
emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.9, 1.4 - 1.0, -8.5 + 16.0 };
sparkEmitterPtr->setEmissionPoints(emissionPoints);
}
sparkEmitterPtr->setIsActive(Environment::shipState.velocity > 0.1f);
sparkEmitterPtr->update(deltaMs);
// Remote ships
for (auto const& [id, playerState] : remotePlayerStates) {
if (deadRemotePlayers.count(id)) continue;
if (!remoteShipSparkEmitters.count(id)) {
remoteShipSparkEmitters.emplace(id, playerState.shipType == 1 ? sparkEmitterCargo : sparkEmitter);
}
auto& remEmitter = remoteShipSparkEmitters.at(id);
std::vector<Vector3f> remEmitPts(2);
if (playerState.shipType == 1) {
remEmitPts[0] = playerState.position + playerState.rotation * Vector3f{ 0.0f, -0.4f+2.8f, 8.4f };
remEmitPts[1] = playerState.position + playerState.rotation * Vector3f{ 0.0f, -0.4f+1.5f, 8.4f };
} else {
remEmitPts[0] = playerState.position + playerState.rotation * Vector3f{ -0.9f, -0.2,5.6 };
remEmitPts[1] = playerState.position + playerState.rotation * Vector3f{ 0.9f,-0.2,5.6 };
}
remEmitter.setEmissionPoints(remEmitPts);
remEmitter.setIsActive(playerState.velocity > 0.1f);
remEmitter.update(deltaMs);
}
}
void Space::prepareSparkEmittersForDraw()
{
sparkEmitter.prepareForDraw(true);
sparkEmitterCargo.prepareForDraw(true);
for (auto& [id, emitter] : remoteShipSparkEmitters) {
if (!deadRemotePlayers.count(id)) emitter.prepareForDraw(true);
}
explosionEmitter.prepareForDraw(false);
for (const auto& p : projectiles) {
if (p && p->isActive()) {
p->projectileEmitter.prepareForDraw(true);
}
}
}
void Space::drawShipSparkEmitters()
{
renderer.PushMatrix();
renderer.RotateMatrix(Environment::inverseShipMatrix);
renderer.TranslateMatrix(-Environment::shipState.position);
if (Environment::shipState.shipType == 1) {
sparkEmitterCargo.draw(renderer, Environment::zoom, Environment::width, Environment::height);
} else {
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
}
for (auto& [id, emitter] : remoteShipSparkEmitters) {
if (!deadRemotePlayers.count(id)) {
renderer.PushMatrix();
renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Environment::inverseShipMatrix);
renderer.TranslateMatrix(-Environment::shipState.position);
emitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
renderer.PopMatrix();
}
}
renderer.PopMatrix();
}
void Space::processTickCount(int64_t newTickCount, int64_t delta) { void Space::processTickCount(int64_t newTickCount, int64_t delta) {
auto now_ms = newTickCount; auto now_ms = newTickCount;
@ -1522,7 +1588,7 @@ namespace ZL
std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent(); std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent();
networkClient->Send(msg); networkClient->Send(msg);
std::cout << "Sending: " << msg << std::endl; //std::cout << "Sending: " << msg << std::endl;
} }
long long leftoverDelta = delta; long long leftoverDelta = delta;
@ -1545,41 +1611,6 @@ namespace ZL
} }
//--------------
SparkEmitter* sparkEmitterPtr;
if (Environment::shipState.shipType == 1) {
sparkEmitterPtr = &sparkEmitterCargo;
static std::vector<Vector3f> emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) };
emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 2.8, -6.5 + 16.0 };
emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 1.5, -6.5 + 16.0 };
sparkEmitterPtr->setEmissionPoints(emissionPoints);
}
else
{
sparkEmitterPtr = &sparkEmitter;
static std::vector<Vector3f> emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) };
emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ -0.9, 1.4 - 1.0, -8.5 + 16.0 };
emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.9, 1.4 - 1.0, -8.5 + 16.0 };
sparkEmitterPtr->setEmissionPoints(emissionPoints);
//sparkEmitterPtr->setEmissionPoints({ /*0.5* */Environment::shipState.position });
//sparkEmitterPtr->setEmissionPoints({ Vector3f(0, 0, 0) });
std::cout << "Ship pos empo: " << Environment::shipState.position.transpose() << "\n";
}
if (Environment::shipState.velocity > 0.1f)
{
sparkEmitterPtr->setIsActive(true);
}
else
{
sparkEmitterPtr->setIsActive(false);
}
sparkEmitterPtr->update(static_cast<float>(delta));
auto latestRemotePlayers = networkClient->getRemotePlayers(); auto latestRemotePlayers = networkClient->getRemotePlayers();
std::chrono::system_clock::time_point nowRoundedWithDelay{ std::chrono::milliseconds(newTickCount - CLIENT_DELAY) }; std::chrono::system_clock::time_point nowRoundedWithDelay{ std::chrono::milliseconds(newTickCount - CLIENT_DELAY) };
@ -1601,6 +1632,8 @@ namespace ZL
remotePlayerStates[id] = playerState; remotePlayerStates[id] = playerState;
} }
updateSparkEmitters(static_cast<float>(delta));
for (auto& p : projectiles) { for (auto& p : projectiles) {
if (p && p->isActive()) { if (p && p->isActive()) {
p->update(static_cast<float>(delta), renderer); p->update(static_cast<float>(delta), renderer);
@ -1875,6 +1908,7 @@ namespace ZL
for (int pid : disconnects) { for (int pid : disconnects) {
remotePlayerStates.erase(pid); remotePlayerStates.erase(pid);
deadRemotePlayers.erase(pid); deadRemotePlayers.erase(pid);
remoteShipSparkEmitters.erase(pid);
if (trackedTargetId == pid) { if (trackedTargetId == pid) {
trackedTargetId = -1; trackedTargetId = -1;
targetAcquireAnim = 0.f; targetAcquireAnim = 0.f;

View File

@ -66,6 +66,7 @@ namespace ZL {
std::unique_ptr<TextRenderer> textRenderer; std::unique_ptr<TextRenderer> textRenderer;
std::unordered_map<int, ClientState> remotePlayerStates; std::unordered_map<int, ClientState> remotePlayerStates;
std::unordered_map<int, SparkEmitter> remoteShipSparkEmitters;
float newShipVelocity = 0; float newShipVelocity = 0;
@ -144,6 +145,10 @@ namespace ZL {
void resetPlayerState(); void resetPlayerState();
void clearTextRendererCache(); void clearTextRendererCache();
void updateSparkEmitters(float deltaMs);
void prepareSparkEmittersForDraw();
void drawShipSparkEmitters();
// Crosshair HUD // Crosshair HUD
struct CrosshairConfig { struct CrosshairConfig {
bool enabled = true; bool enabled = true;

View File

@ -30,8 +30,8 @@ namespace ZL {
: particles(copyFrom.particles), emissionPoints(copyFrom.emissionPoints), : particles(copyFrom.particles), emissionPoints(copyFrom.emissionPoints),
lastEmissionTime(copyFrom.lastEmissionTime), emissionRate(copyFrom.emissionRate), lastEmissionTime(copyFrom.lastEmissionTime), emissionRate(copyFrom.emissionRate),
isActive(copyFrom.isActive), drawPositions(copyFrom.drawPositions), isActive(copyFrom.isActive), drawPositions(copyFrom.drawPositions),
drawTexCoords(copyFrom.drawTexCoords), drawDataDirty(copyFrom.drawDataDirty), drawTexCoords(copyFrom.drawTexCoords), drawDataDirty(true),
sparkQuad(copyFrom.sparkQuad), texture(copyFrom.texture), texture(copyFrom.texture),
maxParticles(copyFrom.maxParticles), particleSize(copyFrom.particleSize), maxParticles(copyFrom.maxParticles), particleSize(copyFrom.particleSize),
biasX(copyFrom.biasX), speedRange(copyFrom.speedRange), biasX(copyFrom.biasX), speedRange(copyFrom.speedRange),
zSpeedRange(copyFrom.zSpeedRange), zSpeedRange(copyFrom.zSpeedRange),
@ -40,6 +40,8 @@ namespace ZL {
shaderProgramName(copyFrom.shaderProgramName), shaderProgramName(copyFrom.shaderProgramName),
configured(copyFrom.configured), useWorldSpace(copyFrom.useWorldSpace) configured(copyFrom.configured), useWorldSpace(copyFrom.useWorldSpace)
{ {
// Each copy gets its own GPU buffers; only copy CPU-side data
sparkQuad.data = copyFrom.sparkQuad.data;
} }
@ -198,16 +200,10 @@ namespace ZL {
throw std::runtime_error("Failed to load spark emitter config file 2!"); throw std::runtime_error("Failed to load spark emitter config file 2!");
} }
//prepareDrawData(withRotation);
if (drawPositions.empty()) { if (drawPositions.empty()) {
return; return;
} }
/*
sparkQuad.data.PositionData = drawPositions;
sparkQuad.data.TexCoordData = drawTexCoords;
sparkQuad.RefreshVBO();
*/
renderer.shaderManager.PushShader(shaderProgramName); renderer.shaderManager.PushShader(shaderProgramName);
renderer.RenderUniform1i(textureUniformName, 0); renderer.RenderUniform1i(textureUniformName, 0);
renderer.SetMatrix(); renderer.SetMatrix();

View File

@ -617,6 +617,7 @@ namespace ZL {
{ {
throw std::runtime_error("Modelview matrix stack overflow!!!!"); throw std::runtime_error("Modelview matrix stack overflow!!!!");
} }
SetMatrix();
} }
void Renderer::LoadIdentity() void Renderer::LoadIdentity()
@ -922,8 +923,6 @@ namespace ZL {
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer()); glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer());
VertexAttribPointer3fv(vPosition, 0, NULL); VertexAttribPointer3fv(vPosition, 0, NULL);
//EnableVertexAttribArray(vPosition);
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(VertexRenderStruct.data.PositionData.size())); glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(VertexRenderStruct.data.PositionData.size()));
} }