/* 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 . */ #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 * > & 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 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 big_chunks; QList near_offsets; GLuint texture; ullong part_count; }; #endif // WATER_SYSTEM_H