计算几何图形包围盒的算法
1 bool YfCalculateSurroundBoxSize
2 (
3 const YsGraphDesc& graphDesc,
4 YsVector& vMin,
5 YsVector& vMax
6 )
7 {
8 switch (graphDesc.graphType)
9 {
10 case YE_GRAPH_PLANE:
11 {
12 if (graphDesc.slices < 2 || graphDesc.stacks < 2)
13 {
14 return false;
15 }
16 vMin = YsVector(0.0f, graphDesc.height - 0.5f, 0.0f);
17 vMax = YsVector(graphDesc.width, graphDesc.height + 0.5f, graphDesc.length);
18 if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
19 {
20 vMin.x -= graphDesc.width * 0.5f;
21 vMin.z -= graphDesc.length * 0.5f;
22 vMax.x -= graphDesc.width * 0.5f;
23 vMax.z -= graphDesc.length * 0.5f;
24 }
25 }
26 break;
27
28 case YE_GRAPH_BOX:
29 {
30 vMin = YsVector(0.0f, 0.0f, 0.0f);
31 vMax = YsVector(graphDesc.extentX, graphDesc.extentY, graphDesc.extentZ);
32
33 YsVector3 vOriginOffset = -vMax * 0.5f;
34 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
35 {
36 vOriginOffset.y = -graphDesc.extentY;
37 }
38 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
39 {
40 vOriginOffset.y = 0.0f;
41 }
42 vMin += vOriginOffset;
43 vMax += vOriginOffset;
44 }
45 break;
46
47 case YE_GRAPH_SPHERE:
48 {
49 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
50 {
51 return false;
52 }
53 vMin = YsVector(-graphDesc.radius);
54 vMax = YsVector(graphDesc.radius);
55 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
56 {
57 vMin.y -= graphDesc.radius;
58 vMax.y -= graphDesc.radius;
59 }
60 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
61 {
62 vMin.y += graphDesc.radius;
63 vMax.y += graphDesc.radius;
64 }
65 }
66 break;
67
68 case YE_GRAPH_DRUM:
69 {
70 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
71 {
72 return false;
73 }
74 vMin = YsVector(-graphDesc.radius);
75 vMax = YsVector(graphDesc.radius);
76
77 vMin.x -= graphDesc.assistRadius;
78 vMin.z -= graphDesc.assistRadius;
79 vMax.x += graphDesc.assistRadius;
80 vMax.z += graphDesc.assistRadius;
81
82 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
83 {
84 vMin.y -= graphDesc.radius;
85 vMax.y -= graphDesc.radius;
86 }
87 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
88 {
89 vMin.y += graphDesc.radius;
90 vMax.y += graphDesc.radius;
91 }
92 }
93 break;
94
95 case YE_GRAPH_HEMISPHERE:
96 {
97 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
98 {
99 return false;
100 }
101 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
102 vMax = YsVector(graphDesc.radius);
103 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
104 {
105 vMin.y -= graphDesc.radius;
106 vMax.y -= graphDesc.radius;
107 }
108 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
109 {
110 vMin.y += graphDesc.radius;
111 vMax.y += graphDesc.radius;
112 }
113 }
114 break;
115
116 case YE_GRAPH_CONE:
117 {
118 if (graphDesc.slices < 2)
119 {
120 return false;
121 }
122 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
123 vMax = YsVector(graphDesc.radius, graphDesc.height, graphDesc.radius);
124 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
125 {
126 vMin.y -= graphDesc.height;
127 vMax.y -= graphDesc.height;
128 }
129 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
130 {
131 vMin.y -= graphDesc.height * 0.5f;
132 vMax.y -= graphDesc.height * 0.5f;
133 }
134 }
135 break;
136
137 case YE_GRAPH_CYLINDER:
138 {
139 if (graphDesc.slices < 2)
140 {
141 return false;
142 }
143
144 Yreal radius = (graphDesc.radius > graphDesc.assistRadius) ? graphDesc.radius : graphDesc.assistRadius;
145 vMin = YsVector(-radius, 0.0f, -radius);
146 vMax = YsVector(radius, graphDesc.height, radius);
147 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
148 {
149 vMin.y -= graphDesc.height;
150 vMax.y -= graphDesc.height;
151 }
152 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
153 {
154 vMin.y -= graphDesc.height * 0.5f;
155 vMax.y -= graphDesc.height * 0.5f;
156 }
157 }
158 break;
159
160 case YE_GRAPH_CAPSULE:
161 {
162 Yuint halfStacks = graphDesc.stacks / 2;
163 if (graphDesc.slices < 2 || halfStacks < 2)
164 {
165 return false;
166 }
167 vMin = YsVector(-graphDesc.radius, -graphDesc.radius - graphDesc.height*0.5f, -graphDesc.radius);
168 vMax = YsVector(graphDesc.radius, graphDesc.radius + graphDesc.height*0.5f, graphDesc.radius);
169 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
170 {
171 vMin.y -= graphDesc.radius + graphDesc.height;
172 vMax.y -= graphDesc.radius + graphDesc.height;
173 }
174 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
175 {
176 vMin.y += graphDesc.radius + graphDesc.height;
177 vMax.y += graphDesc.radius + graphDesc.height;
178 }
179 }
180 break;
181
182 case YE_GRAPH_PYRAMID:
183 {
184 vMin = YsVector(0.0f, 0.0f, 0.0f);
185 vMax = YsVector(graphDesc.width, graphDesc.height, graphDesc.length);
186
187 YsVector3 vOriginOffset(-graphDesc.width / 2, -graphDesc.height / 2, -graphDesc.length / 2);
188 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
189 {
190 vOriginOffset.y = -graphDesc.height;
191 }
192 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
193 {
194 vOriginOffset.y = 0.0f;
195 }
196 vMin += vOriginOffset;
197 vMax += vOriginOffset;
198 }
199 break;
200
201 case YE_GRAPH_ROUND:
202 {
203 if (graphDesc.slices < 3)
204 {
205 return false;
206 }
207 vMin = YsVector(-graphDesc.radius, graphDesc.height - 0.5f, -graphDesc.radius);
208 vMax = YsVector(graphDesc.radius, graphDesc.height + 0.5f, graphDesc.radius);
209 }
210 break;
211
212 case YE_GRAPH_RING:
213 {
214 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
215 {
216 return false;
217 }
218
219 Yreal halfHeight = graphDesc.height * 0.5f;
220 vMin = YsVector(-graphDesc.radius - graphDesc.assistRadius,
221 -halfHeight,
222 -graphDesc.radius - graphDesc.assistRadius);
223 vMax = YsVector(graphDesc.radius + graphDesc.assistRadius,
224 halfHeight,
225 graphDesc.radius + graphDesc.assistRadius);
226
227 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
228 {
229 vMin.y -= halfHeight;
230 vMax.y -= halfHeight;
231 }
232 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
233 {
234 vMin.y += halfHeight;
235 vMax.y += halfHeight;
236 }
237 }
238 break;
239
240 case YE_GRAPH_PIPE:
241 {
242 if (graphDesc.slices < 2)
243 {
244 return false;
245 }
246 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
247 vMax = YsVector(graphDesc.radius, graphDesc.height, graphDesc.radius);
248 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
249 {
250 vMin.y -= graphDesc.height;
251 vMax.y -= graphDesc.height;
252 }
253 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
254 {
255 vMin.y -= graphDesc.height * 0.5f;
256 vMax.y -= graphDesc.height * 0.5f;
257 }
258 }
259 break;
260
261 case YE_GRAPH_WEDGE:
262 {
263 vMin = YsVector(0.0f, 0.0f, 0.0f);
264 vMax = YsVector(graphDesc.width, graphDesc.height, graphDesc.length);
265
266 YsVector3 vOriginOffset(-graphDesc.width / 2, -graphDesc.height / 2, -graphDesc.length / 2);
267 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
268 {
269 vOriginOffset.y = -graphDesc.height;
270 }
271 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
272 {
273 vOriginOffset.y = 0.0f;
274 }
275 vMin += vOriginOffset;
276 vMax += vOriginOffset;
277 }
278 break;
279
280 case YE_GRAPH_FAN:
281 {
282 if (graphDesc.degree < 0 || graphDesc.degree > 360)
283 {
284 return false;
285 }
286 if (graphDesc.slices < 2)
287 {
288 return false;
289 }
290 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
291 vMax = YsVector(graphDesc.radius, graphDesc.height, graphDesc.radius);
292 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
293 {
294 vMin.y -= graphDesc.height;
295 vMax.y -= graphDesc.height;
296 }
297 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
298 {
299 vMin.y -= graphDesc.height * 0.5f;
300 vMax.y -= graphDesc.height * 0.5f;
301 }
302
303 Yreal radian = YD_DEGREE_TO_RADIAN(graphDesc.degree);
304 if (graphDesc.degree < 90)
305 {
306 vMin.x = 0.0f;
307 vMax.x = graphDesc.radius * yf_sin(radian);
308 vMin.z = 0.0f;
309 }
310 else if (graphDesc.degree < 180)
311 {
312 vMin.x = 0.0f;
313 vMin.z = graphDesc.radius * yf_cos(radian);
314 }
315 else if (graphDesc.degree < 270)
316 {
317 vMin.x = graphDesc.radius * yf_sin(radian);
318 }
319 }
320 break;
321
322 case YE_GRAPH_ARC:
323 {
324 if (graphDesc.degree < 0 || graphDesc.degree > 180)
325 {
326 return false;
327 }
328 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
329 {
330 return false;
331 }
332
333 Yreal radian = YD_DEGREE_TO_RADIAN(graphDesc.degree);
334 Yreal radius;
335 if (graphDesc.degree > 90)
336 {
337 radius = graphDesc.radius;
338 }
339 else
340 {
341 radius = graphDesc.radius * yf_sin(radian);
342 }
343
344 vMin = YsVector(-radius, -graphDesc.radius, -radius);
345 vMax = YsVector(radius, graphDesc.radius, radius);
346 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
347 {
348 vMin.y -= graphDesc.radius;
349 vMax.y -= graphDesc.radius;
350 }
351 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
352 {
353 vMin.y += graphDesc.radius;
354 vMax.y += graphDesc.radius;
355 }
356
357 Yreal arcHeight = graphDesc.radius * (1 - yf_cos(radian));
358 vMin.y += graphDesc.radius * 2 - arcHeight;
359 }
360 break;
361
362 case YE_GRAPH_GEARWHEEL:
363 {
364 if (graphDesc.slices < 3)
365 {
366 return false;
367 }
368 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
369 vMax = YsVector(graphDesc.radius, graphDesc.height, graphDesc.radius);
370 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
371 {
372 vMin.y -= graphDesc.height;
373 vMax.y -= graphDesc.height;
374 }
375 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
376 {
377 vMin.y -= graphDesc.height * 0.5f;
378 vMax.y -= graphDesc.height * 0.5f;
379 }
380 }
381 break;
382
383 case YE_GRAPH_STAR:
384 {
385 if (graphDesc.slices < 3)
386 {
387 return false;
388 }
389 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
390 vMax = YsVector(graphDesc.radius, graphDesc.height, graphDesc.radius);
391 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
392 {
393 vMin.y -= graphDesc.height;
394 vMax.y -= graphDesc.height;
395 }
396 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
397 {
398 vMin.y -= graphDesc.height * 0.5f;
399 vMax.y -= graphDesc.height * 0.5f;
400 }
401 }
402 break;
403
404 case YE_GRAPH_SPIRE:
405 {
406 if (graphDesc.stacks < 1 || graphDesc.slices < 3)
407 {
408 return false;
409 }
410
411 Yreal radius = (graphDesc.radius > graphDesc.assistRadius) ? graphDesc.radius : graphDesc.assistRadius;
412 vMin = YsVector(-radius, 0.0f, -radius);
413 vMax = YsVector(radius, graphDesc.height, radius);
414 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
415 {
416 vMin.y -= graphDesc.height;
417 vMax.y -= graphDesc.height;
418 }
419 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
420 {
421 vMin.y -= graphDesc.height * 0.5f;
422 vMax.y -= graphDesc.height * 0.5f;
423 }
424 }
425 break;
426
427 case YE_GRAPH_STAIRS:
428 {
429 if (graphDesc.stacks < 1)
430 {
431 return false;
432 }
433 vMin = YsVector(0.0f, 0.0f, 0.0f);
434 vMax = YsVector(graphDesc.extentX, graphDesc.extentY, graphDesc.extentZ);
435
436 YsVector3 vOriginOffset = -vMax * 0.5f;
437 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
438 {
439 vOriginOffset.y = -graphDesc.extentY;
440 }
441 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
442 {
443 vOriginOffset.y = 0.0f;
444 }
445 vMin += vOriginOffset;
446 vMax += vOriginOffset;
447 }
448 break;
449
450 case YE_GRAPH_SPIRAL_STAIRS:
451 {
452 if (graphDesc.stacks < 1 || graphDesc.slices < 3)
453 {
454 return false;
455 }
456
457 Yreal radius = (graphDesc.radius > graphDesc.assistRadius) ? graphDesc.radius : graphDesc.assistRadius;
458 vMin = YsVector(-radius, 0.0f, -radius);
459 vMax = YsVector(radius, graphDesc.height, radius);
460 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
461 {
462 vMin.y -= graphDesc.height;
463 vMax.y -= graphDesc.height;
464 }
465 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
466 {
467 vMin.y -= graphDesc.height * 0.5f;
468 vMax.y -= graphDesc.height * 0.5f;
469 }
470 }
471 break;
472
473 default:
474 {
475 return false;
476 }
477 break;
478 }
479
480 return true;
481 }
计算几何图形包围球的算法
1 // 计算一个规则图形的包围球大小
2 bool YfCalculateSurroundSphereSize
3 (
4 const YsGraphDesc& graphDesc,
5 OUT YsVector& vCenter,
6 OUT Yreal& fRadius
7 )
8 {
9 switch (graphDesc.graphType)
10 {
11 case YE_GRAPH_PLANE:
12 {
13 if (graphDesc.slices < 2 || graphDesc.stacks < 2)
14 {
15 return false;
16 }
17
18 fRadius = yf_sqrt(graphDesc.width * graphDesc.width +
19 graphDesc.length * graphDesc.length) / 2;
20
21 if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
22 {
23 vCenter = YsVector(0.0f, graphDesc.height, 0.0f);
24 }
25 else
26 {
27 vCenter = YsVector(graphDesc.width / 2, graphDesc.height, graphDesc.length / 2);
28 }
29 }
30 break;
31
32 case YE_GRAPH_BOX:
33 {
34 fRadius = yf_sqrt(graphDesc.extentX * graphDesc.extentX +
35 graphDesc.extentY * graphDesc.extentY +
36 graphDesc.extentZ * graphDesc.extentZ ) / 2;
37
38 vCenter = YsVector(0.0f, 0.0f, 0.0f);
39 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
40 {
41 vCenter.y = -graphDesc.extentY / 2;
42 }
43 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
44 {
45 vCenter.y = graphDesc.extentY / 2;
46 }
47 }
48 break;
49
50 case YE_GRAPH_SPHERE:
51 {
52 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
53 {
54 return false;
55 }
56 fRadius = graphDesc.radius;
57
58 vCenter = YsVector(0.0f, 0.0f, 0.0f);
59 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
60 {
61 vCenter.y -= graphDesc.radius;
62 }
63 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
64 {
65 vCenter.y += graphDesc.radius;
66 }
67 }
68 break;
69
70 case YE_GRAPH_HEMISPHERE:
71 {
72 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
73 {
74 return false;
75 }
76 fRadius = graphDesc.radius;
77
78 vCenter = YsVector(0.0f, 0.0f, 0.0f);
79 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
80 {
81 vCenter.y -= graphDesc.radius;
82 }
83 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
84 {
85 vCenter.y += graphDesc.radius;
86 }
87 }
88 break;
89
90 case YE_GRAPH_DRUM:
91 {
92 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
93 {
94 return false;
95 }
96 fRadius = graphDesc.radius + graphDesc.assistRadius;
97
98 vCenter = YsVector(0.0f, 0.0f, 0.0f);
99 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
100 {
101 vCenter.y -= graphDesc.radius;
102 }
103 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
104 {
105 vCenter.y += graphDesc.radius;
106 }
107 }
108 break;
109
110 case YE_GRAPH_CONE:
111 {
112 if (graphDesc.slices < 2)
113 {
114 return false;
115 }
116
117 if (graphDesc.height < graphDesc.radius)
118 {
119 fRadius = graphDesc.radius;
120 vCenter = YsVector(0.0f, 0.0f, 0.0f);
121 }
122 else
123 {
124 Yreal h = (graphDesc.height*graphDesc.height - graphDesc.radius*graphDesc.radius) /
125 2 / graphDesc.height;
126 fRadius = graphDesc.height - h;
127 vCenter = YsVector(0.0f, h, 0.0f);
128 }
129
130 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
131 {
132 vCenter.y -= graphDesc.height;
133 }
134 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
135 {
136 vCenter.y -= graphDesc.height * 0.5f;
137 }
138 }
139 break;
140
141 case YE_GRAPH_CYLINDER:
142 {
143 if (graphDesc.slices < 2)
144 {
145 return false;
146 }
147
148 Yreal radius = (graphDesc.radius > graphDesc.assistRadius) ? graphDesc.radius : graphDesc.assistRadius;
149
150 fRadius = yf_sqrt(radius*radius + graphDesc.height*graphDesc.height/4);
151
152 vCenter = YsVector(0.0f, 0.0f, 0.0f);
153 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
154 {
155 vCenter.y -= graphDesc.height / 2;
156 }
157 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
158 {
159 vCenter.y += graphDesc.height / 2;
160 }
161 }
162 break;
163
164 case YE_GRAPH_CAPSULE:
165 {
166 Yuint halfStacks = graphDesc.stacks / 2;
167 if (graphDesc.slices < 2 || halfStacks < 2)
168 {
169 return false;
170 }
171
172 fRadius = graphDesc.radius + graphDesc.height/2;
173
174 vCenter = YsVector(0.0f, 0.0f, 0.0f);
175 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
176 {
177 vCenter.y -= fRadius;
178 }
179 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
180 {
181 vCenter.y += fRadius;
182 }
183 }
184 break;
185
186 case YE_GRAPH_PYRAMID:
187 {
188 Yreal radius = yf_sqrt(graphDesc.width*graphDesc.width + graphDesc.length*graphDesc.length) / 2;
189 if (graphDesc.height < radius)
190 {
191 fRadius = radius;
192 vCenter = YsVector(0.0f, 0.0f, 0.0f);
193 }
194 else
195 {
196 Yreal h = (graphDesc.height*graphDesc.height - radius*radius) /
197 2 / graphDesc.height;
198 fRadius = graphDesc.height - h;
199 vCenter = YsVector(0.0f, h, 0.0f);
200 }
201
202 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
203 {
204 vCenter.y -= graphDesc.height;
205 }
206 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
207 {
208 vCenter.y -= graphDesc.height * 0.5f;
209 }
210 }
211 break;
212
213 case YE_GRAPH_ROUND:
214 {
215 if (graphDesc.slices < 3)
216 {
217 return false;
218 }
219 fRadius = graphDesc.radius;
220 vCenter = YsVector(0, graphDesc.height, 0);
221 }
222 break;
223
224 case YE_GRAPH_RING:
225 {
226 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
227 {
228 return false;
229 }
230
231 fRadius = graphDesc.radius + graphDesc.assistRadius;
232
233 vCenter = YsVector(0.0f, 0.0f, 0.0f);
234 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
235 {
236 vCenter.y -= graphDesc.height / 2;
237 }
238 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
239 {
240 vCenter.y += graphDesc.height / 2;
241 }
242 }
243 break;
244
245 case YE_GRAPH_PIPE:
246 {
247 if (graphDesc.slices < 2)
248 {
249 return false;
250 }
251
252 fRadius = yf_sqrt(graphDesc.radius*graphDesc.radius + graphDesc.height*graphDesc.height/4);
253
254 vCenter = YsVector(0.0f, 0.0f, 0.0f);
255 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
256 {
257 vCenter.y -= graphDesc.height / 2;
258 }
259 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
260 {
261 vCenter.y += graphDesc.height / 2;
262 }
263 }
264 break;
265
266 case YE_GRAPH_GEARWHEEL:
267 {
268 if (graphDesc.slices < 3)
269 {
270 return false;
271 }
272 fRadius = yf_sqrt(graphDesc.radius*graphDesc.radius + graphDesc.height*graphDesc.height/4);
273
274 vCenter = YsVector(0.0f, 0.0f, 0.0f);
275 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
276 {
277 vCenter.y -= graphDesc.height / 2;
278 }
279 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
280 {
281 vCenter.y += graphDesc.height / 2;
282 }
283 }
284 break;
285
286 case YE_GRAPH_STAR:
287 {
288 if (graphDesc.slices < 3)
289 {
290 return false;
291 }
292
293 if (graphDesc.height < graphDesc.radius)
294 {
295 fRadius = graphDesc.radius;
296 vCenter = YsVector(0.0f, 0.0f, 0.0f);
297 }
298 else
299 {
300 Yreal h = (graphDesc.height*graphDesc.height - graphDesc.radius*graphDesc.radius) /
301 2 / graphDesc.height;
302 fRadius = graphDesc.height - h;
303 vCenter = YsVector(0.0f, h, 0.0f);
304 }
305
306 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
307 {
308 vCenter.y -= graphDesc.height;
309 }
310 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
311 {
312 vCenter.y -= graphDesc.height * 0.5f;
313 }
314 }
315 break;
316
317 case YE_GRAPH_SPIRE:
318 {
319 if (graphDesc.stacks < 1 || graphDesc.slices < 3)
320 {
321 return false;
322 }
323
324 Yreal radius = (graphDesc.radius > graphDesc.assistRadius) ? graphDesc.radius : graphDesc.assistRadius;
325
326 fRadius = yf_sqrt(radius*radius + graphDesc.height*graphDesc.height/4);
327
328 vCenter = YsVector(0.0f, 0.0f, 0.0f);
329 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
330 {
331 vCenter.y -= graphDesc.height / 2;
332 }
333 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
334 {
335 vCenter.y += graphDesc.height / 2;
336 }
337 }
338 break;
339
340 case YE_GRAPH_STAIRS:
341 {
342 if (graphDesc.stacks < 1)
343 {
344 return false;
345 }
346
347 fRadius = yf_sqrt(graphDesc.extentX * graphDesc.extentX +
348 graphDesc.extentY * graphDesc.extentY +
349 graphDesc.extentZ * graphDesc.extentZ ) / 2;
350
351 vCenter = YsVector(0.0f, 0.0f, 0.0f);
352 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
353 {
354 vCenter.y = -graphDesc.extentY / 2;
355 }
356 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
357 {
358 vCenter.y = graphDesc.extentY / 2;
359 }
360 }
361 break;
362
363 case YE_GRAPH_SPIRAL_STAIRS:
364 {
365 if (graphDesc.stacks < 1 || graphDesc.slices < 3)
366 {
367 return false;
368 }
369
370 Yreal radius = (graphDesc.radius > graphDesc.assistRadius) ? graphDesc.radius : graphDesc.assistRadius;
371
372 fRadius = yf_sqrt(radius*radius + graphDesc.height*graphDesc.height/4);
373
374 vCenter = YsVector(0.0f, 0.0f, 0.0f);
375 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
376 {
377 vCenter.y -= graphDesc.height / 2;
378 }
379 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
380 {
381 vCenter.y += graphDesc.height / 2;
382 }
383 }
384 break;
385
386 case YE_GRAPH_WEDGE:
387 {
388 fRadius = yf_sqrt(graphDesc.extentX * graphDesc.extentX +
389 graphDesc.extentY * graphDesc.extentY +
390 graphDesc.extentZ * graphDesc.extentZ ) / 2;
391
392 vCenter = YsVector(0.0f, 0.0f, 0.0f);
393 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
394 {
395 vCenter.y = -graphDesc.extentY / 2;
396 }
397 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
398 {
399 vCenter.y = graphDesc.extentY / 2;
400 }
401 }
402 break;
403
404 case YE_GRAPH_FAN:
405 {
406 if (graphDesc.degree < 0 || graphDesc.degree > 360)
407 {
408 return false;
409 }
410 if (graphDesc.slices < 2)
411 {
412 return false;
413 }
414 YsVector vMin, vMax;
415 vMin = YsVector(-graphDesc.radius, 0.0f, -graphDesc.radius);
416 vMax = YsVector(graphDesc.radius, graphDesc.height, graphDesc.radius);
417 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
418 {
419 vMin.y -= graphDesc.height;
420 vMax.y -= graphDesc.height;
421 }
422 else if (graphDesc.originPose == YE_ORIGIN_POSE_CENTER)
423 {
424 vMin.y -= graphDesc.height * 0.5f;
425 vMax.y -= graphDesc.height * 0.5f;
426 }
427
428 Yreal radian = YD_DEGREE_TO_RADIAN(graphDesc.degree);
429 if (graphDesc.degree < 90)
430 {
431 vMin.x = 0.0f;
432 vMax.x = graphDesc.radius * yf_sin(radian);
433 vMin.z = 0.0f;
434 }
435 else if (graphDesc.degree < 180)
436 {
437 vMin.x = 0.0f;
438 vMin.z = graphDesc.radius * yf_cos(radian);
439 }
440 else if (graphDesc.degree < 270)
441 {
442 vMin.x = graphDesc.radius * yf_sin(radian);
443 }
444 vCenter = (vMax + vMin) / 2;
445 YsVector vDis = vMax - vMin;
446 fRadius = vDis.Magnitude() / 2;
447 }
448 break;
449
450 case YE_GRAPH_ARC:
451 {
452 if (graphDesc.degree < 0 || graphDesc.degree > 180)
453 {
454 return false;
455 }
456 if (graphDesc.slices < 2 || graphDesc.stacks < 3)
457 {
458 return false;
459 }
460
461 Yreal radian = YD_DEGREE_TO_RADIAN(graphDesc.degree);
462
463 if (graphDesc.degree > 90)
464 {
465 fRadius = graphDesc.radius;
466 vCenter = YsVector(0.0f, 0.0f, 0.0f);
467 }
468 else
469 {
470 fRadius = graphDesc.radius * yf_sin(radian);
471 vCenter = YsVector(0.0f, graphDesc.radius * yf_cos(radian), 0.0f);
472 }
473
474 if (graphDesc.originPose == YE_ORIGIN_POSE_TOP)
475 {
476 vCenter.y -= graphDesc.radius;
477 }
478 else if (graphDesc.originPose == YE_ORIGIN_POSE_BOTTOM)
479 {
480 vCenter.y += graphDesc.radius;
481 }
482 }
483 break;
484
485 default:
486 {
487 return false;
488 }
489 break;
490 }
491
492 return true;
493 }