dbf-udg
view src/mballs.cc @ 14:5be16862d1b5
minor makefile modifications
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 20 Feb 2013 05:54:36 +0200 |
parents | 1abbed71e9c9 |
children |
line source
1 /*
2 Printblobs - halftoning display hack
3 Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <vector>
19 #include <math.h>
20 #include "opengl.h"
21 #include "mballs.h"
22 #include "metasurf.h"
23 #include "dsys.h"
24 #include "udg.h"
26 struct MetaBall {
27 float pos[3];
28 float orbit;
29 float energy;
30 float phase_offs;
31 };
33 #define VOL_SZ 2
34 #define MBALL_GRID_SZ 50
36 static void update(float sec);
37 static float calc_field(float x, float y, float z);
38 static float eval(float x, float y, float z);
39 static void vertex(float x, float y, float z);
40 static void normal(float x, float y, float z);
42 static float grid[MBALL_GRID_SZ][MBALL_GRID_SZ][MBALL_GRID_SZ];
43 static std::vector<MetaBall> balls;
44 static struct metasurface *msurf;
45 static float floor_height = -0.95;
47 static struct dsys_event *evrise;
49 bool mball_init()
50 {
51 static const float bbmin = -VOL_SZ / 2.0;
52 static const float bbmax = VOL_SZ / 2.0;
54 if(!(msurf = msurf_create())) {
55 return false;
56 }
57 msurf_threshold(msurf, 10);
58 msurf_resolution(msurf, MBALL_GRID_SZ, MBALL_GRID_SZ, MBALL_GRID_SZ);
59 msurf_bounds(msurf, bbmin, bbmin, bbmin, bbmax, bbmax, bbmax);
60 msurf_eval_func(msurf, eval);
61 msurf_vertex_func(msurf, vertex);
62 //msurf_normal_func(msurf, normal);
64 for(int i=0; i<10; i++) {
65 MetaBall mb;
66 mb.orbit = 0.25 * rand() / (float)RAND_MAX + 0.35;
67 mb.energy = 0.1 * rand() / (float)RAND_MAX + 0.15;
68 mb.phase_offs = rand() / (float)RAND_MAX * M_PI * 2.0;
69 balls.push_back(mb);
70 }
72 evrise = dsys_event(demo, "mball_rise");
73 dsys_set_event_eval(evrise, dsys_eval_sigmoid);
75 return true;
76 }
78 void mball_render(float sec)
79 {
80 update(sec);
82 const float blue[] = {0.4, 0.45, 1.0, 1};
83 const float dark_red[] = {0.6, 0.2, 0.1, 1};
84 const float white[] = {1, 1, 1, 1};
85 const float black[] = {0, 0, 0, 1};
87 glMatrixMode(GL_MODELVIEW);
88 glPushMatrix();
89 glScalef(4.0, 4.0, 4.0);
91 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
92 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
93 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 80.0);
95 glBegin(GL_TRIANGLES);
96 msurf_polygonize(msurf);
97 glEnd();
99 // floor
100 glBegin(GL_QUADS);
101 glNormal3f(0, 1, 0);
102 glVertex3f(-5, -1, 5);
103 glVertex3f(5, -1, 5);
104 glVertex3f(5, -1, -5);
105 glVertex3f(-5, -1, -5);
106 glEnd();
108 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dark_red);
109 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
110 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 80.0);
112 // box
113 glPushMatrix();
114 glTranslatef(0, -1.7, 1);
115 glScalef(1.05, 1, 0.05);
116 glutSolidCube(2.0);
117 glPopMatrix();
119 glPushMatrix();
120 glTranslatef(0, -1.7, -1);
121 glScalef(1.05, 1, 0.05);
122 glutSolidCube(2.0);
123 glPopMatrix();
125 glPushMatrix();
126 glTranslatef(1, -1.7, 0);
127 glScalef(0.05, 1, 1);
128 glutSolidCube(2.0);
129 glPopMatrix();
131 glPushMatrix();
132 glTranslatef(-1, -1.7, 0);
133 glScalef(0.05, 1, 1);
134 glutSolidCube(2.0);
135 glPopMatrix();
137 glPopMatrix();
138 }
141 static void update(float sec)
142 {
143 float trise = dsys_event_value(evrise);
145 for(size_t i=0; i<balls.size(); i++) {
146 float t = sec + balls[i].phase_offs;
147 balls[i].pos[0] = cos(t * 1.8) * balls[i].orbit;
148 balls[i].pos[2] = sin(t * 1.2) * balls[i].orbit;
149 balls[i].pos[1] = (sin(t) + cos(t * 2.0) / 2.0 + sin(t * 3.0) / 3.0) * 0.45 - (2.0 - trise * 2.0);
150 }
152 for(int i=0; i<MBALL_GRID_SZ; i++) {
153 float x = (float)i / (float)MBALL_GRID_SZ * 2.0 - 1.0;
154 for(int j=0; j<MBALL_GRID_SZ; j++) {
155 float y = (float)j / (float)MBALL_GRID_SZ * 2.0 - 1.0;
156 for(int k=0; k<MBALL_GRID_SZ; k++) {
157 float z = (float)k / (float)MBALL_GRID_SZ * 2.0 - 1.0;
158 grid[i][j][k] = calc_field(x, y, z);
159 }
160 }
161 }
162 }
164 static float calc_field(float x, float y, float z)
165 {
166 float sum = 0.0f;
167 for(size_t i=0; i<balls.size(); i++) {
168 float dx = balls[i].pos[0] - x;
169 float dy = balls[i].pos[1] - y;
170 float dz = balls[i].pos[2] - z;
171 float dist_sq = dx * dx + dy * dy + dz * dz;
172 if(dist_sq > 1e-6) {
173 sum += balls[i].energy / dist_sq;
174 } else {
175 sum += 1000.0;
176 }
177 }
179 // floor
180 float height = y - floor_height;
181 if(height > 1e-6) {
182 sum += 1.0 / height;
183 } else {
184 sum += 1000.0;
185 }
187 return sum;
188 }
190 static inline int clamp(int x, int a, int b)
191 {
192 return x < a ? a : (x > b ? b : x);
193 }
195 static float eval(float x, float y, float z)
196 {
197 int cell_x = clamp((int)((x / VOL_SZ + 0.5) * MBALL_GRID_SZ), 0, MBALL_GRID_SZ - 1);
198 int cell_y = clamp((int)((y / VOL_SZ + 0.5) * MBALL_GRID_SZ), 0, MBALL_GRID_SZ - 1);
199 int cell_z = clamp((int)((z / VOL_SZ + 0.5) * MBALL_GRID_SZ), 0, MBALL_GRID_SZ - 1);
201 return grid[cell_x][cell_y][cell_z];
202 }
204 static void vertex(float x, float y, float z)
205 {
206 float delta = (float)VOL_SZ / (float)MBALL_GRID_SZ;
208 float dfdx = calc_field(x - delta, y, z) - calc_field(x + delta, y, z);
209 float dfdy = calc_field(x, y - delta, z) - calc_field(x, y + delta, z);
210 float dfdz = calc_field(x, y, z - delta) - calc_field(x, y, z + delta);
212 float len = sqrt(dfdx * dfdx + dfdy * dfdy + dfdz * dfdz);
214 glNormal3f(dfdx / len, dfdy / len, dfdz / len);
215 glVertex3f(x, y, z);
216 }
218 static void normal(float x, float y, float z)
219 {
220 glNormal3f(x, y, z);
221 }