Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
FlatBatch3D.cs
浏览该文件的文档.
1namespace Engine.Graphics {
2 public class FlatBatch3D : BaseFlatBatch {
8
12 public void QueueSphere(Vector3 center, float radius, int slices, int stacks, Color color) {
13 if (slices < 3) {
14 slices = 3;
15 }
16 if (stacks < 2) {
17 stacks = 2;
18 }
19 float latitudeStep = (float)Math.PI / stacks;
20 float longitudeStep = 2.0f * (float)Math.PI / slices;
21 for (int lat = 0; lat <= stacks; lat++) {
22 float a1 = (float)(-Math.PI / 2 + lat * latitudeStep);
23 float a2 = (float)(-Math.PI / 2 + (lat + 1) * latitudeStep);
24 for (int lon = 0; lon <= slices; lon++) {
25 float b1 = lon * longitudeStep;
26 float b2 = (lon + 1) * longitudeStep;
27
28 // 上半球顶点
29 Vector3 v1 = center
30 + new Vector3(
31 (float)(Math.Sin(a1) * Math.Cos(b1)) * radius,
32 (float)Math.Cos(a1) * radius,
33 (float)(Math.Sin(a1) * Math.Sin(b1)) * radius
34 );
35 Vector3 v2 = center
36 + new Vector3(
37 (float)(Math.Sin(a2) * Math.Cos(b1)) * radius,
38 (float)Math.Cos(a2) * radius,
39 (float)(Math.Sin(a2) * Math.Sin(b1)) * radius
40 );
41 Vector3 v3 = center
42 + new Vector3(
43 (float)(Math.Sin(a1) * Math.Cos(b2)) * radius,
44 (float)Math.Cos(a1) * radius,
45 (float)(Math.Sin(a1) * Math.Sin(b2)) * radius
46 );
47 Vector3 v4 = center
48 + new Vector3(
49 (float)(Math.Sin(a2) * Math.Cos(b2)) * radius,
50 (float)Math.Cos(a2) * radius,
51 (float)(Math.Sin(a2) * Math.Sin(b2)) * radius
52 );
53
54 // 下半球顶点
55 Vector3 v5 = center
56 - new Vector3(
57 (float)(Math.Sin(-a1) * Math.Cos(b1)) * radius,
58 (float)Math.Cos(-a1) * radius,
59 (float)(Math.Sin(-a1) * Math.Sin(b1)) * radius
60 );
61 Vector3 v6 = center
62 - new Vector3(
63 (float)(Math.Sin(-a1) * Math.Cos(b2)) * radius,
64 (float)Math.Cos(-a1) * radius,
65 (float)(Math.Sin(-a1) * Math.Sin(b2)) * radius
66 );
67 Vector3 v7 = center
68 - new Vector3(
69 (float)(Math.Sin(-a2) * Math.Cos(b2)) * radius,
70 (float)Math.Cos(-a2) * radius,
71 (float)(Math.Sin(-a2) * Math.Sin(b2)) * radius
72 );
73 Vector3 v8 = center
74 - new Vector3(
75 (float)(Math.Sin(-a2) * Math.Cos(b1)) * radius,
76 (float)Math.Cos(-a2) * radius,
77 (float)(Math.Sin(-a2) * Math.Sin(b1)) * radius
78 );
79
80 // 上半球三角形
81 QueueTriangle(v1, v2, v3, color);
82 QueueTriangle(v2, v4, v3, color);
83 // 下半球三角形
84 QueueTriangle(v5, v6, v7, color);
85 QueueTriangle(v5, v7, v8, color);
86 }
87 }
88 }
89
99 public void QueueSphereWithLines(Vector3 center,
100 Color color,
101 float radius = 1,
102 int longitudeLines = 20,
103 int latitudeLines = 20,
104 int draw = 0) {
105 if (longitudeLines < 3) {
106 longitudeLines = 3;
107 }
108 if (latitudeLines < 2) {
109 latitudeLines = 2;
110 }
111 if (draw == 1
112 || draw == 0) {
113 // 绘制纬线球
114 for (int lat = 0; lat <= latitudeLines; lat++) {
115 float angle = (float)(Math.PI / 2 - lat * Math.PI / latitudeLines);
116 float radiusAtLatitude = radius * (float)Math.Cos(angle); // 计算纬度上的圆半径
117 Vector3 offset = new(0, (float)(Math.Sin(angle) * radius), 0);
118 QueueCircle(center + offset, radiusAtLatitude, longitudeLines, color);
119 }
120 }
121 if (draw == 2
122 || draw == 0) {
123 // 绘制经线球
124 for (int lon = 0; lon < longitudeLines; lon++) // 注意:这里不需要包括最后一个经度线,因为它会和第一个经度线重合
125 {
126 float longitudeAngle = lon * 2 * (float)Math.PI / longitudeLines; // 经度角度
127 List<Vector3> points = new();
128 for (int lat = 0; lat <= latitudeLines; lat++) {
129 float latitudeAngle = (float)(Math.PI / 2 - lat * Math.PI / latitudeLines);
130 points.Add(
131 center
132 + new Vector3(
133 (float)(Math.Cos(latitudeAngle) * Math.Cos(longitudeAngle)) * radius,
134 (float)Math.Sin(latitudeAngle) * radius,
135 (float)(Math.Cos(latitudeAngle) * Math.Sin(longitudeAngle)) * radius
136 )
137 );
138 }
139 // 绘制经线
140 QueueLineStrip(points, color);
141 }
142 }
143 }
144
148 public void QueueCircle(Vector3 center, float radius, int segments, Color color, bool useLineStrip = true) {
149 if (segments < 3) {
150 segments = 3;
151 }
152 float step = (float)(2 * Math.PI) / segments;
153 List<Vector3> points = new();
154 for (int i = 0; i <= segments; i++) {
155 float angle = step * i;
156 Vector3 point = center + new Vector3((float)Math.Cos(angle) * radius, 0, (float)Math.Sin(angle) * radius);
157 points.Add(point);
158 }
159 if (useLineStrip) {
160 QueueLineStrip(points, color);
161 }
162 else {
163 for (int i = 0; i < points.Count - 1; i++) {
164 QueueLine(points[i], points[i + 1], color);
165 }
166 }
167 }
168
172 public void QueueCurvedCylinder(Vector3 start, Vector3 end, float radius, Color color, int segments = 12, bool drawTopAndBottom = true) {
173 // 计算圆柱的高度
174 float height = Vector3.Distance(start, end);
175
176 // 计算圆柱的方向
177 Vector3 direction = Vector3.Normalize(end - start);
178
179 // 计算圆柱的基准点
180 Vector3 baseCenter = start + direction * (height / 2);
181
182 // 绘制圆柱的侧面
183 for (int i = 0; i < segments; i++) {
184 float angle1 = (float)(2 * Math.PI * i / segments);
185 float angle2 = (float)(2 * Math.PI * (i + 1) / segments);
186 Vector3 point1 = baseCenter + new Vector3(radius * MathF.Cos(angle1), -height / 2, radius * MathF.Sin(angle1));
187 Vector3 point2 = baseCenter + new Vector3(radius * MathF.Cos(angle2), -height / 2, radius * MathF.Sin(angle2));
188 Vector3 point3 = baseCenter + new Vector3(radius * MathF.Cos(angle1), height / 2, radius * MathF.Sin(angle1));
189 Vector3 point4 = baseCenter + new Vector3(radius * MathF.Cos(angle2), height / 2, radius * MathF.Sin(angle2));
190
191 // 绘制侧面
192 QueueTriangle(point1, point2, point3, color);
193 QueueTriangle(point2, point4, point3, color);
194 }
195 if (drawTopAndBottom) {
196 // 绘制圆柱的顶部和底部
197 QueueCircle(baseCenter + new Vector3(0, height / 2, 0), radius, segments, color);
198 QueueCircle(baseCenter + new Vector3(0, -height / 2, 0), radius, segments, color);
199 }
200 }
201
202 public void QueueBatchTriangles(FlatBatch3D batch, Matrix? matrix = null, Color? color = null) {
203 int count = TriangleVertices.Count;
204 TriangleVertices.AddRange(batch.TriangleVertices);
205 int count2 = TriangleIndices.Count;
206 int count3 = batch.TriangleIndices.Count;
207 TriangleIndices.Count += count3;
208 for (int i = 0; i < count3; i++) {
209 TriangleIndices[i + count2] = batch.TriangleIndices[i] + count;
210 }
211 if (matrix.HasValue
212 && matrix != Matrix.Identity) {
213 TransformTriangles(matrix.Value, count);
214 }
215 if (color.HasValue
216 && color != Color.White) {
217 TransformTrianglesColors(color.Value, count);
218 }
219 }
220
222 public void QueueTriangles(IEnumerable<Vector3> points, Color color) {
223 int count = TriangleVertices.Count;
224 int i = 0;
225 foreach (Vector3 point in points) {
226 TriangleVertices.Add(new VertexPositionColor(point, color));
227 if (++i % 3 == 0) {
228 TriangleIndices.Add(count + i - 3);
229 TriangleIndices.Add(count + i - 2);
230 TriangleIndices.Add(count + i - 1);
231 }
232 }
233 }
234
236 public void QueueTriangles(IEnumerable<VertexPositionColor> vertices) {
237 int count = TriangleVertices.Count;
238 int i = 0;
239 foreach (VertexPositionColor vertex in vertices) {
240 TriangleVertices.Add(vertex);
241 if (++i % 3 == 0) {
242 TriangleIndices.Add(count + i - 3);
243 TriangleIndices.Add(count + i - 2);
244 TriangleIndices.Add(count + i - 1);
245 }
246 }
247 }
248
249 public void QueueBatchLines(FlatBatch3D batch, Matrix? matrix = null, Color? color = null) {
250 int count = LineVertices.Count;
251 LineVertices.AddRange(batch.LineVertices);
252 int count2 = LineIndices.Count;
253 int count3 = batch.LineIndices.Count;
254 LineIndices.Count += count3;
255 for (int i = 0; i < count3; i++) {
256 LineIndices[i + count2] = batch.LineIndices[i] + count;
257 }
258 if (matrix.HasValue
259 && matrix != Matrix.Identity) {
260 TransformLines(matrix.Value, count);
261 }
262 if (color.HasValue
263 && color != Color.White) {
264 TransformLinesColors(color.Value, count);
265 }
266 }
267
269 public void QueueLines(IEnumerable<Vector3> points, Color color) {
270 int count = LineVertices.Count;
271 int i = 0;
272 foreach (Vector3 point in points) {
273 LineVertices.Add(new VertexPositionColor(point, color));
274 if (++i % 2 == 0) {
275 LineIndices.Add(count + i - 2);
276 LineIndices.Add(count + i - 1);
277 }
278 }
279 }
280
281
283 public void QueueLines(IEnumerable<VertexPositionColor> vertices) {
284 int count = LineVertices.Count;
285 int i = 0;
286 foreach (VertexPositionColor vertex in vertices) {
287 LineVertices.Add(vertex);
288 if (++i % 2 == 0) {
289 LineIndices.Add(count + i - 2);
290 LineIndices.Add(count + i - 1);
291 }
292 }
293 }
294
295 public void QueueBatch(FlatBatch3D batch, Matrix? matrix = null, Color? color = null) {
296 QueueBatchLines(batch, matrix, color);
297 QueueBatchTriangles(batch, matrix, color);
298 }
299
300 public void QueueLine(Vector3 p1, Vector3 p2, Color color) {
301 int count = LineVertices.Count;
302 LineVertices.Add(new VertexPositionColor(p1, color));
303 LineVertices.Add(new VertexPositionColor(p2, color));
304 LineIndices.Add(count);
305 LineIndices.Add(count + 1);
306 }
307
308 public void QueueLine(Vector3 p1, Vector3 p2, Color color1, Color color2) {
309 int count = LineVertices.Count;
310 LineVertices.Add(new VertexPositionColor(p1, color1));
311 LineVertices.Add(new VertexPositionColor(p2, color2));
312 LineIndices.Add(count);
313 LineIndices.Add(count + 1);
314 }
315
316 public void QueueLineStrip(IEnumerable<Vector3> points, Color color) {
317 int i = LineVertices.Count;
318 bool notFirst = false;
319 foreach (Vector3 point in points) {
320 LineVertices.Add(new VertexPositionColor(point, color));
321 if (notFirst) {
322 LineIndices.Add(i++);
323 LineIndices.Add(i);
324 }
325 notFirst = true;
326 }
327 }
328
329 public void QueueLineStrip(IEnumerable<VertexPositionColor> vertices) {
330 int i = LineVertices.Count;
331 bool notFirst = false;
332 foreach (VertexPositionColor vertex in vertices) {
333 LineVertices.Add(vertex);
334 if (notFirst) {
335 LineIndices.Add(i++);
336 LineIndices.Add(i);
337 }
338 notFirst = true;
339 }
340 }
341
342 public void QueueTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Color color) {
343 int count = TriangleVertices.Count;
344 TriangleVertices.Add(new VertexPositionColor(p1, color));
345 TriangleVertices.Add(new VertexPositionColor(p2, color));
346 TriangleVertices.Add(new VertexPositionColor(p3, color));
347 TriangleIndices.Add(count);
348 TriangleIndices.Add(count + 1);
349 TriangleIndices.Add(count + 2);
350 }
351
352 public void QueueTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Color color1, Color color2, Color color3) {
353 int count = TriangleVertices.Count;
354 TriangleVertices.Add(new VertexPositionColor(p1, color1));
355 TriangleVertices.Add(new VertexPositionColor(p2, color2));
356 TriangleVertices.Add(new VertexPositionColor(p3, color3));
357 TriangleIndices.Add(count);
358 TriangleIndices.Add(count + 1);
359 TriangleIndices.Add(count + 2);
360 }
361
365 public void QueueQuad(Vector3 p1,
366 Vector3 p2,
367 Vector3 p3,
368 Vector3 p4,
369 Color color1,
370 Color color2,
371 Color color3,
372 Color color4) {
373 int count = TriangleVertices.Count;
374 TriangleVertices.Add(new VertexPositionColor(p1, color1)); // 左上
375 TriangleVertices.Add(new VertexPositionColor(p2, color2)); // 右上
376 TriangleVertices.Add(new VertexPositionColor(p3, color3)); // 左下
377 TriangleVertices.Add(new VertexPositionColor(p4, color4)); // 右下
378 TriangleIndices.Add(count);
379 TriangleIndices.Add(count + 1);
380 TriangleIndices.Add(count + 2);
381 TriangleIndices.Add(count + 2);
382 TriangleIndices.Add(count + 0);
383 TriangleIndices.Add(count + 3);
384 }
385
386 public void QueueQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color color) {
387 int count = TriangleVertices.Count;
388 TriangleVertices.Add(new VertexPositionColor(p1, color));
389 TriangleVertices.Add(new VertexPositionColor(p2, color));
390 TriangleVertices.Add(new VertexPositionColor(p3, color));
391 TriangleVertices.Add(new VertexPositionColor(p4, color));
392 TriangleIndices.Add(count);
393 TriangleIndices.Add(count + 1);
394 TriangleIndices.Add(count + 2);
395 TriangleIndices.Add(count + 2);
396 TriangleIndices.Add(count + 3);
397 TriangleIndices.Add(count);
398 }
399
400 public void QueueBoundingBox(BoundingBox boundingBox, Color color) {
401 QueueLine(
402 new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Min.Z),
403 new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Min.Z),
404 color
405 );
406 QueueLine(
407 new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Min.Z),
408 new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Min.Z),
409 color
410 );
411 QueueLine(
412 new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Min.Z),
413 new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Min.Z),
414 color
415 );
416 QueueLine(
417 new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Min.Z),
418 new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Min.Z),
419 color
420 );
421 QueueLine(
422 new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Max.Z),
423 new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Max.Z),
424 color
425 );
426 QueueLine(
427 new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Max.Z),
428 new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Max.Z),
429 color
430 );
431 QueueLine(
432 new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Max.Z),
433 new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Max.Z),
434 color
435 );
436 QueueLine(
437 new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Max.Z),
438 new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Max.Z),
439 color
440 );
441 QueueLine(
442 new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Min.Z),
443 new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Max.Z),
444 color
445 );
446 QueueLine(
447 new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Min.Z),
448 new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Max.Z),
449 color
450 );
451 QueueLine(
452 new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Min.Z),
453 new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Max.Z),
454 color
455 );
456 QueueLine(
457 new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Min.Z),
458 new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Max.Z),
459 color
460 );
461 }
462
463 public void QueueBoundingFrustum(BoundingFrustum boundingFrustum, Color color) {
464 ReadOnlyList<Vector3> array = boundingFrustum.Corners;
465 QueueLine(array[0], array[1], color);
466 QueueLine(array[1], array[2], color);
467 QueueLine(array[2], array[3], color);
468 QueueLine(array[3], array[0], color);
469 QueueLine(array[4], array[5], color);
470 QueueLine(array[5], array[6], color);
471 QueueLine(array[6], array[7], color);
472 QueueLine(array[7], array[4], color);
473 QueueLine(array[0], array[4], color);
474 QueueLine(array[1], array[5], color);
475 QueueLine(array[2], array[6], color);
476 QueueLine(array[3], array[7], color);
477 }
478
479 public void QueueCube(Vector3 center, float size, Color color) {
480 float halfSize = size / 2f;
481 QueueQuad(
482 new Vector3(center.X - halfSize, center.Y - halfSize, center.Z - halfSize),
483 new Vector3(center.X + halfSize, center.Y - halfSize, center.Z - halfSize),
484 new Vector3(center.X + halfSize, center.Y + halfSize, center.Z - halfSize),
485 new Vector3(center.X - halfSize, center.Y + halfSize, center.Z - halfSize),
486 color
487 );
488 QueueQuad(
489 new Vector3(center.X - halfSize, center.Y - halfSize, center.Z + halfSize),
490 new Vector3(center.X + halfSize, center.Y - halfSize, center.Z + halfSize),
491 new Vector3(center.X + halfSize, center.Y + halfSize, center.Z + halfSize),
492 new Vector3(center.X - halfSize, center.Y + halfSize, center.Z + halfSize),
493 color
494 );
495 QueueQuad(
496 new Vector3(center.X - halfSize, center.Y - halfSize, center.Z - halfSize),
497 new Vector3(center.X - halfSize, center.Y - halfSize, center.Z + halfSize),
498 new Vector3(center.X - halfSize, center.Y + halfSize, center.Z + halfSize),
499 new Vector3(center.X - halfSize, center.Y + halfSize, center.Z - halfSize),
500 color
501 );
502 QueueQuad(
503 new Vector3(center.X + halfSize, center.Y - halfSize, center.Z - halfSize),
504 new Vector3(center.X + halfSize, center.Y - halfSize, center.Z + halfSize),
505 new Vector3(center.X + halfSize, center.Y + halfSize, center.Z + halfSize),
506 new Vector3(center.X + halfSize, center.Y + halfSize, center.Z - halfSize),
507 color
508 );
509 QueueQuad(
510 new Vector3(center.X - halfSize, center.Y - halfSize, center.Z - halfSize),
511 new Vector3(center.X + halfSize, center.Y - halfSize, center.Z - halfSize),
512 new Vector3(center.X + halfSize, center.Y - halfSize, center.Z + halfSize),
513 new Vector3(center.X - halfSize, center.Y - halfSize, center.Z + halfSize),
514 color
515 );
516 QueueQuad(
517 new Vector3(center.X - halfSize, center.Y + halfSize, center.Z - halfSize),
518 new Vector3(center.X + halfSize, center.Y + halfSize, center.Z - halfSize),
519 new Vector3(center.X + halfSize, center.Y + halfSize, center.Z + halfSize),
520 new Vector3(center.X - halfSize, center.Y + halfSize, center.Z + halfSize),
521 color
522 );
523 }
524 }
525}
Engine.Vector3 Vector3
ReadOnlyList< Vector3 > Corners
readonly DynamicArray< int > LineIndices
readonly DynamicArray< int > TriangleIndices
void TransformLines(Matrix matrix, int start=0, int end=-1)
readonly DynamicArray< VertexPositionColor > TriangleVertices
void TransformTrianglesColors(Color color, int start=0, int end=-1)
void TransformLinesColors(Color color, int start=0, int end=-1)
readonly DynamicArray< VertexPositionColor > LineVertices
void TransformTriangles(Matrix matrix, int start=0, int end=-1)
static readonly BlendState AlphaBlend
static readonly DepthStencilState Default
void QueueLines(IEnumerable< Vector3 > points, Color color)
每两个顶点为一个线段,请确保输入的顶点数量为 2 的倍数
void QueueBoundingBox(BoundingBox boundingBox, Color color)
void QueueBatch(FlatBatch3D batch, Matrix? matrix=null, Color? color=null)
void QueueLineStrip(IEnumerable< Vector3 > points, Color color)
void QueueLines(IEnumerable< VertexPositionColor > vertices)
每两个顶点为一个线段,请确保输入的顶点数量为 2 的倍数
void QueueCurvedCylinder(Vector3 start, Vector3 end, float radius, Color color, int segments=12, bool drawTopAndBottom=true)
绘制圆柱
void QueueSphere(Vector3 center, float radius, int slices, int stacks, Color color)
绘制球
void QueueBatchTriangles(FlatBatch3D batch, Matrix? matrix=null, Color? color=null)
void QueueBatchLines(FlatBatch3D batch, Matrix? matrix=null, Color? color=null)
void QueueTriangles(IEnumerable< VertexPositionColor > vertices)
每三个顶点为一个三角形,请确保输入的顶点数量为 3 的倍数
void QueueCircle(Vector3 center, float radius, int segments, Color color, bool useLineStrip=true)
绘制圆
void QueueQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color color)
void QueueLine(Vector3 p1, Vector3 p2, Color color)
void QueueLine(Vector3 p1, Vector3 p2, Color color1, Color color2)
void QueueLineStrip(IEnumerable< VertexPositionColor > vertices)
void QueueCube(Vector3 center, float size, Color color)
void QueueQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color color1, Color color2, Color color3, Color color4)
绘制矩形(支持渐变)
void QueueBoundingFrustum(BoundingFrustum boundingFrustum, Color color)
void QueueTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Color color)
void QueueTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Color color1, Color color2, Color color3)
void QueueTriangles(IEnumerable< Vector3 > points, Color color)
每三个顶点为一个三角形,请确保输入的顶点数量为 3 的倍数
void QueueSphereWithLines(Vector3 center, Color color, float radius=1, int longitudeLines=20, int latitudeLines=20, int draw=0)
绘制球线框
static readonly RasterizerState CullNoneScissor
static Color White
static readonly Matrix Identity
static Vector3 Normalize(Vector3 v)
static float Distance(Vector3 v1, Vector3 v2)