﻿using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FalcoEngine { public struct Plane { internal const int size = 16; private Vector3 m_Normal; private float m_Distance; /// /// Normal vector of the plane. /// public Vector3 normal { get { return m_Normal; } set { m_Normal = value; } } /// /// Distance from the origin to the plane. /// public float distance { get { return m_Distance; } set { m_Distance = value; } } /// /// Returns a copy of the plane that faces in the opposite direction. /// public Plane flipped => new Plane(-m_Normal, 0f - m_Distance); /// /// Creates a plane. /// /// /// public Plane(Vector3 inNormal, Vector3 inPoint) { m_Normal = Vector3.Normalize(inNormal); m_Distance = 0f - Vector3.Dot(m_Normal, inPoint); } /// /// Creates a plane. /// /// /// public Plane(Vector3 inNormal, float d) { m_Normal = Vector3.Normalize(inNormal); m_Distance = d; } /// /// Creates a plane. /// /// /// /// public Plane(Vector3 a, Vector3 b, Vector3 c) { m_Normal = Vector3.Normalize(Vector3.Cross(b - a, c - a)); m_Distance = 0f - Vector3.Dot(m_Normal, a); } /// /// Sets a plane using a point that lies within it along with a normal to orient it. /// /// The plane's normal vector. /// A point that lies on the plane. public void SetNormalAndPosition(Vector3 inNormal, Vector3 inPoint) { m_Normal = Vector3.Normalize(inNormal); m_Distance = 0f - Vector3.Dot(inNormal, inPoint); } /// /// Sets a plane using three points that lie within it. The points go around clockwise as you look down on the top surface of the plane. /// /// First point in clockwise order. /// Second point in clockwise order. /// Third point in clockwise order. public void Set3Points(Vector3 a, Vector3 b, Vector3 c) { m_Normal = Vector3.Normalize(Vector3.Cross(b - a, c - a)); m_Distance = 0f - Vector3.Dot(m_Normal, a); } /// /// Makes the plane face in the opposite direction. /// public void Flip() { m_Normal = -m_Normal; m_Distance = 0f - m_Distance; } /// /// Moves the plane in space by the translation vector. /// /// The offset in space to move the plane with. public void Translate(Vector3 translation) { m_Distance += Vector3.Dot(m_Normal, translation); } /// /// Returns a copy of the given plane that is moved in space by the given translation. /// /// The plane to move in space. /// The offset in space to move the plane with. /// /// The translated plane. /// public static Plane Translate(Plane plane, Vector3 translation) { return new Plane(plane.m_Normal, plane.m_Distance += Vector3.Dot(plane.m_Normal, translation)); } /// /// For a given point returns the closest point on the plane. /// /// The point to project onto the plane. /// /// A point on the plane that is closest to point. /// public Vector3 ClosestPointOnPlane(Vector3 point) { float d = Vector3.Dot(m_Normal, point) + m_Distance; return point - m_Normal * d; } /// /// Returns a signed distance from plane to point. /// /// public float GetDistanceToPoint(Vector3 point) { return Vector3.Dot(m_Normal, point) + m_Distance; } /// /// Is a point on the positive side of the plane? /// /// public bool GetSide(Vector3 point) { return Vector3.Dot(m_Normal, point) + m_Distance > 0f; } /// /// Are two points on the same side of the plane? /// /// /// public bool SameSide(Vector3 inPt0, Vector3 inPt1) { float distanceToPoint = GetDistanceToPoint(inPt0); float distanceToPoint2 = GetDistanceToPoint(inPt1); return (distanceToPoint > 0f && distanceToPoint2 > 0f) || (distanceToPoint <= 0f && distanceToPoint2 <= 0f); } public bool Raycast(Ray ray, out float enter) { float num = Vector3.Dot(ray.direction, m_Normal); float num2 = 0f - Vector3.Dot(ray.origin, m_Normal) - m_Distance; if (Mathf.Approximately(num, 0f)) { enter = 0f; return false; } enter = num2 / num; return enter > 0f; } public override string ToString() { return String.Format("(normal:({0:F1}, {1:F1}, {2:F1}), distance:{3:F1})", m_Normal.x, m_Normal.y, m_Normal.z, m_Distance); } public string ToString(string format) { return String.Format("(normal:({0}, {1}, {2}), distance:{3})", m_Normal.x.ToString(format), m_Normal.y.ToString(format), m_Normal.z.ToString(format), m_Distance.ToString(format)); } } }