123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- using System;
- #if REAL_T_IS_DOUBLE
- using real_t = System.Double;
- #else
- using real_t = System.Single;
- #endif
- namespace Godot
- {
- public struct Plane : IEquatable<Plane>
- {
- private Vector3 _normal;
- public Vector3 Normal
- {
- get { return _normal; }
- set { _normal = value; }
- }
- public real_t x
- {
- get
- {
- return _normal.x;
- }
- set
- {
- _normal.x = value;
- }
- }
- public real_t y
- {
- get
- {
- return _normal.y;
- }
- set
- {
- _normal.y = value;
- }
- }
- public real_t z
- {
- get
- {
- return _normal.z;
- }
- set
- {
- _normal.z = value;
- }
- }
- public real_t D { get; set; }
- public Vector3 Center
- {
- get
- {
- return _normal * D;
- }
- }
- public real_t DistanceTo(Vector3 point)
- {
- return _normal.Dot(point) - D;
- }
- public Vector3 GetAnyPoint()
- {
- return _normal * D;
- }
- public bool HasPoint(Vector3 point, real_t epsilon = Mathf.Epsilon)
- {
- real_t dist = _normal.Dot(point) - D;
- return Mathf.Abs(dist) <= epsilon;
- }
- public Vector3 Intersect3(Plane b, Plane c)
- {
- real_t denom = _normal.Cross(b._normal).Dot(c._normal);
- if (Mathf.Abs(denom) <= Mathf.Epsilon)
- return new Vector3();
- Vector3 result = b._normal.Cross(c._normal) * D +
- c._normal.Cross(_normal) * b.D +
- _normal.Cross(b._normal) * c.D;
- return result / denom;
- }
- public Vector3 IntersectRay(Vector3 from, Vector3 dir)
- {
- real_t den = _normal.Dot(dir);
- if (Mathf.Abs(den) <= Mathf.Epsilon)
- return new Vector3();
- real_t dist = (_normal.Dot(from) - D) / den;
- // This is a ray, before the emitting pos (from) does not exist
- if (dist > Mathf.Epsilon)
- return new Vector3();
- return from + dir * -dist;
- }
- public Vector3 IntersectSegment(Vector3 begin, Vector3 end)
- {
- Vector3 segment = begin - end;
- real_t den = _normal.Dot(segment);
- if (Mathf.Abs(den) <= Mathf.Epsilon)
- return new Vector3();
- real_t dist = (_normal.Dot(begin) - D) / den;
- if (dist < -Mathf.Epsilon || dist > 1.0f + Mathf.Epsilon)
- return new Vector3();
- return begin + segment * -dist;
- }
- public bool IsPointOver(Vector3 point)
- {
- return _normal.Dot(point) > D;
- }
- public Plane Normalized()
- {
- real_t len = _normal.Length();
- if (len == 0)
- return new Plane(0, 0, 0, 0);
- return new Plane(_normal / len, D / len);
- }
- public Vector3 Project(Vector3 point)
- {
- return point - _normal * DistanceTo(point);
- }
- // Constants
- private static readonly Plane _planeYZ = new Plane(1, 0, 0, 0);
- private static readonly Plane _planeXZ = new Plane(0, 1, 0, 0);
- private static readonly Plane _planeXY = new Plane(0, 0, 1, 0);
- public static Plane PlaneYZ { get { return _planeYZ; } }
- public static Plane PlaneXZ { get { return _planeXZ; } }
- public static Plane PlaneXY { get { return _planeXY; } }
- // Constructors
- public Plane(real_t a, real_t b, real_t c, real_t d)
- {
- _normal = new Vector3(a, b, c);
- this.D = d;
- }
- public Plane(Vector3 normal, real_t d)
- {
- this._normal = normal;
- this.D = d;
- }
- public Plane(Vector3 v1, Vector3 v2, Vector3 v3)
- {
- _normal = (v1 - v3).Cross(v1 - v2);
- _normal.Normalize();
- D = _normal.Dot(v1);
- }
- public static Plane operator -(Plane plane)
- {
- return new Plane(-plane._normal, -plane.D);
- }
- public static bool operator ==(Plane left, Plane right)
- {
- return left.Equals(right);
- }
- public static bool operator !=(Plane left, Plane right)
- {
- return !left.Equals(right);
- }
- public override bool Equals(object obj)
- {
- if (obj is Plane)
- {
- return Equals((Plane)obj);
- }
- return false;
- }
- public bool Equals(Plane other)
- {
- return _normal == other._normal && Mathf.IsEqualApprox(D, other.D);
- }
- public override int GetHashCode()
- {
- return _normal.GetHashCode() ^ D.GetHashCode();
- }
- public override string ToString()
- {
- return String.Format("({0}, {1})", new object[]
- {
- _normal.ToString(),
- D.ToString()
- });
- }
- public string ToString(string format)
- {
- return String.Format("({0}, {1})", new object[]
- {
- _normal.ToString(format),
- D.ToString(format)
- });
- }
- }
- }
|