convert line ends
[canaan.git] / prj / cam / src / editor / primshap.c
blob15ec0d8c33707d3507c3bf4ec19f1e2fff20718b
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/editor/primshap.c,v 1.12 2000/02/19 13:11:15 toml Exp $
7 // primshap(e)... code and data for generating the primal shapes
9 #include <string.h>
10 #include <stdlib.h>
11 #include <math.h>
13 #include <matrix.h>
14 #include <primal.h>
15 #include <memall.h>
16 #include <dbmem.h> // must be last header!
18 ///////////////////
19 // setup template silliness
21 // declare the base static setup, ie. the primalInfo inlined struct
22 #define _static_declare_base(NAME) \
23 static primalInfo NAME##_base= \
24 {##NAME##_PT_CNT,##NAME##_EDGE_CNT,##NAME##_FACE_CNT,##NAME##_FACE_PTS,NULL,NULL,NULL,NULL}
26 // various array declarations, here to be consistently named, and have array sizes hardcoded
27 #define _static_declare_edges(NAME) \
28 static int NAME##_edge_list[##NAME##_EDGE_CNT*2]
29 #define _static_declare_face_pts(NAME) \
30 static int NAME##_face_pts_list[##NAME##_FACE_CNT * ##NAME##_FACE_PTS]
31 #define _static_declare_face_edge(NAME) \
32 static int NAME##_face_edge_list[##NAME##_FACE_CNT * ##NAME##_FACE_PTS]
33 #define _static_declare_pt_list(NAME) \
34 static mxs_vector NAME##_pts_list[##NAME##_PT_CNT]
36 // memory setup ops
37 #define _build_named_primal(NAME,newprim) \
38 do { \
39 memcpy(newprim,&##NAME##_base,sizeof(primalInfo)); \
40 if (!_primalBr_GetMem(newprim)) return FALSE; \
41 memcpy(newprim->edge_list,##NAME##_edge_list,sizeof(##NAME##_edge_list)); \
42 memcpy(newprim->face_pts_list,##NAME##_face_pts_list,sizeof(##NAME##_face_pts_list)); \
43 memcpy(newprim->face_edge_list,##NAME##_face_edge_list,sizeof(##NAME##_face_edge_list)); \
44 memcpy(newprim->pt_array,##NAME##_pts_list,sizeof(##NAME##_pts_list)); \
45 } while (0)
47 ///////////////////
48 // basic cube!
50 #define cube_PT_CNT (8)
51 #define cube_EDGE_CNT (12)
52 #define cube_FACE_CNT (6)
53 #define cube_FACE_PTS (4+1)
55 // here is our primalInfo intself
56 _static_declare_base(cube);
58 _static_declare_edges(cube)=
59 { 0,1, 1,2, 2,3, 3,0,
60 0,4, 4,7, 7,3, 2,6,
61 6,5, 5,1, 4,5, 6,7};
62 _static_declare_face_pts(cube)=
63 { 0,1,2,3,-1,
64 3,2,6,7,-1,
65 7,6,5,4,-1,
66 4,5,1,0,-1,
67 1,5,6,2,-1,
68 4,0,3,7,-1 };
69 _static_declare_face_edge(cube)=
70 { 0,1,2,3,-1,
71 2,7,11,6,-1,
72 11,8,10,5,-1,
73 10,9,0,4,-1,
74 9,8,7,1,-1,
75 4,3,6,5,-1 };
76 _static_declare_pt_list(cube)=
77 { {-1,1,-1},{-1,1,1},{-1,-1,1},{-1,-1,-1},
78 { 1,1,-1},{ 1,1,1},{ 1,-1,1},{ 1,-1,-1}};
80 BOOL PrimShape_CreateCube(primalInfo *new_cube)
82 _build_named_primal(cube,new_cube); // can return FALSE internally
83 return TRUE;
86 /////////////////////
87 // look, a line - really just here to simplify some other code
89 #define line_PT_CNT (2)
90 #define line_EDGE_CNT (1)
91 #define line_FACE_CNT (1)
92 #define line_FACE_PTS (2+1)
94 // here is our primalInfo intself
95 _static_declare_base(line);
97 _static_declare_edges(line)=
98 { 0,1 };
99 _static_declare_face_pts(line)=
100 { 0,1,-1 };
101 _static_declare_face_edge(line)=
102 { 0,1,-1 };
103 _static_declare_pt_list(line)=
104 { {-1,0,0},{1,0,0} };
106 BOOL PrimShape_CreateLine(primalInfo *new_line)
108 _build_named_primal(line,new_line); // can return FALSE internally
109 return TRUE;
112 //////////////////////
113 // tri pyramid hack for test
115 #define tri_PT_CNT (4)
116 #define tri_EDGE_CNT (6)
117 #define tri_FACE_CNT (4)
118 #define tri_FACE_PTS (3+1)
120 #define Root3Over2 (0.866025)
121 #define EdgeLn (1.0)
123 // here is our primalInfo intself
124 _static_declare_base(tri);
126 _static_declare_edges(tri)=
127 { 0,1, 1,2, 2,0, 3,2, 3,1, 0,3 };
128 _static_declare_face_pts(tri)=
129 { 0,1,2,-1,
130 2,1,3,-1,
131 3,1,0,-1,
132 0,2,3,-1 };
133 _static_declare_face_edge(tri)=
134 { 0,1,2,-1,
135 1,4,3,-1,
136 4,0,5,-1,
137 2,3,5,-1 };
138 _static_declare_pt_list(tri)=
139 { { 0, EdgeLn, -EdgeLn/2 },
140 {-Root3Over2,-EdgeLn/2, -EdgeLn/2 },
141 { Root3Over2,-EdgeLn/2, -EdgeLn/2 },
142 { 0, 0, EdgeLn } };
144 BOOL PrimShape_CreateTri(primalInfo *new_tri)
146 _build_named_primal(tri,new_tri);
147 return TRUE;
150 //////////////////////
151 // light
153 #define light_PT_CNT (6)
154 #define light_EDGE_CNT (3)
155 #define light_FACE_CNT (1)
156 #define light_FACE_PTS (1)
158 // here is our primalInfo intself
159 _static_declare_base(light);
161 _static_declare_edges(light)=
162 { 0,1, 2,3, 4,5 };
163 _static_declare_face_pts(light)=
164 { -1 };
165 _static_declare_face_edge(light)=
166 { -1 };
167 _static_declare_pt_list(light)=
168 { { 0, 1, 0}, { 0,-1, 0},
169 { 1, 0, 0}, {-1, 0, 0},
170 { 0, 0, 1}, { 0, 0,-1} };
172 BOOL PrimShape_CreateLight(primalInfo *new_light)
174 _build_named_primal(light,new_light);
175 return TRUE;
178 /////////////////////
179 // generic ngon basis stuff
181 // fill pts with an n-gon in xy with z coodinate z
182 static void build_ngon_base(int n, mxs_vector *pts, float z, BOOL face_align)
184 double face_mod=face_align?1.0:0.0, scale_f=1.0;
185 int i;
187 for (i=0; i<n; i++)
189 double ang=MX_REAL_2PI*(i*2.0+face_mod)/(n*2.0); // currently vertex aligned, add 1.0 to numerator for face
190 if (face_align&&(i==0))
191 scale_f=(double)1.0/cos(ang);
192 pts[i].y= cos(ang)*scale_f;
193 pts[i].x=-sin(ang)*scale_f;
194 pts[i].z= z;
198 static void build_ngon_edge_list(int n, int *base_pt, int base_idx)
200 int i;
201 for (i=0; i<n-1; i++)
203 base_pt[i*2]=base_idx+i;
204 base_pt[i*2+1]=base_idx+i+1;
206 base_pt[i*2]=base_idx+i;
207 base_pt[i*2+1]=base_idx;
210 ////////////////////
211 // ngon pyramids
213 BOOL PrimShape_CreateNGonPyr(primalInfo *new_pyr, int n, BOOL face_align, BOOL corner_p)
215 int i;
217 new_pyr->faces=n+1;
218 new_pyr->points=n+1;
219 new_pyr->edges=2*n;
220 new_pyr->face_stride=n+1;
221 if (!_primalBr_SzCheck(new_pyr)) return FALSE;
222 if (!_primalBr_GetMem(new_pyr)) return FALSE;
224 //////// PTLIST
225 build_ngon_base(n,new_pyr->pt_array,-1,face_align);
226 if (corner_p)
228 new_pyr->pt_array[n].x=new_pyr->pt_array[0].x;
229 new_pyr->pt_array[n].y=new_pyr->pt_array[0].y;
230 new_pyr->pt_array[n].z=1.0;
232 else
234 new_pyr->pt_array[n].x=new_pyr->pt_array[n].y=0;
235 new_pyr->pt_array[n].z=1.0;
238 //////// EDGELIST
239 build_ngon_edge_list(n,new_pyr->edge_list,0); // ring around the base
240 for (i=0; i<n; i++)
241 { // and here are edges up to the top
242 new_pyr->edge_list[(n+i)*2]=i;
243 new_pyr->edge_list[(n+i)*2+1]=n;
246 //////// FACEPTS
247 for (i=0; i<n; i++) // faces up to the top
249 new_pyr->face_pts_list[new_pyr->face_stride*i+0]=i;
250 new_pyr->face_pts_list[new_pyr->face_stride*i+1]=n+1;
251 new_pyr->face_pts_list[new_pyr->face_stride*i+2]=(i+1)%n;
252 new_pyr->face_pts_list[new_pyr->face_stride*i+3]=-1;
254 for (i=0; i<n; i++) // right around the base
255 new_pyr->face_pts_list[new_pyr->face_stride*n+i]=i;
256 new_pyr->face_pts_list[new_pyr->face_stride*n+i]=-1;
258 //////// FACEEDGES
259 for (i=0; i<n; i++) // faces up to the top
261 new_pyr->face_edge_list[new_pyr->face_stride*i+0]=i;
262 new_pyr->face_edge_list[new_pyr->face_stride*i+1]=n+i;
263 new_pyr->face_edge_list[new_pyr->face_stride*i+2]=n+((i+1)%n);
264 new_pyr->face_edge_list[new_pyr->face_stride*i+3]=-1;
266 for (i=0; i<n; i++) // right around the base
267 new_pyr->face_edge_list[new_pyr->face_stride*n+i]=i;
268 new_pyr->face_edge_list[new_pyr->face_stride*n+i]=-1;
270 return TRUE;
273 ////////////////////
274 // ngon cylinders
276 BOOL PrimShape_CreateNGonCyl(primalInfo *new_cyl, int n, BOOL face_align)
278 int i;
279 new_cyl->faces=n+2;
280 new_cyl->points=2*n;
281 new_cyl->edges=3*n;
282 new_cyl->face_stride=max(n+1,4+1); // in case you have a 3 sided base on a cyl - rect sides have more edges
283 if (!_primalBr_SzCheck(new_cyl)) return FALSE;
284 if (!_primalBr_GetMem(new_cyl)) return FALSE;
286 //////// PTLIST
287 build_ngon_base(n,new_cyl->pt_array ,-1, face_align); // bottom of cylinder
288 build_ngon_base(n,new_cyl->pt_array+n, 1, face_align); // top of cylinder
290 //////// EDGELIST
291 build_ngon_edge_list(n,new_cyl->edge_list ,0); // ring around the base
292 build_ngon_edge_list(n,new_cyl->edge_list+2*n,n); // ring around the top
293 for (i=0; i<n; i++)
294 { // and here are sides
295 new_cyl->edge_list[(2*n+i)*2] =i;
296 new_cyl->edge_list[(2*n+i)*2+1]=n+i;
299 //////// FACEPTS
300 for (i=0; i<n; i++) // faces up to the top
302 new_cyl->face_pts_list[new_cyl->face_stride*i+0]=i;
303 new_cyl->face_pts_list[new_cyl->face_stride*i+1]=n+i;
304 new_cyl->face_pts_list[new_cyl->face_stride*i+2]=n+((i+1)%n);
305 new_cyl->face_pts_list[new_cyl->face_stride*i+3]=(i+1)%n;
306 new_cyl->face_pts_list[new_cyl->face_stride*i+4]=-1;
308 new_cyl->face_pts_list[new_cyl->face_stride*n+0]=n;
309 for (i=1; i<n; i++) // around the top
310 new_cyl->face_pts_list[new_cyl->face_stride*n+i]=2*n-i;
311 new_cyl->face_pts_list[new_cyl->face_stride*n+i]=-1;
312 for (i=0; i<n; i++) // around the top
313 new_cyl->face_pts_list[new_cyl->face_stride*(n+1)+i]=i;
314 new_cyl->face_pts_list[new_cyl->face_stride*(n+1)+i]=-1;
316 //////// FACEEDGES
317 for (i=0; i<n; i++) // faces up to the top
319 new_cyl->face_edge_list[new_cyl->face_stride*i+0]=i;
320 new_cyl->face_edge_list[new_cyl->face_stride*i+1]=2*n+i;
321 new_cyl->face_edge_list[new_cyl->face_stride*i+2]=n+i;
322 new_cyl->face_edge_list[new_cyl->face_stride*i+3]=2*n+((i+1)%n);
323 new_cyl->face_edge_list[new_cyl->face_stride*i+4]=-1;
325 for (i=0; i<n; i++) // around the top
326 new_cyl->face_edge_list[new_cyl->face_stride*n+i]=2*n-i-1;
327 new_cyl->face_edge_list[new_cyl->face_stride*n+i]=-1;
328 for (i=0; i<n; i++) // around the top
329 new_cyl->face_edge_list[new_cyl->face_stride*(n+1)+i]=i;
330 new_cyl->face_edge_list[new_cyl->face_stride*(n+1)+i]=-1;
332 return TRUE;
335 ///////////////////
336 // Wedge Antilles
338 #define wedge_PT_CNT (6)
339 #define wedge_EDGE_CNT (9)
340 #define wedge_FACE_CNT (5)
341 #define wedge_FACE_PTS (4+1)
343 // here is our primalInfo intself
344 _static_declare_base(wedge);
346 _static_declare_edges(wedge)=
347 { 0,1, 1,2, 2,0,
348 3,4, 4,5, 5,3,
349 0,3, 2,5, 1,4,
352 _static_declare_face_pts(wedge)=
354 0,3,4,1,-1,
355 2,1,4,5,-1,
356 0,2,5,3,-1,
357 0,1,2,-1,-1,
358 3,5,4,-1,-1,
360 _static_declare_face_edge(wedge)=
362 0,6,3,8,-1,
363 1,8,4,7,-1,
364 6,2,7,5,-1,
365 0,1,2,-1,-1,
366 3,5,4,-1,-1,
369 _static_declare_pt_list(wedge)=
370 { {1,-1,1},{1,1,-1},{1,-1,-1},
371 {-1,-1,1},{-1,1,-1},{-1,-1,-1},
375 _static_declare_pt_list(wedge)=
376 { {-1,1,1},{1,-1,1},{-1,-1,1},
377 {-1,1,-1},{1,-1,-1},{-1,-1,-1},
380 BOOL PrimShape_CreateWedge(primalInfo *new_wedge)
382 _build_named_primal(wedge,new_wedge); // can return FALSE internally
383 return TRUE;
386 /////////////////////////////////////////////
387 // Dodecahedron, or a d12 for you philistines
389 #define dodec_PT_CNT (20)
390 #define dodec_EDGE_CNT (30)
391 #define dodec_FACE_CNT (12)
392 #define dodec_FACE_PTS (5+1)
394 // here is our primalInfo intself
395 _static_declare_base(dodec);
397 _static_declare_edges(dodec)=
398 { 0,1, 1,2, 2,3, 3,4, 4,0,
399 4,9, 9,15, 15,5, 5,0, 5,19,
400 19,6, 6,1, 6,18, 18,7, 7,2,
401 7,17, 17,8, 8,3, 8,16, 16,9,
402 10,11, 11,12, 12,13, 13,14, 14,10,
403 14,19, 10,15, 11,16, 17,12, 13,18,
405 1,2, 2,3, 3,4, 4,5, 5,1,
406 5,10, 10,16, 16,6, 6,1, 6,20,
407 20,7, 7,2, 7,19, 19,8, 8,3,
408 8,18, 18,9, 9,4, 9,17, 17,10,
409 11,12, 12,13, 13,14, 14,15, 15,11,
410 15,20, 11,16, 12,17, 18,13, 14,19,
415 _static_declare_face_pts(dodec)=
416 { 0,1,2,3,4,-1,
417 0,4,9,15,5,-1,
418 1,0,5,19,6,-1,
419 2,1,6,18,7,-1,
420 3,2,7,17,8,-1,
422 4,3,8,16,9,-1,
423 10,11,12,13,14,-1,
424 10,14,19,5,15,-1,
425 11,10,15,9,16,-1,
426 12,11,16,8,17,-1,
428 13,12,17,7,18,-1,
429 14,13,18,6,19,-1,
432 _static_declare_face_edge(dodec)=
433 { 0,1,2,3,4,-1,
434 4,5,6,7,8,-1,
435 0,8,9,10,11,-1,
436 1,11,12,13,14,-1,
437 2,14,15,16,17,-1,
439 3,17,18,19,5,-1,
440 20,21,22,23,24,-1,
441 24,25,9,7,26,-1,
442 20,26,6,19,27,-1,
443 21,27,18,16,28,-1,
445 22,28,15,13,29,-1,
446 23,29,12,10,25,-1,
449 #define DOD_SCALE 1.0F
450 #define DODA (0.0F * DOD_SCALE)
451 #define DODB (0.5773502692F * DOD_SCALE)
452 #define DODC (0.7946544723F * DOD_SCALE)
453 #define DODD (0.1875924741F * DOD_SCALE)
454 #define DODE (0.9822469464F * DOD_SCALE)
455 #define DODF (0.6070619982F * DOD_SCALE)
456 #define DODG (0.9341723590F * DOD_SCALE)
457 #define DODH (0.3568220898F * DOD_SCALE)
458 #define DODI (0.4911234732F * DOD_SCALE)
459 #define DODJ (0.3035309991F * DOD_SCALE)
461 _static_declare_pt_list(dodec)=
463 {DODB,DODD,-DODC},{DODA,DODF,-DODC},{-DODB,DODD,-DODC},{-DODH,-DODI,-DODC},{DODH,-DODI,-DODC},
464 {DODG,DODJ,-DODD},{DODA,DODE,-DODD},{-DODG,DODJ,-DODD},{-DODB,-DODC,-DODD},{DODB,-DODC,-DODD},
465 {DODB,-DODD,DODC},{DODA,-DODF,DODC},{-DODB,-DODD,DODC},{-DODH,DODI,DODC},{DODH,DODI,DODC},
466 {DODG,-DODJ,DODD},{DODA,-DODE,DODD},{-DODG,-DODJ,DODD},{-DODB,DODC,DODD},{DODB,DODC,DODD},
469 BOOL PrimShape_CreateDodecahedron(primalInfo *new_dodec)
471 _build_named_primal(dodec,new_dodec); // can return FALSE internally
472 return TRUE;