514f95d9a7b6ca62a229c95eb2ea441c44367b44
[dosdemo] / tools / procgen / steamtun.cc
1 //#define BASE_STR
2 #define BASE_LEFTJ
3 //#define RIGHT_STR1
4 #define RIGHT_STR2
5 //#define LEFT_STR1
6 //#define LEFT_STR2
7 //#define LEFT_STR3
8 //#define LEFT_STR4
9
10 //#define LEFT_J1
11 //#define LEFT_J2
12 //#define LEFT_J3
13 #define LEFT_J4
14
15 #define STD_RAD         0.05
16 #define FAT_RAD         0.08
17 #define CON_RAD(r)      ((r) * 1.4)
18 #define CON_WIDTH       0.04
19
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);
28
29 static Mat4 xform;
30
31 #define add_object(o) \
32         do { \
33                 Object *tmp = o; \
34                 if(head) { \
35                         tail->next = tmp; \
36                         tail = tmp; \
37                 } else { \
38                         head = tail = tmp; \
39                 } \
40                 while(tail->next) tail = tail->next; \
41         } while(0)
42
43 extern "C" Object *generate()
44 {
45         Object *head = 0, *tail = 0;
46
47 #ifdef BASE_STR
48         add_object(gen_base_straight());
49 #endif
50 #ifdef BASE_LEFTJ
51         add_object(gen_base_left_junction());
52 #endif
53         add_object(gen_pipeworks());
54         return head;
55 }
56
57 static Object *gen_base_straight()
58 {
59         Object *owalls = new Object;
60         owalls->mesh = new Mesh;
61         gen_box(owalls->mesh, -1, -2, -1, 1, 2);
62
63         xform.rotation_x(deg_to_rad(90));
64         owalls->mesh->apply_xform(xform);
65
66         owalls->mesh->remove_faces(16, 23);
67
68         xform.translation(0, 0.5, 0);
69         owalls->mesh->apply_xform(xform);
70
71         return owalls;
72 }
73
74 static Object *gen_base_left_junction()
75 {
76         Mesh tmp;
77
78         Object *obj = new Object;
79         obj->mesh = new Mesh;
80
81         gen_box(obj->mesh, -1, -2, -1, 1, 3);
82
83         xform.rotation_x(deg_to_rad(90));
84         xform.translate(0, 0.5, 0);
85         obj->mesh->apply_xform(xform);
86
87         obj->mesh->remove_faces(24, 35);
88         obj->mesh->remove_faces(6, 11);
89
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);
97         }
98
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);
103
104         tmp.remove_faces(8, 11);
105
106         obj->mesh->append(tmp);
107
108         return obj;
109 }
110
111 static Object *gen_pipeworks()
112 {
113         Object *head = 0, *tail = 0;
114
115         // --- right straight pipes ---
116         float start_y = CON_RAD(FAT_RAD) + 0.01;
117
118 #if defined(RIGHT_STR1) || defined(RIGHT_STR2)
119         add_object(gen_pipe(0.5 - FAT_RAD, start_y, FAT_RAD));
120 #endif
121         start_y += (CON_RAD(FAT_RAD) + CON_RAD(STD_RAD)) * 0.9;
122
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);
126
127 #ifdef RIGHT_STR2
128                 if(i == 1) {
129                         add_object(gen_pipe_inwall(x, y, STD_RAD));
130                 } else {
131                         add_object(gen_pipe(x, y, STD_RAD));
132                 }
133 #endif
134 #ifdef RIGHT_STR1
135                 add_object(gen_pipe(x, y, STD_RAD));
136 #endif
137         }
138
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));
143 #endif
144 #ifdef LEFT_STR1
145         add_object(gen_pipe(-0.5 + CON_RAD(STD_RAD), 0.68, STD_RAD));
146 #endif
147 #ifdef LEFT_STR2
148         add_object(gen_pipe(-0.5 + CON_RAD(STD_RAD), 0.3, STD_RAD));
149 #endif
150 #ifdef LEFT_STR3
151         add_object(gen_pipe_s(-0.5 + CON_RAD(STD_RAD), 0.3, 0.67, STD_RAD));
152 #endif
153 #ifdef LEFT_STR4
154         add_object(gen_pipe_s(-0.5 + CON_RAD(STD_RAD), 0.68, 0.3, STD_RAD));
155 #endif
156
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));
161 #endif
162 #ifdef LEFT_J1
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));
165 #endif
166 #ifdef LEFT_J2
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));
169 #endif
170 #ifdef LEFT_J3
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));
173 #endif
174 #ifdef LEFT_J4
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));
177 #endif
178         return head;
179 }
180
181 static Object *gen_pipe(float x, float y, float rad)
182 {
183         Object *opipe = new Object;
184         opipe->mesh = new Mesh;
185
186
187         for(int i=0; i<2; i++) {
188                 Mesh tmp;
189
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);
195
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);
200
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);
205         }
206
207         xform.rotation_x(deg_to_rad(90));
208         opipe->mesh->apply_xform(xform);
209         opipe->xform.translation(x, y, 0);
210
211         return opipe;
212 }
213
214 static Object *gen_pipe_inwall(float x, float y, float rad)
215 {
216         Object *opipe = new Object;
217         opipe->mesh = new Mesh;
218
219         const float pipelen = 0.2;
220         float zoffs = 1.0 - pipelen - CON_WIDTH;
221
222         for(int i=0; i<2; i++) {
223                 Mesh tmp;
224                 float sign = i == 0 ? 1.0f : -1.0f;
225
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);
232
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);
239
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);
245         }
246
247         opipe->xform.translation(x, y, 0);
248
249         return opipe;
250 }
251
252 static Object *gen_pipe_s(float x, float y0, float y1, float rad)
253 {
254         Mesh tmp;
255         float dist = fabs(y0 - y1);
256         float pipelen = 1.0f - rad * 2.0 - CON_WIDTH / 2.0;
257
258         Object *obj = new Object;
259         obj->mesh = new Mesh;
260
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);
264
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);
271
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);
277
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);
283
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);
289         }
290
291         gen_cylinder(&tmp, rad, dist - rad * 4.0, 6, 1);
292         obj->mesh->append(tmp);
293
294         obj->xform.translation(x, (y0 + y1) / 2.0, 0);
295         return obj;
296 }
297
298 static Object *gen_pipe_corner(float x, float y, float z, float rad)
299 {
300         Mesh tmp;
301         Object *obj = new Object;
302         obj->mesh = new Mesh;
303
304         float xoffs = CON_RAD(rad);
305         float pipelen = 0.5 - CON_WIDTH - (rad * 2.0 - xoffs + CON_WIDTH);
306
307         float sign = z >= 0.0f ? 1.0f : -1.0f;
308
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);
314
315         for(int i=0; i<2; i++) {
316                 Mesh pipe;
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);
322                 pipe.append(tmp);
323
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);
328                 pipe.append(tmp);
329
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);
334                 pipe.append(tmp);
335
336                 if(i > 0) {
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);
343                 }
344
345                 obj->mesh->append(pipe);
346         }
347
348         obj->xform.translation(x, y, 0);
349         return obj;
350 }