Files
minecraft-pe-0.6.1/src/client/particle/ParticleEngine.cpp
2026-03-02 22:04:18 +03:00

158 lines
4.8 KiB
C++
Executable File

#include "ParticleEngine.h"
#include "Particle.h"
#include "TerrainParticle.h"
#include "../renderer/Textures.h"
#include "../../world/level/Level.h"
#include "../../NinecraftApp.h"
ParticleEngine::ParticleEngine(Level* level, Textures* textures)
: level(level),
textures(textures)
{
textures->loadTexture("particles.png");
}
ParticleEngine::~ParticleEngine() {
clear();
}
void ParticleEngine::add(Particle* p) {
int t = p->getParticleTexture();
particles[t].push_back(p);
}
void ParticleEngine::tick() {
for (int tt = 0; tt < TEXTURE_COUNT; tt++) {
ParticleList& list = particles[tt];
unsigned int size = list.size();
for (unsigned int i = 0; i < size; ++i) {
Particle* p = list[i];
p->tick();
if (p->removed) {
list.erase(list.begin() + (i--));
--size;
delete p;
}
}
}
}
void ParticleEngine::render(Entity* player, float a) {
float xa = (float) Mth::cos(player->yRot * Mth::PI / 180);
float za = (float) Mth::sin(player->yRot * Mth::PI / 180);
float xa2 = -za * (float) Mth::sin(player->xRot * Mth::PI / 180);
float za2 = xa * (float) Mth::sin(player->xRot * Mth::PI / 180);
float ya = (float) Mth::cos(player->xRot * Mth::PI / 180);
Particle::xOff = (player->xOld+(player->x-player->xOld)*a);
Particle::yOff = (player->yOld+(player->y-player->yOld)*a);
Particle::zOff = (player->zOld+(player->z-player->zOld)*a);
for (int tt = 0; tt < 3; tt++) {
if (particles[tt].size() == 0) continue;
if (tt == MISC_TEXTURE)
textures->loadAndBindTexture("particles.png");
else if (tt == TERRAIN_TEXTURE)
textures->loadAndBindTexture("terrain.png");
else if (tt == ITEM_TEXTURE)
textures->loadAndBindTexture("gui/items.png");
Tesselator& t = Tesselator::instance;
t.begin();
for (unsigned int i = 0; i < particles[tt].size(); i++) {
Particle* p = particles[tt][i];
p->render(t, a, xa, ya, za, xa2, za2);
}
t.draw();
}
renderLit(player, a);
}
void ParticleEngine::renderLit(Entity* player, float a) {
int tt = ENTITY_PARTICLE_TEXTURE;
ParticleList& pl = particles[tt];
const int size = pl.size();
if (size == 0) return;
float xa = Mth::cos(player->yRot * Mth::DEGRAD);
float za = Mth::sin(player->yRot * Mth::DEGRAD);
float xs = Mth::sin(player->xRot * Mth::DEGRAD);
float xa2 = -za * xs;
float za2 = xa * xs;
float ya = Mth::cos(player->xRot * Mth::DEGRAD);
Tesselator& t = Tesselator::instance;
for (int i = 0; i < size; i++) {
Particle* p = pl[i];
p->render(t, a, xa, ya, za, xa2, za2);
}
}
void ParticleEngine::setLevel(Level* level) {
this->level = level;
clear();
}
void ParticleEngine::destroy(int x, int y, int z) {
int tid = level->getTile(x, y, z);
if (tid == 0) return;
int data = level->getData(x, y, z);
//static Stopwatch sw;
//sw.start();
Tile* tile = Tile::tiles[tid];
const int SD = 3;
for (int xx = 0; xx < SD; xx++)
for (int yy = 1; yy < SD; yy++)
for (int zz = 0; zz < SD; zz++) {
float xp = x + (xx + 0.5f) / SD;
float yp = y + (yy + 0.5f) / SD;
float zp = z + (zz + 0.5f) / SD;
add((new TerrainParticle(level, xp, yp, zp, 2*(xp - x - 0.5f), 2*(yp - y - 0.5f), 2*(zp - z - 0.5f), tile, data))->init(x, y, z));
}
//sw.stop();
//sw.print("gen destroy particles: ");
}
void ParticleEngine::crack(int x, int y, int z, int face) {
int tid = level->getTile(x, y, z);
if (tid == 0) return;
int data = level->getData(x, y, z);
Tile* tile = Tile::tiles[tid];
float r = 0.10f;
float xp = x + random.nextFloat() * ((tile->xx1 - tile->xx0) - r * 2) + r + tile->xx0;
float yp = y + random.nextFloat() * ((tile->yy1 - tile->yy0) - r * 2) + r + tile->yy0;
float zp = z + random.nextFloat() * ((tile->zz1 - tile->zz0) - r * 2) + r + tile->zz0;
switch (face) {
case 0: yp = y + tile->yy0 - r; break;
case 1: yp = y + tile->yy1 + r; break;
case 2: zp = z + tile->zz0 - r; break;
case 3: zp = z + tile->zz1 + r; break;
case 4: xp = x + tile->xx0 - r; break;
case 5: xp = x + tile->xx1 + r; break;
}
add((new TerrainParticle(level, xp, yp, zp, 0, 0, 0, tile, data))->init(x, y, z)->setPower(0.2f)->scale(0.6f));
}
std::string ParticleEngine::countParticles() {
std::stringstream ss;
int count = 0;
for (int i = 0; i < TEXTURE_COUNT; ++i)
count += particles[i].size();
ss << count;
return ss.str();
}
void ParticleEngine::clear()
{
for (int tt = 0; tt < TEXTURE_COUNT; tt++) {
for (unsigned int i = 0; i < particles[tt].size(); i++)
delete particles[tt][i];
particles[tt].clear();
}
}