88 lines
3.7 KiB
C++
88 lines
3.7 KiB
C++
/*
|
|
Water system
|
|
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
|
|
|
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 _i = i.p0 % BIG_CHUNK_SIZE, _j = i.p1 % BIG_CHUNK_SIZE, _k = i.p2 % BIG_CHUNK_SIZE;
|
|
if (_i < 0) _i += BIG_CHUNK_SIZE; if (_j < 0) _j += BIG_CHUNK_SIZE; if (_k < 0) _k += BIG_CHUNK_SIZE;
|
|
if (chunks[_i][_j][_k] == 0) {qDebug() << "insert" << _i << _j << _k; chunks[_i][_j][_k] = new Chunk();}
|
|
return chunks[_i][_j][_k];}
|
|
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
|