17 #define CON_RAD(r) ((r) * 1.4)
18 #define CON_WIDTH 0.04
20 static Object *gen_base_straight();
21 static Object *gen_base_left_junction();
22 static Object *gen_base_right_junction();
23 static Object *gen_pipeworks();
24 static Object *gen_pipe(float x, float y, float rad);
25 static Object *gen_pipe_inwall(float x, float y, float rad);
26 static Object *gen_pipe_s(float x, float y0, float y1, float rad);
27 static Object *gen_pipe_corner(float x, float y, float z, float rad);
31 #define add_object(o) \
40 while(tail->next) tail = tail->next; \
43 extern "C" Object *generate()
45 Object *head = 0, *tail = 0;
48 add_object(gen_base_straight());
51 add_object(gen_base_left_junction());
53 add_object(gen_pipeworks());
57 static Object *gen_base_straight()
59 Object *owalls = new Object;
60 owalls->mesh = new Mesh;
61 gen_box(owalls->mesh, -1, -2, -1, 1, 2);
63 xform.rotation_x(deg_to_rad(90));
64 owalls->mesh->apply_xform(xform);
66 owalls->mesh->remove_faces(16, 23);
68 xform.translation(0, 0.5, 0);
69 owalls->mesh->apply_xform(xform);
74 static Object *gen_base_left_junction()
78 Object *obj = new Object;
81 gen_box(obj->mesh, -1, -2, -1, 1, 3);
83 xform.rotation_x(deg_to_rad(90));
84 xform.translate(0, 0.5, 0);
85 obj->mesh->apply_xform(xform);
87 obj->mesh->remove_faces(24, 35);
88 obj->mesh->remove_faces(6, 11);
90 for(int i=0; i<2; i++) {
91 float sign = i == 0 ? 1.0f : -1.0f;
92 gen_plane(&tmp, 0.5, 1, 1, 1);
93 xform.rotation_y(deg_to_rad(90));
94 xform.translate(-0.5, 0.5, sign * 0.75);
95 tmp.apply_xform(xform);
96 obj->mesh->append(tmp);
99 gen_box(&tmp, -1, -0.5, -1, 1, 1);
100 xform.rotation_z(deg_to_rad(90));
101 xform.translate(-0.75, 0.5, 0);
102 tmp.apply_xform(xform);
104 tmp.remove_faces(8, 11);
106 obj->mesh->append(tmp);
111 static Object *gen_pipeworks()
113 Object *head = 0, *tail = 0;
115 // --- right straight pipes ---
116 float start_y = CON_RAD(FAT_RAD) + 0.01;
118 #if defined(RIGHT_STR1) || defined(RIGHT_STR2)
119 add_object(gen_pipe(0.5 - FAT_RAD, start_y, FAT_RAD));
121 start_y += (CON_RAD(FAT_RAD) + CON_RAD(STD_RAD)) * 0.9;
123 for(int i=0; i<3; i++) {
124 float x = 0.5 - CON_RAD(STD_RAD);
125 float y = start_y + i * (CON_RAD(STD_RAD) * 1.8);
129 add_object(gen_pipe_inwall(x, y, STD_RAD));
131 add_object(gen_pipe(x, y, STD_RAD));
135 add_object(gen_pipe(x, y, STD_RAD));
139 // --- left straight pipes ---
140 #if defined(LEFT_STR1) || defined(LEFT_STR2) || defined(LEFT_STR3) || defined(LEFT_STR4)
141 //add_object(gen_pipe(-0.5 + FAT_RAD, start_y, FAT_RAD));
142 add_object(gen_pipe(-0.5 + CON_RAD(STD_RAD), 0.8, STD_RAD));
145 add_object(gen_pipe(-0.5 + CON_RAD(STD_RAD), 0.68, STD_RAD));
148 add_object(gen_pipe(-0.5 + CON_RAD(STD_RAD), 0.3, STD_RAD));
151 add_object(gen_pipe_s(-0.5 + CON_RAD(STD_RAD), 0.3, 0.67, STD_RAD));
154 add_object(gen_pipe_s(-0.5 + CON_RAD(STD_RAD), 0.68, 0.3, STD_RAD));
157 // --- left junction pipes ---
158 #if defined(LEFT_J1) || defined(LEFT_J2) || defined(LEFT_J3) || defined(LEFT_J4)
159 add_object(gen_pipe_corner(-0.5, 0.8, 0.5, STD_RAD));
160 add_object(gen_pipe_corner(-0.5, 0.8, -0.5, STD_RAD));
163 add_object(gen_pipe_corner(-0.5, 0.68, 0.5, STD_RAD));
164 add_object(gen_pipe_corner(-0.5, 0.68, -0.5, STD_RAD));
167 add_object(gen_pipe_corner(-0.5, 0.3, 0.5, STD_RAD));
168 add_object(gen_pipe_corner(-0.5, 0.3, -0.5, STD_RAD));
171 add_object(gen_pipe_corner(-0.5, 0.3, 0.5, STD_RAD));
172 add_object(gen_pipe_corner(-0.5, 0.68, -0.5, STD_RAD));
175 add_object(gen_pipe_corner(-0.5, 0.68, 0.5, STD_RAD));
176 add_object(gen_pipe_corner(-0.5, 0.3, -0.5, STD_RAD));
181 static Object *gen_pipe(float x, float y, float rad)
183 Object *opipe = new Object;
184 opipe->mesh = new Mesh;
187 for(int i=0; i<2; i++) {
190 float pipelen = 1 - CON_WIDTH * 2;
191 gen_cylinder(&tmp, rad, pipelen, 6, 1);
192 xform.translation(0, i - pipelen / 2 - CON_WIDTH, 0);
193 tmp.apply_xform(xform);
194 opipe->mesh->append(tmp);
196 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
197 xform.translation(0, 1 - i - CON_WIDTH / 2, 0);
198 tmp.apply_xform(xform);
199 opipe->mesh->append(tmp);
201 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
202 xform.translation(0, 1 - i - CON_WIDTH * 1.5 - pipelen, 0);
203 tmp.apply_xform(xform);
204 opipe->mesh->append(tmp);
207 xform.rotation_x(deg_to_rad(90));
208 opipe->mesh->apply_xform(xform);
209 opipe->xform.translation(x, y, 0);
214 static Object *gen_pipe_inwall(float x, float y, float rad)
216 Object *opipe = new Object;
217 opipe->mesh = new Mesh;
219 const float pipelen = 0.2;
220 float zoffs = 1.0 - pipelen - CON_WIDTH;
222 for(int i=0; i<2; i++) {
224 float sign = i == 0 ? 1.0f : -1.0f;
226 gen_torus(&tmp, rad * 2.0, rad, 4, 7, 0.25);
227 xform = Mat4::identity;
228 if(i > 0) xform.rotate_y(deg_to_rad(90));
229 xform.translate(rad * 2.0, 0, sign * zoffs);
230 tmp.apply_xform(xform);
231 opipe->mesh->append(tmp);
233 gen_cylinder(&tmp, rad, pipelen, 7, 1);
234 xform.rotation_x(deg_to_rad(90));
235 xform.rotate_z(deg_to_rad(90));
236 xform.translate(0, 0, sign * (zoffs + pipelen / 2.0));
237 tmp.apply_xform(xform);
238 opipe->mesh->append(tmp);
240 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
241 xform.rotation_x(deg_to_rad(90));
242 xform.translate(0, 0, sign * (1 - CON_WIDTH / 2.0));
243 tmp.apply_xform(xform);
244 opipe->mesh->append(tmp);
247 opipe->xform.translation(x, y, 0);
252 static Object *gen_pipe_s(float x, float y0, float y1, float rad)
255 float dist = fabs(y0 - y1);
256 float pipelen = 1.0f - rad * 2.0 - CON_WIDTH / 2.0;
258 Object *obj = new Object;
259 obj->mesh = new Mesh;
261 for(int i=0; i<2; i++) {
262 float zsign = i == 0 ? 1.0f : -1.0f;
263 float ysign = zsign * (y0 > y1 ? 1.0f : -1.0f);
265 gen_torus(&tmp, rad * 2.0, rad, 4, 6, 0.25);
266 xform.rotation_z(deg_to_rad(90) * ysign);
267 if(i != 0) xform.rotate_x(deg_to_rad(y0 < y1 ? -90 : 90));
268 xform.translate(0, ysign * (-dist / 2.0 + rad * 2.0), zsign * rad * 2.0);
269 tmp.apply_xform(xform);
270 obj->mesh->append(tmp);
272 gen_cylinder(&tmp, rad, pipelen, 6, 1);
273 xform.rotation_x(deg_to_rad(90));
274 xform.translate(0, ysign * -dist / 2.0, zsign * (pipelen / 2.0 + rad * 2.0));
275 tmp.apply_xform(xform);
276 obj->mesh->append(tmp);
278 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
279 xform.rotation_x(deg_to_rad(90));
280 xform.translate(0, ysign * -dist / 2.0, zsign * (1 - CON_WIDTH / 2.0));
281 tmp.apply_xform(xform);
282 obj->mesh->append(tmp);
284 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
285 xform.rotation_x(deg_to_rad(90));
286 xform.translate(0, ysign * -dist / 2.0, zsign * (rad * 2.0 + CON_WIDTH / 2.0));
287 tmp.apply_xform(xform);
288 obj->mesh->append(tmp);
291 gen_cylinder(&tmp, rad, dist - rad * 4.0, 6, 1);
292 obj->mesh->append(tmp);
294 obj->xform.translation(x, (y0 + y1) / 2.0, 0);
298 static Object *gen_pipe_corner(float x, float y, float z, float rad)
301 Object *obj = new Object;
302 obj->mesh = new Mesh;
304 float xoffs = CON_RAD(rad);
305 float pipelen = 0.5 - CON_WIDTH - (rad * 2.0 - xoffs + CON_WIDTH);
307 float sign = z >= 0.0f ? 1.0f : -1.0f;
309 gen_torus(&tmp, rad * 2.0, rad, 4, 6, 0.25);
310 xform.rotation_y(deg_to_rad(sign >= 0.0f ? -90 : 180));
311 xform.translate(xoffs - rad * 2.0, 0, sign * (0.5 + rad * 2.0 - xoffs));
312 tmp.apply_xform(xform);
313 obj->mesh->append(tmp);
315 for(int i=0; i<2; i++) {
317 gen_cylinder(&tmp, rad, pipelen, 6, 1);
318 xform.rotation_x(deg_to_rad(90));
319 xform.rotate_z(deg_to_rad(90));
320 xform.translate(xoffs, 0, sign * (1 - pipelen / 2 - CON_WIDTH));
321 tmp.apply_xform(xform);
324 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
325 xform.rotation_x(deg_to_rad(90));
326 xform.translate(xoffs, 0, sign * (1 - CON_WIDTH / 2));
327 tmp.apply_xform(xform);
330 gen_cylinder(&tmp, CON_RAD(rad), CON_WIDTH, 7, 1, 1);
331 xform.rotation_x(deg_to_rad(90));
332 xform.translate(xoffs, 0, sign * (0.5 + rad * 2.0 - xoffs + CON_WIDTH / 2.0));
333 tmp.apply_xform(xform);
337 xform = Mat4::identity;
338 xform.translate(-xoffs, 0, sign * -0.5);
339 xform.rotate_y(deg_to_rad(sign * -90));
340 xform.translate(xoffs, 0, sign * 0.5);
341 xform.translate(-xoffs, 0, sign * -xoffs);
342 pipe.apply_xform(xform);
345 obj->mesh->append(pipe);
348 obj->xform.translation(x, y, 0);