Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
BoundingFrustum.cs
Go to the documentation of this file.
1using System;
4
6
9public class BoundingFrustum : IEquatable<BoundingFrustum>
10{
11 public const int CornerCount = 8;
12
13 private const int NearPlaneIndex = 0;
14
15 private const int FarPlaneIndex = 1;
16
17 private const int LeftPlaneIndex = 2;
18
19 private const int RightPlaneIndex = 3;
20
21 private const int TopPlaneIndex = 4;
22
23 private const int BottomPlaneIndex = 5;
24
25 private const int NumPlanes = 6;
26
27 private Matrix matrix;
28
29 private Plane[] planes = new Plane[6];
30
31 internal Vector3[] cornerArray = new Vector3[8];
32
33 private Gjk gjk;
34
35 public Plane Near => planes[0];
36
37 public Plane Far => planes[1];
38
39 public Plane Left => planes[2];
40
41 public Plane Right => planes[3];
42
43 public Plane Top => planes[4];
44
45 public Plane Bottom => planes[5];
46
48 {
49 get
50 {
51 return matrix;
52 }
53 set
54 {
55 SetMatrix(ref value);
56 }
57 }
58
60 {
61 return (Vector3[])cornerArray.Clone();
62 }
63
64 public void GetCorners(Vector3[] corners)
65 {
66 if (corners == null)
67 {
68 throw new ArgumentNullException("corners");
69 }
70 if (corners.Length < 8)
71 {
73 }
74 cornerArray.CopyTo(corners, 0);
75 }
76
78 {
79 if (other == null)
80 {
81 return false;
82 }
83 return matrix == other.matrix;
84 }
85
86 public override bool Equals(object obj)
87 {
88 bool result = false;
89 BoundingFrustum boundingFrustum = obj as BoundingFrustum;
90 if (boundingFrustum != null)
91 {
92 result = matrix == boundingFrustum.matrix;
93 }
94 return result;
95 }
96
97 public override int GetHashCode()
98 {
99 return matrix.GetHashCode();
100 }
101
102 public override string ToString()
103 {
104 CultureInfo currentCulture = CultureInfo.CurrentCulture;
105 return string.Format(currentCulture, "{{Near:{0} Far:{1} Left:{2} Right:{3} Top:{4} Bottom:{5}}}", Near.ToString(), Far.ToString(), Left.ToString(), Right.ToString(), Top.ToString(), Bottom.ToString());
106 }
107
109 {
110 }
111
113 {
114 SetMatrix(ref value);
115 }
116
117 private void SetMatrix(ref Matrix value)
118 {
119 matrix = value;
120 planes[2].Normal.X = 0f - value.M14 - value.M11;
121 planes[2].Normal.Y = 0f - value.M24 - value.M21;
122 planes[2].Normal.Z = 0f - value.M34 - value.M31;
123 planes[2].D = 0f - value.M44 - value.M41;
124 planes[3].Normal.X = 0f - value.M14 + value.M11;
125 planes[3].Normal.Y = 0f - value.M24 + value.M21;
126 planes[3].Normal.Z = 0f - value.M34 + value.M31;
127 planes[3].D = 0f - value.M44 + value.M41;
128 planes[4].Normal.X = 0f - value.M14 + value.M12;
129 planes[4].Normal.Y = 0f - value.M24 + value.M22;
130 planes[4].Normal.Z = 0f - value.M34 + value.M32;
131 planes[4].D = 0f - value.M44 + value.M42;
132 planes[5].Normal.X = 0f - value.M14 - value.M12;
133 planes[5].Normal.Y = 0f - value.M24 - value.M22;
134 planes[5].Normal.Z = 0f - value.M34 - value.M32;
135 planes[5].D = 0f - value.M44 - value.M42;
136 planes[0].Normal.X = 0f - value.M13;
137 planes[0].Normal.Y = 0f - value.M23;
138 planes[0].Normal.Z = 0f - value.M33;
139 planes[0].D = 0f - value.M43;
140 planes[1].Normal.X = 0f - value.M14 + value.M13;
141 planes[1].Normal.Y = 0f - value.M24 + value.M23;
142 planes[1].Normal.Z = 0f - value.M34 + value.M33;
143 planes[1].D = 0f - value.M44 + value.M43;
144 for (int i = 0; i < 6; i++)
145 {
146 float num = planes[i].Normal.Length();
147 planes[i].Normal /= num;
148 planes[i].D /= num;
149 }
150 Ray ray = ComputeIntersectionLine(ref planes[0], ref planes[2]);
151 ref Vector3 reference = ref cornerArray[0];
152 reference = ComputeIntersection(ref planes[4], ref ray);
153 ref Vector3 reference2 = ref cornerArray[3];
154 reference2 = ComputeIntersection(ref planes[5], ref ray);
155 ray = ComputeIntersectionLine(ref planes[3], ref planes[0]);
156 ref Vector3 reference3 = ref cornerArray[1];
157 reference3 = ComputeIntersection(ref planes[4], ref ray);
158 ref Vector3 reference4 = ref cornerArray[2];
159 reference4 = ComputeIntersection(ref planes[5], ref ray);
160 ray = ComputeIntersectionLine(ref planes[2], ref planes[1]);
161 ref Vector3 reference5 = ref cornerArray[4];
162 reference5 = ComputeIntersection(ref planes[4], ref ray);
163 ref Vector3 reference6 = ref cornerArray[7];
164 reference6 = ComputeIntersection(ref planes[5], ref ray);
165 ray = ComputeIntersectionLine(ref planes[1], ref planes[3]);
166 ref Vector3 reference7 = ref cornerArray[5];
167 reference7 = ComputeIntersection(ref planes[4], ref ray);
168 ref Vector3 reference8 = ref cornerArray[6];
169 reference8 = ComputeIntersection(ref planes[5], ref ray);
170 }
171
172 private static Ray ComputeIntersectionLine(ref Plane p1, ref Plane p2)
173 {
174 Ray result = default(Ray);
175 result.Direction = Vector3.Cross(p1.Normal, p2.Normal);
176 float num = result.Direction.LengthSquared();
177 result.Position = Vector3.Cross((0f - p1.D) * p2.Normal + p2.D * p1.Normal, result.Direction) / num;
178 return result;
179 }
180
181 private static Vector3 ComputeIntersection(ref Plane plane, ref Ray ray)
182 {
183 float num = (0f - plane.D - Vector3.Dot(plane.Normal, ray.Position)) / Vector3.Dot(plane.Normal, ray.Direction);
184 return ray.Position + ray.Direction * num;
185 }
186
187 public bool Intersects(BoundingBox box)
188 {
189 Intersects(ref box, out var result);
190 return result;
191 }
192
193 public void Intersects(ref BoundingBox box, out bool result)
194 {
195 if (gjk == null)
196 {
197 gjk = new Gjk();
198 }
199 gjk.Reset();
200 Vector3.Subtract(ref cornerArray[0], ref box.Min, out var result2);
201 if (result2.LengthSquared() < 1E-05f)
202 {
203 Vector3.Subtract(ref cornerArray[0], ref box.Max, out result2);
204 }
205 float num = float.MaxValue;
206 float num2 = 0f;
207 result = false;
208 Vector3 v = default(Vector3);
209 do
210 {
211 v.X = 0f - result2.X;
212 v.Y = 0f - result2.Y;
213 v.Z = 0f - result2.Z;
214 SupportMapping(ref v, out var result3);
215 box.SupportMapping(ref result2, out var result4);
216 Vector3.Subtract(ref result3, ref result4, out var result5);
217 float num3 = result2.X * result5.X + result2.Y * result5.Y + result2.Z * result5.Z;
218 if (num3 > 0f)
219 {
220 return;
221 }
222 gjk.AddSupportPoint(ref result5);
223 result2 = gjk.ClosestPoint;
224 float num4 = num;
225 num = result2.LengthSquared();
226 if (num4 - num <= 1E-05f * num4)
227 {
228 return;
229 }
230 num2 = 4E-05f * gjk.MaxLengthSquared;
231 }
232 while (!gjk.FullSimplex && num >= num2);
233 result = true;
234 }
235
236 public bool Intersects(BoundingFrustum frustum)
237 {
238 if (frustum == null)
239 {
240 throw new ArgumentNullException("frustum");
241 }
242 if (gjk == null)
243 {
244 gjk = new Gjk();
245 }
246 gjk.Reset();
247 Vector3.Subtract(ref cornerArray[0], ref frustum.cornerArray[0], out var result);
248 if (result.LengthSquared() < 1E-05f)
249 {
250 Vector3.Subtract(ref cornerArray[0], ref frustum.cornerArray[1], out result);
251 }
252 float num = float.MaxValue;
253 float num2 = 0f;
254 Vector3 v = default(Vector3);
255 do
256 {
257 v.X = 0f - result.X;
258 v.Y = 0f - result.Y;
259 v.Z = 0f - result.Z;
260 SupportMapping(ref v, out var result2);
261 frustum.SupportMapping(ref result, out var result3);
262 Vector3.Subtract(ref result2, ref result3, out var result4);
263 float num3 = result.X * result4.X + result.Y * result4.Y + result.Z * result4.Z;
264 if (num3 > 0f)
265 {
266 return false;
267 }
268 gjk.AddSupportPoint(ref result4);
269 result = gjk.ClosestPoint;
270 float num4 = num;
271 num = result.LengthSquared();
272 num2 = 4E-05f * gjk.MaxLengthSquared;
273 if (num4 - num <= 1E-05f * num4)
274 {
275 return false;
276 }
277 }
278 while (!gjk.FullSimplex && num >= num2);
279 return true;
280 }
281
283 {
284 int num = 0;
285 for (int i = 0; i < 8; i++)
286 {
287 Vector3.Dot(ref cornerArray[i], ref plane.Normal, out var result);
288 num = ((!(result + plane.D > 0f)) ? (num | 2) : (num | 1));
289 if (num == 3)
290 {
291 return PlaneIntersectionType.Intersecting;
292 }
293 }
294 if (num != 1)
295 {
296 return PlaneIntersectionType.Back;
297 }
298 return PlaneIntersectionType.Front;
299 }
300
301 public void Intersects(ref Plane plane, out PlaneIntersectionType result)
302 {
303 int num = 0;
304 for (int i = 0; i < 8; i++)
305 {
306 Vector3.Dot(ref cornerArray[i], ref plane.Normal, out var result2);
307 num = ((!(result2 + plane.D > 0f)) ? (num | 2) : (num | 1));
308 if (num == 3)
309 {
310 result = PlaneIntersectionType.Intersecting;
311 return;
312 }
313 }
314 result = ((num != 1) ? PlaneIntersectionType.Back : PlaneIntersectionType.Front);
315 }
316
317 public float? Intersects(Ray ray)
318 {
319 Intersects(ref ray, out var result);
320 return result;
321 }
322
323 public void Intersects(ref Ray ray, out float? result)
324 {
325 Contains(ref ray.Position, out var result2);
326 if (result2 == ContainmentType.Contains)
327 {
328 result = 0f;
329 return;
330 }
331 float num = float.MinValue;
332 float num2 = float.MaxValue;
333 result = null;
334 Plane[] array = planes;
335 for (int i = 0; i < array.Length; i++)
336 {
337 Plane plane = array[i];
338 Vector3 vector = plane.Normal;
339 Vector3.Dot(ref ray.Direction, ref vector, out var result3);
340 Vector3.Dot(ref ray.Position, ref vector, out var result4);
341 result4 += plane.D;
342 if (Math.Abs(result3) < 1E-05f)
343 {
344 if (result4 > 0f)
345 {
346 return;
347 }
348 continue;
349 }
350 float num3 = (0f - result4) / result3;
351 if (result3 < 0f)
352 {
353 if (num3 > num2)
354 {
355 return;
356 }
357 if (num3 > num)
358 {
359 num = num3;
360 }
361 }
362 else
363 {
364 if (num3 < num)
365 {
366 return;
367 }
368 if (num3 < num2)
369 {
370 num2 = num3;
371 }
372 }
373 }
374 float num4 = ((num >= 0f) ? num : num2);
375 if (num4 >= 0f)
376 {
377 result = num4;
378 }
379 }
380
381 public bool Intersects(BoundingSphere sphere)
382 {
383 Intersects(ref sphere, out var result);
384 return result;
385 }
386
387 public void Intersects(ref BoundingSphere sphere, out bool result)
388 {
389 if (gjk == null)
390 {
391 gjk = new Gjk();
392 }
393 gjk.Reset();
394 Vector3.Subtract(ref cornerArray[0], ref sphere.Center, out var result2);
395 if (result2.LengthSquared() < 1E-05f)
396 {
397 result2 = Vector3.UnitX;
398 }
399 float num = float.MaxValue;
400 float num2 = 0f;
401 result = false;
402 Vector3 v = default(Vector3);
403 do
404 {
405 v.X = 0f - result2.X;
406 v.Y = 0f - result2.Y;
407 v.Z = 0f - result2.Z;
408 SupportMapping(ref v, out var result3);
409 sphere.SupportMapping(ref result2, out var result4);
410 Vector3.Subtract(ref result3, ref result4, out var result5);
411 float num3 = result2.X * result5.X + result2.Y * result5.Y + result2.Z * result5.Z;
412 if (num3 > 0f)
413 {
414 return;
415 }
416 gjk.AddSupportPoint(ref result5);
417 result2 = gjk.ClosestPoint;
418 float num4 = num;
419 num = result2.LengthSquared();
420 if (num4 - num <= 1E-05f * num4)
421 {
422 return;
423 }
424 num2 = 4E-05f * gjk.MaxLengthSquared;
425 }
426 while (!gjk.FullSimplex && num >= num2);
427 result = true;
428 }
429
431 {
432 bool flag = false;
433 Plane[] array = planes;
434 foreach (Plane plane in array)
435 {
436 switch (box.Intersects(plane))
437 {
438 case PlaneIntersectionType.Front:
439 return ContainmentType.Disjoint;
440 case PlaneIntersectionType.Intersecting:
441 flag = true;
442 break;
443 }
444 }
445 if (!flag)
446 {
447 return ContainmentType.Contains;
448 }
450 }
451
452 public void Contains(ref BoundingBox box, out ContainmentType result)
453 {
454 bool flag = false;
455 Plane[] array = planes;
456 foreach (Plane plane in array)
457 {
458 switch (box.Intersects(plane))
459 {
460 case PlaneIntersectionType.Front:
461 result = ContainmentType.Disjoint;
462 return;
463 case PlaneIntersectionType.Intersecting:
464 flag = true;
465 break;
466 }
467 }
468 result = ((!flag) ? ContainmentType.Contains : ContainmentType.Intersects);
469 }
470
472 {
473 if (frustum == null)
474 {
475 throw new ArgumentNullException("frustum");
476 }
477 ContainmentType result = ContainmentType.Disjoint;
478 if (Intersects(frustum))
479 {
480 result = ContainmentType.Contains;
481 for (int i = 0; i < cornerArray.Length; i++)
482 {
483 if (Contains(frustum.cornerArray[i]) == ContainmentType.Disjoint)
484 {
485 result = ContainmentType.Intersects;
486 break;
487 }
488 }
489 }
490 return result;
491 }
492
494 {
495 Plane[] array = planes;
496 for (int i = 0; i < array.Length; i++)
497 {
498 Plane plane = array[i];
499 float num = plane.Normal.X * point.X + plane.Normal.Y * point.Y + plane.Normal.Z * point.Z + plane.D;
500 if (num > 1E-05f)
501 {
502 return ContainmentType.Disjoint;
503 }
504 }
505 return ContainmentType.Contains;
506 }
507
508 public void Contains(ref Vector3 point, out ContainmentType result)
509 {
510 Plane[] array = planes;
511 for (int i = 0; i < array.Length; i++)
512 {
513 Plane plane = array[i];
514 float num = plane.Normal.X * point.X + plane.Normal.Y * point.Y + plane.Normal.Z * point.Z + plane.D;
515 if (num > 1E-05f)
516 {
517 result = ContainmentType.Disjoint;
518 return;
519 }
520 }
521 result = ContainmentType.Contains;
522 }
523
525 {
526 Vector3 center = sphere.Center;
527 float radius = sphere.Radius;
528 int num = 0;
529 Plane[] array = planes;
530 for (int i = 0; i < array.Length; i++)
531 {
532 Plane plane = array[i];
533 float num2 = plane.Normal.X * center.X + plane.Normal.Y * center.Y + plane.Normal.Z * center.Z;
534 float num3 = num2 + plane.D;
535 if (num3 > radius)
536 {
537 return ContainmentType.Disjoint;
538 }
539 if (num3 < 0f - radius)
540 {
541 num++;
542 }
543 }
544 if (num != 6)
545 {
546 return ContainmentType.Intersects;
547 }
548 return ContainmentType.Contains;
549 }
550
551 public void Contains(ref BoundingSphere sphere, out ContainmentType result)
552 {
553 Vector3 center = sphere.Center;
554 float radius = sphere.Radius;
555 int num = 0;
556 Plane[] array = planes;
557 for (int i = 0; i < array.Length; i++)
558 {
559 Plane plane = array[i];
560 float num2 = plane.Normal.X * center.X + plane.Normal.Y * center.Y + plane.Normal.Z * center.Z;
561 float num3 = num2 + plane.D;
562 if (num3 > radius)
563 {
564 result = ContainmentType.Disjoint;
565 return;
566 }
567 if (num3 < 0f - radius)
568 {
569 num++;
570 }
571 }
572 result = ((num == 6) ? ContainmentType.Contains : ContainmentType.Intersects);
573 }
574
575 internal void SupportMapping(ref Vector3 v, out Vector3 result)
576 {
577 int num = 0;
578 Vector3.Dot(ref cornerArray[0], ref v, out var result2);
579 for (int i = 1; i < cornerArray.Length; i++)
580 {
581 Vector3.Dot(ref cornerArray[i], ref v, out var result3);
582 if (result3 > result2)
583 {
584 num = i;
585 result2 = result3;
586 }
587 }
588 result = cornerArray[num];
589 }
590
592 {
593 return object.Equals(a, b);
594 }
595
597 {
598 return !object.Equals(a, b);
599 }
600}
ContainmentType Contains(BoundingFrustum frustum)
void Intersects(ref Plane plane, out PlaneIntersectionType result)
static bool operator==(BoundingFrustum a, BoundingFrustum b)
void Contains(ref Vector3 point, out ContainmentType result)
void Contains(ref BoundingSphere sphere, out ContainmentType result)
void Intersects(ref Ray ray, out float? result)
bool Equals(BoundingFrustum other)
void Intersects(ref BoundingBox box, out bool result)
bool Intersects(BoundingFrustum frustum)
static Vector3 ComputeIntersection(ref Plane plane, ref Ray ray)
PlaneIntersectionType Intersects(Plane plane)
void Contains(ref BoundingBox box, out ContainmentType result)
void SupportMapping(ref Vector3 v, out Vector3 result)
ContainmentType Contains(BoundingSphere sphere)
bool Intersects(BoundingSphere sphere)
void Intersects(ref BoundingSphere sphere, out bool result)
static bool operator!=(BoundingFrustum a, BoundingFrustum b)
ContainmentType Contains(Vector3 point)
static Ray ComputeIntersectionLine(ref Plane p1, ref Plane p2)
ContainmentType Contains(BoundingBox box)
bool AddSupportPoint(ref Vector3 newPoint)
Definition Gjk.cs:67
static CultureInfo CurrentCulture
static double Abs(double value)
PlaneIntersectionType Intersects(BoundingBox box)
Definition Plane.cs:265
override string ToString()
Definition Plane.cs:84
static Vector3 Min(Vector3 value1, Vector3 value2)
Definition Vector3.cs:241
static float Dot(Vector3 vector1, Vector3 vector2)
Definition Vector3.cs:165
static Vector3 Subtract(Vector3 value1, Vector3 value2)
Definition Vector3.cs:745
static Vector3 Max(Vector3 value1, Vector3 value2)
Definition Vector3.cs:257
static Vector3 Cross(Vector3 vector1, Vector3 vector2)
Definition Vector3.cs:204