From 02ec6e3ff5ebd73f8dde3a00737452a7c47755d3 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Thu, 22 Mar 2018 18:18:20 +0200 Subject: [PATCH] procedural generator for the steam tunnels part --- tools/procgen/steamtun.cc | 264 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 tools/procgen/steamtun.cc diff --git a/tools/procgen/steamtun.cc b/tools/procgen/steamtun.cc new file mode 100644 index 0000000..e610cd8 --- /dev/null +++ b/tools/procgen/steamtun.cc @@ -0,0 +1,264 @@ +//#define BASE_STR +#define BASE_LEFTJ +//#define RIGHT_STR1 +#define RIGHT_STR2 +//#define LEFT_STR1 +//#define LEFT_STR2 +//#define LEFT_STR3 +//#define LEFT_STR4 + +#define CON_RAD(r) ((r) * 1.4) +#define CON_WIDTH 0.04 + +static Object *gen_base_straight(); +static Object *gen_base_left_junction(); +static Object *gen_base_right_junction(); +static Object *gen_pipeworks(); +static Object *gen_pipe(float x, float y, float rad); +static Object *gen_pipe_inwall(float x, float y, float rad); +static Object *gen_pipe_s(float x, float y0, float y1, float rad); + +static Mat4 xform; + +#define add_object(o) \ + do { \ + Object *tmp = o; \ + if(head) { \ + tail->next = tmp; \ + tail = tmp; \ + } else { \ + head = tail = tmp; \ + } \ + while(tail->next) tail = tail->next; \ + } while(0) + +extern "C" Object *generate() +{ + Object *head = 0, *tail = 0; + +#ifdef BASE_STR + add_object(gen_base_straight()); +#endif +#ifdef BASE_LEFTJ + add_object(gen_base_left_junction()); +#endif + add_object(gen_pipeworks()); + return head; +} + +static Object *gen_base_straight() +{ + Object *owalls = new Object; + owalls->mesh = new Mesh; + gen_box(owalls->mesh, -1, -2, -1, 1, 2); + + xform.rotation_x(deg_to_rad(90)); + owalls->mesh->apply_xform(xform); + + owalls->mesh->remove_faces(16, 23); + + xform.translation(0, 0.5, 0); + owalls->mesh->apply_xform(xform); + + return owalls; +} + +static Object *gen_base_left_junction() +{ + Mesh tmp; + + Object *obj = new Object; + obj->mesh = new Mesh; + + gen_box(obj->mesh, -1, -2, -1, 1, 3); + + xform.rotation_x(deg_to_rad(90)); + xform.translate(0, 0.5, 0); + obj->mesh->apply_xform(xform); + + obj->mesh->remove_faces(24, 35); + obj->mesh->remove_faces(6, 11); + + for(int i=0; i<2; i++) { + float sign = i == 0 ? 1.0f : -1.0f; + gen_plane(&tmp, 0.5, 1, 1, 1); + xform.rotation_y(deg_to_rad(90)); + xform.translate(-0.5, 0.5, sign * 0.75); + tmp.apply_xform(xform); + obj->mesh->append(tmp); + } + + gen_box(&tmp, -1, -0.5, -1, 1, 1); + xform.rotation_z(deg_to_rad(90)); + xform.translate(-0.75, 0.5, 0); + tmp.apply_xform(xform); + + tmp.remove_faces(8, 11); + + obj->mesh->append(tmp); + + return obj; +} + +static Object *gen_pipeworks() +{ + Object *head = 0, *tail = 0; + + float start_y = CON_RAD(0.08) + 0.01; + +#if defined(RIGHT_STR1) || defined(RIGHT_STR2) + add_object(gen_pipe(0.5 - 0.08, start_y, 0.08)); +#endif + start_y += (CON_RAD(0.08) + CON_RAD(0.05)) * 0.9; + + for(int i=0; i<3; i++) { + float x = 0.5 - CON_RAD(0.05); + float y = start_y + i * (CON_RAD(0.05) * 1.8); + +#ifdef RIGHT_STR2 + if(i == 1) { + add_object(gen_pipe_inwall(x, y, 0.05)); + } else { + add_object(gen_pipe(x, y, 0.05)); + } +#endif +#ifdef RIGHT_STR1 + add_object(gen_pipe(x, y, 0.05)); +#endif + } + +#if defined(LEFT_STR1) || defined(LEFT_STR2) || defined(LEFT_STR3) || defined(LEFT_STR4) + //add_object(gen_pipe(-0.5 + 0.08, start_y, 0.08)); + add_object(gen_pipe(-0.5 + CON_RAD(0.05), 0.8, 0.05)); +#endif +#ifdef LEFT_STR1 + add_object(gen_pipe(-0.5 + CON_RAD(0.05), 0.68, 0.05)); +#endif +#ifdef LEFT_STR2 + add_object(gen_pipe(-0.5 + CON_RAD(0.05), 0.3, 0.05)); +#endif +#ifdef LEFT_STR3 + add_object(gen_pipe_s(-0.5 + CON_RAD(0.05), 0.3, 0.67, 0.05)); +#endif +#ifdef LEFT_STR4 + add_object(gen_pipe_s(-0.5 + CON_RAD(0.05), 0.67, 0.3, 0.05)); +#endif + return head; +} + +static Object *gen_pipe(float x, float y, float rad) +{ + Object *opipe = new Object; + opipe->mesh = new Mesh; + + + for(int i=0; i<2; i++) { + Mesh tmp; + + float pipelen = 1 - CON_WIDTH * 2; + gen_cylinder(&tmp, rad, pipelen, 6, 1); + xform.translation(0, i - pipelen / 2 - CON_WIDTH, 0); + tmp.apply_xform(xform); + opipe->mesh->append(tmp); + + gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1); + xform.translation(0, 1 - i - CON_WIDTH / 2, 0); + tmp.apply_xform(xform); + opipe->mesh->append(tmp); + + gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1); + xform.translation(0, 1 - i - CON_WIDTH * 1.5 - pipelen, 0); + tmp.apply_xform(xform); + opipe->mesh->append(tmp); + } + + xform.rotation_x(deg_to_rad(90)); + opipe->mesh->apply_xform(xform); + opipe->xform.translation(x, y, 0); + + return opipe; +} + +static Object *gen_pipe_inwall(float x, float y, float rad) +{ + Object *opipe = new Object; + opipe->mesh = new Mesh; + + const float pipelen = 0.2; + float zoffs = 1.0 - pipelen - CON_WIDTH; + + for(int i=0; i<2; i++) { + Mesh tmp; + float sign = i == 0 ? 1.0f : -1.0f; + + gen_torus(&tmp, rad * 2.0, rad, 4, 7, 0.25); + xform = Mat4::identity; + if(i > 0) xform.rotate_y(deg_to_rad(90)); + xform.translate(rad * 2.0, 0, sign * zoffs); + tmp.apply_xform(xform); + opipe->mesh->append(tmp); + + gen_cylinder(&tmp, rad, pipelen, 7, 1); + xform.rotation_x(deg_to_rad(90)); + xform.rotate_z(deg_to_rad(90)); + xform.translate(0, 0, sign * (zoffs + pipelen / 2.0)); + tmp.apply_xform(xform); + opipe->mesh->append(tmp); + + gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1); + xform.rotation_x(deg_to_rad(90)); + xform.translate(0, 0, sign * (1 - CON_WIDTH / 2.0)); + tmp.apply_xform(xform); + opipe->mesh->append(tmp); + } + + opipe->xform.translation(x, y, 0); + + return opipe; +} + +static Object *gen_pipe_s(float x, float y0, float y1, float rad) +{ + Mesh tmp; + float dist = fabs(y0 - y1); + float pipelen = 1.0f - rad * 2.0 - CON_WIDTH / 2.0; + + Object *obj = new Object; + obj->mesh = new Mesh; + + for(int i=0; i<2; i++) { + float zsign = i == 0 ? 1.0f : -1.0f; + float ysign = zsign * (y0 > y1 ? 1.0f : -1.0f); + + gen_torus(&tmp, rad * 2.0, rad, 4, 6, 0.25); + xform.rotation_z(deg_to_rad(90) * ysign); + if(i != 0) xform.rotate_x(deg_to_rad(y0 < y1 ? -90 : 90)); + xform.translate(0, ysign * (-dist / 2.0 + rad * 2.0), zsign * rad * 2.0); + tmp.apply_xform(xform); + obj->mesh->append(tmp); + + gen_cylinder(&tmp, rad, pipelen, 6, 1); + xform.rotation_x(deg_to_rad(90)); + xform.translate(0, ysign * -dist / 2.0, zsign * (pipelen / 2.0 + rad * 2.0)); + tmp.apply_xform(xform); + obj->mesh->append(tmp); + + gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1); + xform.rotation_x(deg_to_rad(90)); + xform.translate(0, ysign * -dist / 2.0, zsign * (1 - CON_WIDTH / 2.0)); + tmp.apply_xform(xform); + obj->mesh->append(tmp); + + gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1); + xform.rotation_x(deg_to_rad(90)); + xform.translate(0, ysign * -dist / 2.0, zsign * (rad * 2.0 + CON_WIDTH / 2.0)); + tmp.apply_xform(xform); + obj->mesh->append(tmp); + } + + gen_cylinder(&tmp, rad, dist - rad * 4.0, 6, 1); + obj->mesh->append(tmp); + + obj->xform.translation(x, (y0 + y1) / 2.0, 0); + return obj; +} -- 1.7.10.4