ld33_umonster
diff src/dragon.cc @ 7:92d662deb66e
capsule distance seems broken
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 25 Aug 2015 00:38:00 +0300 |
parents | 3b4460b34d43 |
children | bed39534d471 |
line diff
1.1 --- a/src/dragon.cc Sun Aug 23 05:37:09 2015 +0300 1.2 +++ b/src/dragon.cc Tue Aug 25 00:38:00 2015 +0300 1.3 @@ -1,15 +1,60 @@ 1.4 #include <algorithm> 1.5 #include "opengl.h" 1.6 #include "dragon.h" 1.7 +#include "metasurf.h" 1.8 +#include "geom.h" 1.9 +#include "game.h" 1.10 +#include "shadow.h" 1.11 + 1.12 +#define VOXEL_PAD 1.0f 1.13 +#define DYN_FCOUNT 64 1.14 +#define DYN_VCOUNT (DYN_FCOUNT * 3) 1.15 + 1.16 +#define NUM_NECK_SEG 8 1.17 +static const float nseg_sizes[NUM_NECK_SEG][2] = { 1.18 + {1.0, 3.0}, {1.0, 1.5}, {1.5, 2.0}, {2.0, 2.5}, {2.5, 3.0}, {3.0, 3.5} 1.19 +}; 1.20 + 1.21 +static Vector3 bezier(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, float t); 1.22 +static float mseval(struct metasurface *ms, float x, float y, float z); 1.23 +static void msvertex(struct metasurface *ms, float x, float y, float z); 1.24 + 1.25 1.26 Dragon::Dragon() 1.27 : pos(0, 0, 0), dir(0, 0, -1), head_pos(0, 0, -1), target(0, 0, -2) 1.28 { 1.29 set_head_limits(-1, 1, -1, 1); 1.30 + 1.31 + glGenBuffers(1, &dyn_vbo); 1.32 + glBindBuffer(GL_ARRAY_BUFFER, dyn_vbo); 1.33 + glBufferData(GL_ARRAY_BUFFER, DYN_VCOUNT * sizeof(DynVertex), 0, GL_STREAM_DRAW); 1.34 + glBindBuffer(GL_ARRAY_BUFFER, 0); 1.35 + 1.36 + dyn_varr = new DynVertex[DYN_VCOUNT]; 1.37 + 1.38 + neck_seg_count = NUM_NECK_SEG; 1.39 + neck_seg = new Capsule[neck_seg_count]; 1.40 + 1.41 + for(int i=0; i<neck_seg_count; i++) { 1.42 + neck_seg[i].w[0] = nseg_sizes[i][0]; 1.43 + neck_seg[i].w[1] = nseg_sizes[i][1]; 1.44 + } 1.45 + 1.46 + msurf = msurf_create(); 1.47 + msurf_set_user_data(msurf, this); 1.48 + msurf_set_resolution(msurf, 36, 36, 36); 1.49 + msurf_set_threshold(msurf, 1.0); 1.50 + msurf_eval_func(msurf, mseval); 1.51 + msurf_vertex_func(msurf, msvertex); 1.52 } 1.53 1.54 Dragon::~Dragon() 1.55 { 1.56 + delete [] neck_seg; 1.57 + msurf_free(msurf); 1.58 + 1.59 + delete [] dyn_varr; 1.60 + glDeleteBuffers(1, &dyn_vbo); 1.61 } 1.62 1.63 void Dragon::set_position(const Vector3 &p) 1.64 @@ -71,8 +116,120 @@ 1.65 1.66 void Dragon::update() 1.67 { 1.68 + Vector3 bdir = breath_dir(); 1.69 + Vector3 bezcp[] = { pos, pos + dir * 6.0, head_pos - bdir * 8.0, head_pos }; 1.70 + 1.71 + float t = 0.0, dt = 1.0 / (float)(neck_seg_count + 1); 1.72 + Vector3 p = bezier(bezcp[0], bezcp[1], bezcp[2], bezcp[3], t); 1.73 + 1.74 + for(int i=0; i<neck_seg_count; i++) { 1.75 + t += dt; 1.76 + Vector3 pnext = bezier(bezcp[0], bezcp[1], bezcp[2], bezcp[3], t); 1.77 + 1.78 + neck_seg[i].p[0] = p; 1.79 + neck_seg[i].p[1] = pnext; 1.80 + 1.81 + p = pnext; 1.82 + } 1.83 } 1.84 1.85 +void Dragon::draw() const 1.86 +{ 1.87 + static float bmin[] = { head_xlim[0] - VOXEL_PAD * 0.9, head_ylim[0] - VOXEL_PAD, head_pos.z }; 1.88 + static float bmax[] = { head_xlim[1] + VOXEL_PAD * 0.9, head_ylim[1] + VOXEL_PAD * 2.1f, pos.z + VOXEL_PAD }; 1.89 + msurf_set_bounds(msurf, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2]); 1.90 + 1.91 + 1.92 + if(!shadow_pass) { 1.93 + 1.94 + if(dbg_wireframe) { 1.95 + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 1.96 + } 1.97 + 1.98 + dyn_vidx = 0; 1.99 + msurf_polygonize(msurf); 1.100 + flush_dynvbo(); 1.101 + 1.102 + if(dbg_wireframe) { 1.103 + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 1.104 + } 1.105 + 1.106 + int cur_sdr; 1.107 + glGetIntegerv(GL_CURRENT_PROGRAM, &cur_sdr); 1.108 + glUseProgram(0); 1.109 + 1.110 + glPushAttrib(GL_ENABLE_BIT); 1.111 + glDisable(GL_LIGHTING); 1.112 + 1.113 + // bounds 1.114 + glColor3f(1, 0, 0); 1.115 + glBegin(GL_LINE_LOOP); 1.116 + glVertex3f(bmin[0], bmin[1], bmin[2]); 1.117 + glVertex3f(bmax[0], bmin[1], bmin[2]); 1.118 + glVertex3f(bmax[0], bmax[1], bmin[2]); 1.119 + glVertex3f(bmin[0], bmax[1], bmin[2]); 1.120 + glEnd(); 1.121 + glBegin(GL_LINE_LOOP); 1.122 + glVertex3f(bmin[0], bmin[1], bmax[2]); 1.123 + glVertex3f(bmax[0], bmin[1], bmax[2]); 1.124 + glVertex3f(bmax[0], bmax[1], bmax[2]); 1.125 + glVertex3f(bmin[0], bmax[1], bmax[2]); 1.126 + glEnd(); 1.127 + glBegin(GL_LINE_LOOP); 1.128 + glVertex3f(bmin[0], bmax[1], bmin[2]); 1.129 + glVertex3f(bmax[0], bmax[1], bmin[2]); 1.130 + glVertex3f(bmax[0], bmax[1], bmax[2]); 1.131 + glVertex3f(bmin[0], bmax[1], bmax[2]); 1.132 + glEnd(); 1.133 + glBegin(GL_LINE_LOOP); 1.134 + glVertex3f(bmin[0], bmin[1], bmin[2]); 1.135 + glVertex3f(bmax[0], bmin[1], bmin[2]); 1.136 + glVertex3f(bmax[0], bmin[1], bmax[2]); 1.137 + glVertex3f(bmin[0], bmin[1], bmax[2]); 1.138 + glEnd(); 1.139 + 1.140 + // foo 1.141 + glDisable(GL_DEPTH_TEST); 1.142 + glEnable(GL_BLEND); 1.143 + glBlendFunc(GL_ONE, GL_ONE); 1.144 + glLineWidth(2.0); 1.145 + glColor3f(0, 0, 1); 1.146 + 1.147 + glBegin(GL_LINES); 1.148 + for(int i=0; i<neck_seg_count; i++) { 1.149 + glVertex3f(neck_seg[i].p[0].x, neck_seg[i].p[0].y, neck_seg[i].p[0].z); 1.150 + glVertex3f(neck_seg[i].p[1].x, neck_seg[i].p[1].y, neck_seg[i].p[1].z); 1.151 + } 1.152 + glEnd(); 1.153 + glLineWidth(1); 1.154 + 1.155 + // done debug drawing 1.156 + glPopAttrib(); 1.157 + if(cur_sdr) glUseProgram(cur_sdr); 1.158 + } 1.159 +} 1.160 + 1.161 +void Dragon::flush_dynvbo() const 1.162 +{ 1.163 + if(!dyn_vidx) return; 1.164 + 1.165 + glBindBuffer(GL_ARRAY_BUFFER, dyn_vbo); 1.166 + glBufferSubData(GL_ARRAY_BUFFER, 0, dyn_vidx * sizeof(DynVertex), dyn_varr); 1.167 + 1.168 + glEnableClientState(GL_VERTEX_ARRAY); 1.169 + glVertexPointer(3, GL_FLOAT, sizeof(DynVertex), (void*)offsetof(DynVertex, x)); 1.170 + glEnableClientState(GL_NORMAL_ARRAY); 1.171 + glNormalPointer(GL_FLOAT, sizeof(DynVertex), (void*)offsetof(DynVertex, nx)); 1.172 + glBindBuffer(GL_ARRAY_BUFFER, 0); 1.173 + 1.174 + glDrawArrays(GL_TRIANGLES, 0, dyn_vidx); 1.175 + 1.176 + glDisableClientState(GL_VERTEX_ARRAY); 1.177 + glDisableClientState(GL_NORMAL_ARRAY); 1.178 + dyn_vidx = 0; 1.179 +} 1.180 + 1.181 + 1.182 static Vector3 bezier(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, float t) 1.183 { 1.184 float x = bezier(a.x, b.x, c.x, d.x, t); 1.185 @@ -81,40 +238,48 @@ 1.186 return Vector3(x, y, z); 1.187 } 1.188 1.189 -void Dragon::draw() const 1.190 +static float mseval(struct metasurface *ms, float x, float y, float z) 1.191 { 1.192 - Vector3 bdir = breath_dir(); 1.193 - Vector3 bezcp[] = { pos, pos + dir * 6.0, head_pos - bdir * 8.0, head_pos }; 1.194 + Dragon *dragon = (Dragon*)msurf_get_user_data(ms); 1.195 1.196 - int cur_sdr; 1.197 - glGetIntegerv(GL_CURRENT_PROGRAM, &cur_sdr); 1.198 - glUseProgram(0); 1.199 + Vector3 pt = Vector3(x, y, z); 1.200 + Capsule *seg = dragon->neck_seg; 1.201 1.202 - glPushAttrib(GL_ENABLE_BIT); 1.203 - glDisable(GL_LIGHTING); 1.204 + //printf("eval(%g %g %g)\n", x, y, z); 1.205 1.206 - glLineWidth(2.0); 1.207 - glColor3f(0, 0, 1); 1.208 + float sum = 0.0f; 1.209 + for(int i=0; i<dragon->neck_seg_count; i++) { 1.210 + float dist = capsule_distance(seg[i].p[0], seg[i].w[0], seg[i].p[1], seg[i].w[1], pt); 1.211 + //float dist = sphere_distance(seg[i].p[0], 1.0, pt); 1.212 + if(dist < 1e-4) dist = 1e-4; 1.213 + float energy = 0.0001 / (dist * dist); 1.214 + /*float dx = x - seg[i].p[0].x; 1.215 + float dy = y - seg[i].p[0].y; 1.216 + float dz = z - seg[i].p[0].z; 1.217 + float energy = 0.5 / (dx * dx + dy * dy + dz * dz);*/ 1.218 + sum += energy; 1.219 + } 1.220 + return sum; 1.221 +} 1.222 1.223 - glBegin(GL_LINE_STRIP); 1.224 - for(int i=0; i<10; i++) { 1.225 - float t = (float)i / 10.0f; 1.226 - Vector3 p = bezier(bezcp[0], bezcp[1], bezcp[2], bezcp[3], t); 1.227 - glVertex3f(p.x, p.y, p.z); 1.228 +static void msvertex(struct metasurface *ms, float x, float y, float z) 1.229 +{ 1.230 + Dragon *dragon = (Dragon*)msurf_get_user_data(ms); 1.231 + 1.232 + const float dt = 0.001; 1.233 + float dfdx = mseval(ms, x - dt, y, z) - mseval(ms, x + dt, y, z); 1.234 + float dfdy = mseval(ms, x, y - dt, z) - mseval(ms, x, y + dt, z); 1.235 + float dfdz = mseval(ms, x, y, z - dt) - mseval(ms, x, y, z + dt); 1.236 + 1.237 + DynVertex *vptr = dragon->dyn_varr + dragon->dyn_vidx++; 1.238 + vptr->x = x; 1.239 + vptr->y = y; 1.240 + vptr->z = z; 1.241 + vptr->nx = dfdx; 1.242 + vptr->ny = dfdy; 1.243 + vptr->nz = dfdz; 1.244 + 1.245 + if(dragon->dyn_vidx >= DYN_VCOUNT) { 1.246 + dragon->flush_dynvbo(); 1.247 } 1.248 - glEnd(); 1.249 - glLineWidth(1); 1.250 - 1.251 - glPointSize(5.0); 1.252 - glColor3f(0, 1, 0); 1.253 - 1.254 - glBegin(GL_POINTS); 1.255 - for(int i=0; i<4; i++) { 1.256 - glVertex3f(bezcp[i].x, bezcp[i].y, bezcp[i].z); 1.257 - } 1.258 - glEnd(); 1.259 - 1.260 - glPopAttrib(); 1.261 - 1.262 - glUseProgram(cur_sdr); 1.263 }