Files
qad/qglview/water_system.h

90 lines
3.7 KiB
C++

/*
Water system
Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WATER_SYSTEM_H
#define WATER_SYSTEM_H
#include "globject.h"
#define BIG_CHUNK_SIZE 4
#define BIG_CHUNK_SIZEF 4.f
#define CHUNK_SIZE 8*8*8
class WaterSystem: public GLObjectBase
{
public:
WaterSystem();
~WaterSystem();
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
virtual void update();
virtual void init() {createGLTexture(texture, QImage("./media-record.png")); material_.map_diffuse.bitmap_id = texture; is_init = true;}
protected:
class Chunk;
class BigChunk;
struct Particle {
Particle() {mass = 1.; radius = 0.2;}
//Particle(const Particle & other) {pos = other.pos; speed = other.speed; accel = other.accel; mass = other.mass; radius = other.radius; processed = other.processed;}
Vector3d pos;
Vector3d speed;
Vector3d accel;
float mass;
float radius;
bool processed;
Vector3i chunkIndex() {return Vector3i(floor(pos.x / 8.), floor(pos.y / 8.), floor(pos.z / 8.));}
Vector3i bigChunkIndex() {Vector3i i(floor(pos.x / 8.), floor(pos.y / 8.), floor(pos.z / 8.)); return Vector3i(floor(i.p0 / BIG_CHUNK_SIZEF), floor(i.p1 / BIG_CHUNK_SIZEF), floor(i.p2 / BIG_CHUNK_SIZEF));}
void process(const QList<QVector<Particle> * > & near_parts);
};
class Chunk {
public:
Chunk() {particles.reserve(CHUNK_SIZE); prev_particles.reserve(CHUNK_SIZE);}
Vector3i bigIndex() {return Vector3i(floor(index.p0 / BIG_CHUNK_SIZEF), floor(index.p1 / BIG_CHUNK_SIZEF), floor(index.p2 / BIG_CHUNK_SIZEF));}
void saveState() {prev_particles = particles; for (int i = 0; i < particles.size(); ++i) particles[i].processed = false;}
Vector3i index;
QVector<Particle> particles, prev_particles;
};
class BigChunk {
public:
BigChunk() {for (int i = 0; i < BIG_CHUNK_SIZE; ++i) for (int j = 0; j < BIG_CHUNK_SIZE; ++j) for (int k = 0; k < BIG_CHUNK_SIZE; ++k) chunks[i][j][k] = 0;}
~BigChunk() {for (int i = 0; i < BIG_CHUNK_SIZE; ++i) for (int j = 0; j < BIG_CHUNK_SIZE; ++j) for (int k = 0; k < BIG_CHUNK_SIZE; ++k) if (chunks[i][j][k] != 0) delete chunks[i][j][k];}
void saveState() {for (int i = 0; i < BIG_CHUNK_SIZE; ++i) for (int j = 0; j < BIG_CHUNK_SIZE; ++j) for (int k = 0; k < BIG_CHUNK_SIZE; ++k) if (chunks[i][j][k] != 0) chunks[i][j][k]->saveState();}
Chunk * newChunk(const Vector3i & i) {
int ii = i.p0 % BIG_CHUNK_SIZE, jj = i.p1 % BIG_CHUNK_SIZE, kk = i.p2 % BIG_CHUNK_SIZE;
if (ii < 0) ii += BIG_CHUNK_SIZE;
if (jj < 0) jj += BIG_CHUNK_SIZE;
if (kk < 0) kk += BIG_CHUNK_SIZE;
if (chunks[ii][jj][kk] == 0) {qDebug() << "insert" << ii << jj << kk; chunks[ii][jj][kk] = new Chunk();}
return chunks[ii][jj][kk];}
Vector3i index;
Chunk * chunks[BIG_CHUNK_SIZE][BIG_CHUNK_SIZE][BIG_CHUNK_SIZE];
};
BigChunk * newBigChunk(const Vector3i & i) {BigChunk * tbc = big_chunks.value(i); if (tbc == 0) {qDebug() << "insert big" << i; tbc = new BigChunk(); big_chunks.insert(i, tbc);} return tbc;}
QHash<Vector3i, BigChunk * > big_chunks;
QList<Vector3i> near_offsets;
GLuint texture;
ullong part_count;
};
#endif // WATER_SYSTEM_H