tavli
diff src/board.cc @ 4:b41ceead1708
procedural playing field texture mask
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 25 Jun 2015 05:58:35 +0300 |
parents | 893192aea099 |
children | e48b40a3c82a |
line diff
1.1 --- a/src/board.cc Mon Jun 22 21:46:57 2015 +0300 1.2 +++ b/src/board.cc Thu Jun 25 05:58:35 2015 +0300 1.3 @@ -16,6 +16,9 @@ 1.4 1.5 bool Board::init() 1.6 { 1.7 + if(!generate_textures()) { 1.8 + return false; 1.9 + } 1.10 if(!generate()) { 1.11 return false; 1.12 } 1.13 @@ -57,65 +60,75 @@ 1.14 1.15 bool Board::generate() 1.16 { 1.17 + Mesh tmp; 1.18 Matrix4x4 xform; 1.19 1.20 obj.clear(); 1.21 1.22 - // generate bottom 1.23 - Mesh *bottom = new Mesh; 1.24 - gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0); 1.25 - xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0)); 1.26 - bottom->apply_xform(xform); 1.27 + for(int i=0; i<2; i++) { 1.28 + int sign = i * 2 - 1; 1.29 1.30 - Object *obottom = new Object; 1.31 - obottom->set_mesh(bottom); 1.32 - obj.push_back(obottom); 1.33 + // generate bottom 1.34 + Mesh *bottom = new Mesh; 1.35 + gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0); 1.36 + xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0)); 1.37 + bottom->apply_xform(xform); 1.38 1.39 + Object *obottom = new Object; 1.40 + obottom->set_mesh(bottom); 1.41 + obottom->xform().set_translation(Vector3(sign * (HSIZE / 2.0 + WALL_THICKNESS + HINGE_RAD * 0.25), 0, 0)); 1.42 + obottom->set_texture(img_field.texture()); 1.43 + obj.push_back(obottom); 1.44 1.45 - // generate the 4 sides 1.46 - Mesh *sides = new Mesh; 1.47 - gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); 1.48 - xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0, 1.49 - WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); 1.50 - sides->apply_xform(xform); 1.51 1.52 - Mesh tmp; 1.53 - gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); 1.54 - xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0, 1.55 - WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); 1.56 - tmp.apply_xform(xform); 1.57 - sides->append(tmp); 1.58 - tmp.clear(); 1.59 + // generate the 4 sides 1.60 + Mesh *sides = new Mesh; 1.61 + gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); 1.62 + xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0, 1.63 + WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); 1.64 + sides->apply_xform(xform); 1.65 1.66 - gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); 1.67 - xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, 1.68 - (VSIZE + WALL_THICKNESS) / 2.0)); 1.69 - tmp.apply_xform(xform); 1.70 - sides->append(tmp); 1.71 - tmp.clear(); 1.72 + gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); 1.73 + xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0, 1.74 + WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); 1.75 + tmp.apply_xform(xform); 1.76 + sides->append(tmp); 1.77 + tmp.clear(); 1.78 1.79 - gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); 1.80 - xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, 1.81 - -(VSIZE + WALL_THICKNESS) / 2.0)); 1.82 - tmp.apply_xform(xform); 1.83 - sides->append(tmp); 1.84 - tmp.clear(); 1.85 + gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); 1.86 + xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, 1.87 + (VSIZE + WALL_THICKNESS) / 2.0)); 1.88 + tmp.apply_xform(xform); 1.89 + sides->append(tmp); 1.90 + tmp.clear(); 1.91 1.92 - Object *osides = new Object; 1.93 - osides->set_mesh(sides); 1.94 - obj.push_back(osides); 1.95 + gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); 1.96 + xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, 1.97 + -(VSIZE + WALL_THICKNESS) / 2.0)); 1.98 + tmp.apply_xform(xform); 1.99 + sides->append(tmp); 1.100 + tmp.clear(); 1.101 + 1.102 + Object *osides = new Object; 1.103 + osides->set_mesh(sides); 1.104 + osides->xform() = obottom->xform(); 1.105 + obj.push_back(osides); 1.106 + 1.107 + } 1.108 1.109 1.110 // generate the hinges 1.111 Mesh *hinges = new Mesh; 1.112 gen_cylinder(hinges, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1); 1.113 - xform.set_rotation(Vector3(M_PI / 2.0, 0, 0)); 1.114 - xform.translate(Vector3(0, VSIZE / 4.0, 0)); 1.115 + xform.reset_identity(); 1.116 + xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, VSIZE / 4.0)); 1.117 + xform.rotate(Vector3(M_PI / 2.0, 0, 0)); 1.118 hinges->apply_xform(xform); 1.119 1.120 gen_cylinder(&tmp, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1); 1.121 - xform.set_rotation(Vector3(M_PI / 2.0, 0, 0)); 1.122 - xform.translate(Vector3(0, -VSIZE / 4.0, 0)); 1.123 + xform.reset_identity(); 1.124 + xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, -VSIZE / 4.0)); 1.125 + xform.rotate(Vector3(M_PI / 2.0, 0, 0)); 1.126 tmp.apply_xform(xform); 1.127 1.128 hinges->append(tmp); 1.129 @@ -127,3 +140,73 @@ 1.130 1.131 return true; 1.132 } 1.133 + 1.134 +static bool spike(float x, float y) 1.135 +{ 1.136 + x = fmod(x * 5.0, 1.0); 1.137 + return y < (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x); 1.138 +} 1.139 + 1.140 +static bool circle(float x, float y, float rad) 1.141 +{ 1.142 + x = fmod(x * 5.0, 1.0) - 0.5; 1.143 + y = (y - 0.65) * 5.0; 1.144 + float len = sqrt(x * x + y * y); 1.145 + return len < rad; 1.146 +} 1.147 + 1.148 +static bool diamond(float x, float y) 1.149 +{ 1.150 + return y >= (1.0 - (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x)) * 0.3333333 + 0.88; 1.151 +} 1.152 + 1.153 +static bool center_circle(float x, float y, float rad) 1.154 +{ 1.155 + x = x - 0.5; 1.156 + y = 1.0 - y; 1.157 + return sqrt(x * x + y * y) < rad; 1.158 +} 1.159 + 1.160 +bool Board::generate_textures() 1.161 +{ 1.162 + const int xsz = 512; 1.163 + const int ysz = 1024; 1.164 + 1.165 + img_field.create(xsz, ysz); 1.166 + clear_image(&img_field, 0, 0, 0); 1.167 + 1.168 + unsigned char *pptr = img_field.pixels; 1.169 + 1.170 + for(int i=0; i<ysz; i++) { 1.171 + float v = (float)i / (float)ysz; 1.172 + 1.173 + for(int j=0; j<xsz; j++) { 1.174 + float u = (float)j / (float)xsz; 1.175 + 1.176 + int r = 0, g = 0, b = 0; 1.177 + 1.178 + float x = u; 1.179 + float y = v < 0.5 ? v * 2.0 : 2.0 - v * 2.0; 1.180 + bool inside = false; 1.181 + 1.182 + inside |= (spike(x, y + 0.33333) && !spike(x, y + 0.4)) || 1.183 + (spike(x, y + 0.5) && !spike(x, y + 0.68)); 1.184 + inside |= (circle(x, y, 0.12) && !circle(x, y, 0.1)) || circle(x, y, 0.06); 1.185 + inside |= (diamond(x, y) && !diamond(x, y - 0.015)) || 1.186 + (diamond(x, y - 0.023) && !diamond(x, y - 0.028)); 1.187 + inside |= center_circle(x, y, 0.03); 1.188 + 1.189 + if(inside) { 1.190 + r = g = b = 255; 1.191 + } 1.192 + 1.193 + pptr[0] = r; 1.194 + pptr[1] = g; 1.195 + pptr[2] = b; 1.196 + pptr += 3; 1.197 + } 1.198 + } 1.199 + 1.200 + img_field.texture(); 1.201 + return true; 1.202 +}