1
git-svn-id: svn://db.shs.com.ru/libs@1 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
230
qglview/water_system.cpp
Normal file
230
qglview/water_system.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
QGLView
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "water_system.h"
|
||||
|
||||
|
||||
WaterSystem::WaterSystem(): GLObjectBase() {
|
||||
texture = 0;
|
||||
near_offsets
|
||||
<< Vector3i(-1, 0, 0)
|
||||
<< Vector3i( 1, 0, 0)
|
||||
<< Vector3i(-1, -1, 0)
|
||||
<< Vector3i( 1, -1, 0)
|
||||
<< Vector3i( 0, -1, 0)
|
||||
<< Vector3i(-1, 1, 0)
|
||||
<< Vector3i( 1, 1, 0)
|
||||
<< Vector3i( 0, 1, 0)
|
||||
<< Vector3i(-1, 0, -1)
|
||||
<< Vector3i( 1, 0, -1)
|
||||
<< Vector3i( 0, 0, -1)
|
||||
<< Vector3i(-1, -1, -1)
|
||||
<< Vector3i( 1, -1, -1)
|
||||
<< Vector3i( 0, -1, -1)
|
||||
<< Vector3i(-1, 1, -1)
|
||||
<< Vector3i( 1, 1, -1)
|
||||
<< Vector3i( 0, 1, -1)
|
||||
<< Vector3i(-1, 0, 1)
|
||||
<< Vector3i( 1, 0, 1)
|
||||
<< Vector3i( 0, 0, 1)
|
||||
<< Vector3i(-1, -1, 1)
|
||||
<< Vector3i( 1, -1, 1)
|
||||
<< Vector3i( 0, -1, 1)
|
||||
<< Vector3i(-1, 1, 1)
|
||||
<< Vector3i( 1, 1, 1)
|
||||
<< Vector3i( 0, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
WaterSystem::~WaterSystem() {
|
||||
QList<BigChunk * > cv = big_chunks.values();
|
||||
foreach (BigChunk * i, cv) {
|
||||
qDebug() << "delete" << i;
|
||||
delete i;
|
||||
}
|
||||
cv.clear();
|
||||
}
|
||||
|
||||
|
||||
void WaterSystem::update() {
|
||||
QList<BigChunk * > cv = big_chunks.values();
|
||||
//qDebug() << "save states" << cv.size();
|
||||
foreach (BigChunk * i, cv)
|
||||
i->saveState();
|
||||
Particle tp;
|
||||
if (part_count < 5000)
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
tp.pos = QVector3D(urand()*20+30, urand()*20+30, 30);
|
||||
tp.speed = QVector3D(urand(1.), urand(1.), 0.);
|
||||
newBigChunk(tp.bigChunkIndex())->newChunk(tp.chunkIndex())->particles << tp;
|
||||
}
|
||||
QList<BigChunk * > near_big;
|
||||
QList<Chunk * > near_;
|
||||
QList<QVector<Particle> * > near_parts;
|
||||
Vector3i cind, nind;
|
||||
#if QT_VERSION >= 0x040700
|
||||
near_big.reserve(27);
|
||||
near_.reserve(27);
|
||||
near_parts.reserve(27);
|
||||
#endif
|
||||
foreach (BigChunk * bc, cv) {
|
||||
Vector3i bci = bc->index;
|
||||
near_big.clear();
|
||||
near_big << bc;
|
||||
foreach (const Vector3i & o, near_offsets)
|
||||
near_big << big_chunks.value(bci + o);
|
||||
near_big.removeAll(0);
|
||||
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) {
|
||||
Chunk * cc = bc->chunks[i][j][k];
|
||||
if (cc == 0) continue;
|
||||
near_.clear();
|
||||
//foreach (const Vector3i & o, near_offsets)
|
||||
// near_ << big_chunks.value(bci + o);
|
||||
near_ << cc;
|
||||
near_.removeAll(0);
|
||||
near_parts.clear();
|
||||
foreach (Chunk * ci, near_)
|
||||
if (!ci->prev_particles.isEmpty())
|
||||
near_parts << &(ci->prev_particles);
|
||||
QVector<Particle> & parts(cc->particles);
|
||||
//qDebug() << "chunk" << cc->index.toQVector3D() << "proc" << parts.size() << "particles";
|
||||
for (int p = 0; p < parts.size(); ++p) {
|
||||
Particle & cp(parts[p]);
|
||||
//Vector3i obi = cp.bigChunkIndex(), oi = cp.chunkIndex();
|
||||
if (cp.processed) continue;
|
||||
cp.processed = true;
|
||||
cind = cp.chunkIndex();
|
||||
cp.process(near_parts);
|
||||
nind = cp.chunkIndex();
|
||||
if (nind == cind) continue;
|
||||
newBigChunk(cp.bigChunkIndex())->newChunk(nind)->particles << cp;
|
||||
parts.remove(p);
|
||||
--p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WaterSystem::Particle::process(const QList<QVector<Particle> * > & near_parts) {
|
||||
accel += Vector3d(0., 0., -0.98 / 60.) / mass;
|
||||
speed += accel;
|
||||
pos += speed;
|
||||
speed *= 0.95;
|
||||
GLfloat sm = speed.length();//piMax<GLfloat>(fabs(speed.x), fabs(speed.y), fabs(speed.z));
|
||||
if (sm > 0.2)
|
||||
speed.normalize() *= 0.2;
|
||||
if (pos.z - radius < 0.) {
|
||||
pos.z = radius;
|
||||
speed.z = -speed.z * 0.2;
|
||||
speed *= 0.9;
|
||||
accel.clear();
|
||||
}
|
||||
GLfloat sdist, srad, ssrad;
|
||||
Vector3d dpos;
|
||||
//return;
|
||||
/*int cnt = 0;
|
||||
foreach (QVector<Particle> * pl, near_parts)
|
||||
cnt += pl->size();
|
||||
qDebug() << cnt;*/
|
||||
foreach (QVector<Particle> * pl, near_parts) {
|
||||
QVector<Particle> & rpl(*pl);
|
||||
for (int i = 0; i < rpl.size(); ++i) {
|
||||
Particle & cp(rpl[i]);
|
||||
srad = radius + cp.radius;
|
||||
dpos = pos - cp.pos;
|
||||
if (fabs(dpos.x) >= srad || fabs(dpos.y) >= srad || fabs(dpos.z) >= srad) continue;
|
||||
ssrad = srad * srad;
|
||||
sdist = dpos.lengthSquared();
|
||||
if (sdist >= ssrad) continue;
|
||||
//continue;
|
||||
sdist = sqrt(sdist);
|
||||
ssrad = (srad - sdist) / 2;
|
||||
dpos *= ssrad / sdist;
|
||||
//pos += dpos;
|
||||
//cp.pos -= dpos;
|
||||
//qDebug() << "intersect" << sdist << (pos - cp.pos).length();
|
||||
speed -= speed.projectTo(dpos) * 2.;
|
||||
cp.speed -= cp.speed.projectTo(dpos) * 2.;
|
||||
speed *= 0.8;
|
||||
cp.speed *= 0.8;
|
||||
accel *= 0.8;
|
||||
cp.accel *= 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WaterSystem::draw(bool simplest) {
|
||||
//return;
|
||||
pass_ = GLObjectBase::Transparent;
|
||||
//qDebug() << "save states" << cv.size();
|
||||
glPointSize(20);
|
||||
GLfloat pp[] = {1.f, 1.f, 0.f};
|
||||
//glEnable(GL_BLEND);
|
||||
glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, pp);
|
||||
//glDepthMask(GL_FALSE);
|
||||
glNormal3f(0.f, 0.f, 1.f);
|
||||
//glEnable(GL_POINT_SPRITE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_VERTEX_ARRAY);
|
||||
//glDisable(GL_BLEND);
|
||||
//glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_NORMAL_ARRAY);
|
||||
glDisable(GL_COLOR_ARRAY);
|
||||
glDisable(GL_TEXTURE_COORD_ARRAY);
|
||||
double ha = 1. / (big_chunks.size() + 1.), ch = 0.;
|
||||
QVector<GLfloat> v;
|
||||
QList<BigChunk * > cv = big_chunks.values();
|
||||
part_count = 0;
|
||||
foreach (BigChunk * bc, cv) {
|
||||
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) {
|
||||
Chunk * cc = bc->chunks[i][j][k];
|
||||
if (cc == 0) continue;
|
||||
const QVector<Particle> & cp(cc->particles);
|
||||
part_count += cp.size();
|
||||
v.clear();
|
||||
foreach (const Particle & p, cp)
|
||||
v << p.pos.x << p.pos.y << p.pos.z;
|
||||
qglColor(QColor::fromHsvF(ch, 1., 1.));
|
||||
glVertexPointer(3, GL_FLOAT, 0, v.constData());
|
||||
glDrawArrays(GL_POINTS, 0, v.size() / 3);
|
||||
ch += ha;
|
||||
while (ch > 1.) ch -= 1.;
|
||||
}
|
||||
}
|
||||
qDebug() << "draw" << part_count << "water particles";
|
||||
//glDepthMask(GL_TRUE);
|
||||
/*if (!d_vertices.isEmpty()) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData());
|
||||
//glColorPointer(4, GL_FLOAT, 0, d_colors.constData());
|
||||
glNormalPointer(GL_FLOAT, 0, d_normals.constData());
|
||||
glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/
|
||||
/*if (pass_ == Reflection) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
}*/
|
||||
//}
|
||||
}
|
||||
Reference in New Issue
Block a user