2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
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
16 #include <dbmem.h> // must be last header!
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]
37 #define _build_named_primal(NAME,newprim) \
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)); \
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
)=
62 _static_declare_face_pts(cube
)=
69 _static_declare_face_edge(cube
)=
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
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
)=
99 _static_declare_face_pts(line
)=
101 _static_declare_face_edge(line
)=
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
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)
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
)=
133 _static_declare_face_edge(tri
)=
138 _static_declare_pt_list(tri
)=
139 { { 0, EdgeLn
, -EdgeLn
/2 },
140 {-Root3Over2
,-EdgeLn
/2, -EdgeLn
/2 },
141 { Root3Over2
,-EdgeLn
/2, -EdgeLn
/2 },
144 BOOL
PrimShape_CreateTri(primalInfo
*new_tri
)
146 _build_named_primal(tri
,new_tri
);
150 //////////////////////
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
)=
163 _static_declare_face_pts(light
)=
165 _static_declare_face_edge(light
)=
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
);
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;
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
;
198 static void build_ngon_edge_list(int n
, int *base_pt
, int base_idx
)
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
;
213 BOOL
PrimShape_CreateNGonPyr(primalInfo
*new_pyr
, int n
, BOOL face_align
, BOOL corner_p
)
220 new_pyr
->face_stride
=n
+1;
221 if (!_primalBr_SzCheck(new_pyr
)) return FALSE
;
222 if (!_primalBr_GetMem(new_pyr
)) return FALSE
;
225 build_ngon_base(n
,new_pyr
->pt_array
,-1,face_align
);
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;
234 new_pyr
->pt_array
[n
].x
=new_pyr
->pt_array
[n
].y
=0;
235 new_pyr
->pt_array
[n
].z
=1.0;
239 build_ngon_edge_list(n
,new_pyr
->edge_list
,0); // ring around the base
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
;
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;
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;
276 BOOL
PrimShape_CreateNGonCyl(primalInfo
*new_cyl
, int n
, BOOL face_align
)
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
;
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
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
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
;
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;
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;
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
)=
352 _static_declare_face_pts(wedge
)=
360 _static_declare_face_edge(wedge
)=
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
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
)=
432 _static_declare_face_edge(dodec
)=
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