/* * Copyright (C) 2012-2020 CypherCore * Copyright (C) 2003-2004 Eran Kampf eran@ekampf.com http://www.ekampf.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System; using System.Runtime.Serialization; using System.Security.Permissions; namespace Framework.GameMath { /// /// An enumeration representing the sides of the plane. /// public enum PlaneSide { /// /// Represents the plane itself. /// None, /// /// Represents the positive halfspace of the plane (the side where the normal points to). /// Positive, /// /// Represents the negative halfspace of the plane /// Negative } /// /// Represents a plane in 3D space. /// /// /// The plane is described by a normal and a constant (N,D) which /// denotes that the plane is consisting of points Q that /// satisfies (N dot Q)+D = 0. /// [Serializable] public struct Plane : ISerializable, ICloneable { #region Private Fields private Vector3 _normal; private float _const; #endregion #region Constructors /// /// Initializes a new instance of the class using given normal and constant values. /// /// The plane's normal vector. /// The plane's constant value. public Plane(Vector3 normal, float constant) { _normal = normal; _const = constant; } /// /// Initializes a new instance of the class using given normal and a point. /// /// The plane's normal vector. /// A point on the plane in 3D space. public Plane(Vector3 normal, Vector3 point) { _normal = normal; _const = Vector3.DotProduct(normal, point); } /// /// Initializes a new instance of the class using 3 given points. /// /// A point on the plane in 3D space. /// A point on the plane in 3D space. /// A point on the plane in 3D space. public Plane(Vector3 p0, Vector3 p1, Vector3 p2) { _normal = Vector3.CrossProduct(p2 - p1, p0 - p1); _normal.Normalize(); _const = Vector3.DotProduct(_normal, p0); } /// /// Initializes a new instance of the class using given a plane to assign values from. /// /// A 3D plane to assign values from. public Plane(Plane p) { _normal = p.Normal; _const = p.Constant; } /// /// Initializes a new instance of the class with serialized data. /// /// The object that holds the serialized object data. /// The contextual information about the source or destination. private Plane(SerializationInfo info, StreamingContext context) { _normal = (Vector3)info.GetValue("Normal", typeof(Vector3)); _const = info.GetSingle("Constant"); } #endregion #region Constants /// /// Plane on the X axis. /// public static readonly Plane XPlane = new(Vector3.XAxis, Vector3.Zero); /// /// Plane on the Y axis. /// public static readonly Plane YPlane = new(Vector3.YAxis, Vector3.Zero); /// /// Plane on the Z axis. /// public static readonly Plane ZPlane = new(Vector3.ZAxis, Vector3.Zero); #endregion #region Public Properties /// /// Gets or sets the plane's normal vector. /// public Vector3 Normal { get { return _normal; } set { _normal = value; } } /// /// Gets or sets the plane's constant value. /// public float Constant { get { return _const; } set { _const = value; } } #endregion #region ICloneable Members /// /// Creates an exact copy of this object. /// /// The object this method creates, cast as an object. object ICloneable.Clone() { return new Plane(this); } /// /// Creates an exact copy of this object. /// /// The object this method creates. public Plane Clone() { return new Plane(this); } #endregion #region ISerializable Members /// /// Populates a with the data needed to serialize the target object. /// /// The to populate with data. /// The destination (see ) for this serialization. //[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Normal", _normal, typeof(Vector3)); info.AddValue("Constant", _const); } #endregion #region Public Methods /// /// Flip the plane. /// public void Flip() { _normal = -_normal; } /// /// Creates a new flipped plane (-normal, constant). /// /// A new instance. public Plane GetFlipped() { return new Plane(-_normal, _const); } /// /// Get the shortest distance from a 3D vector to the plane. /// /// A instance. /// A float representing the shortest distance from the given vector to the plane. public float GetDistanceToPlane(Vector3 p) { return Vector3.DotProduct(p, Normal) - Constant; } public void getEquation(ref Vector3 n, out float d) { double _d; getEquation(ref n, out _d); d = (float)_d; } void getEquation(ref Vector3 n, out double d) { n = _normal; d = -_const; } #endregion #region Overrides /// /// Returns the hashcode for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return _normal.GetHashCode() ^ _const.GetHashCode(); } /// /// Returns a value indicating whether this instance is equal to /// the specified object. /// /// An object to compare to this instance. /// True if is a and has the same values as this instance; otherwise, False. public override bool Equals(object obj) { if (obj is Plane) { Plane p = (Plane)obj; return (_normal == p.Normal) && (_const == p.Constant); } return false; } /// /// Returns a string representation of this object. /// /// A string representation of this object. public override string ToString() { return $"Plane[n={_normal}, c={_const}]"; } #endregion } }