nuclear@0: #include "opengl.h" nuclear@0: #include "board.h" nuclear@1: #include "meshgen.h" nuclear@0: nuclear@0: nuclear@0: Board::Board() nuclear@0: { nuclear@2: puck_obj = 0; nuclear@0: clear(); nuclear@0: } nuclear@0: nuclear@0: Board::~Board() nuclear@0: { nuclear@0: destroy(); nuclear@0: } nuclear@0: nuclear@0: bool Board::init() nuclear@0: { nuclear@4: if(!generate_textures()) { nuclear@4: return false; nuclear@4: } nuclear@1: if(!generate()) { nuclear@0: return false; nuclear@0: } nuclear@1: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void Board::destroy() nuclear@0: { nuclear@2: for(size_t i=0; idraw(); nuclear@1: } nuclear@0: } nuclear@0: nuclear@1: #define HSIZE 1.0 nuclear@1: #define VSIZE (2.0 * HSIZE) nuclear@1: #define BOT_THICKNESS (HSIZE * 0.01) nuclear@1: #define WALL_THICKNESS (HSIZE * 0.05) nuclear@1: #define WALL_HEIGHT (HSIZE * 0.1) nuclear@1: #define GAP (HSIZE * 0.025) nuclear@1: #define HINGE_RAD (GAP * 0.5) nuclear@1: #define HINGE_HEIGHT (VSIZE * 0.075) nuclear@1: nuclear@1: bool Board::generate() nuclear@0: { nuclear@4: Mesh tmp; nuclear@1: Matrix4x4 xform; nuclear@1: nuclear@2: obj.clear(); nuclear@2: nuclear@4: for(int i=0; i<2; i++) { nuclear@4: int sign = i * 2 - 1; nuclear@1: nuclear@4: // generate bottom nuclear@4: Mesh *bottom = new Mesh; nuclear@4: gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0); nuclear@4: xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0)); nuclear@4: bottom->apply_xform(xform); nuclear@2: nuclear@4: Object *obottom = new Object; nuclear@4: obottom->set_mesh(bottom); nuclear@4: obottom->xform().set_translation(Vector3(sign * (HSIZE / 2.0 + WALL_THICKNESS + HINGE_RAD * 0.25), 0, 0)); nuclear@4: obottom->set_texture(img_field.texture()); nuclear@4: obj.push_back(obottom); nuclear@2: nuclear@1: nuclear@4: // generate the 4 sides nuclear@4: Mesh *sides = new Mesh; nuclear@4: gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); nuclear@4: xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0, nuclear@4: WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); nuclear@4: sides->apply_xform(xform); nuclear@1: nuclear@4: gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); nuclear@4: xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0, nuclear@4: WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); nuclear@4: tmp.apply_xform(xform); nuclear@4: sides->append(tmp); nuclear@4: tmp.clear(); nuclear@1: nuclear@4: gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); nuclear@4: xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, nuclear@4: (VSIZE + WALL_THICKNESS) / 2.0)); nuclear@4: tmp.apply_xform(xform); nuclear@4: sides->append(tmp); nuclear@4: tmp.clear(); nuclear@1: nuclear@4: gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); nuclear@4: xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, nuclear@4: -(VSIZE + WALL_THICKNESS) / 2.0)); nuclear@4: tmp.apply_xform(xform); nuclear@4: sides->append(tmp); nuclear@4: tmp.clear(); nuclear@4: nuclear@4: Object *osides = new Object; nuclear@4: osides->set_mesh(sides); nuclear@4: osides->xform() = obottom->xform(); nuclear@4: obj.push_back(osides); nuclear@4: nuclear@4: } nuclear@2: nuclear@2: nuclear@1: // generate the hinges nuclear@1: Mesh *hinges = new Mesh; nuclear@1: gen_cylinder(hinges, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1); nuclear@4: xform.reset_identity(); nuclear@4: xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, VSIZE / 4.0)); nuclear@4: xform.rotate(Vector3(M_PI / 2.0, 0, 0)); nuclear@1: hinges->apply_xform(xform); nuclear@1: nuclear@1: gen_cylinder(&tmp, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1); nuclear@4: xform.reset_identity(); nuclear@4: xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, -VSIZE / 4.0)); nuclear@4: xform.rotate(Vector3(M_PI / 2.0, 0, 0)); nuclear@1: tmp.apply_xform(xform); nuclear@1: nuclear@1: hinges->append(tmp); nuclear@1: nuclear@2: Object *ohinges = new Object; nuclear@2: ohinges->set_mesh(hinges); nuclear@2: obj.push_back(ohinges); nuclear@1: nuclear@2: nuclear@1: return true; nuclear@0: } nuclear@4: nuclear@4: static bool spike(float x, float y) nuclear@4: { nuclear@4: x = fmod(x * 5.0, 1.0); nuclear@4: return y < (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x); nuclear@4: } nuclear@4: nuclear@4: static bool circle(float x, float y, float rad) nuclear@4: { nuclear@4: x = fmod(x * 5.0, 1.0) - 0.5; nuclear@4: y = (y - 0.65) * 5.0; nuclear@4: float len = sqrt(x * x + y * y); nuclear@4: return len < rad; nuclear@4: } nuclear@4: nuclear@4: static bool diamond(float x, float y) nuclear@4: { nuclear@4: return y >= (1.0 - (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x)) * 0.3333333 + 0.88; nuclear@4: } nuclear@4: nuclear@4: static bool center_circle(float x, float y, float rad) nuclear@4: { nuclear@4: x = x - 0.5; nuclear@4: y = 1.0 - y; nuclear@4: return sqrt(x * x + y * y) < rad; nuclear@4: } nuclear@4: nuclear@4: bool Board::generate_textures() nuclear@4: { nuclear@4: const int xsz = 512; nuclear@4: const int ysz = 1024; nuclear@4: nuclear@4: img_field.create(xsz, ysz); nuclear@4: clear_image(&img_field, 0, 0, 0); nuclear@4: nuclear@4: unsigned char *pptr = img_field.pixels; nuclear@4: nuclear@4: for(int i=0; i