Exemple #1
0
    /// <summary>
    /// returns true if a line collides with the plane
    /// points are float4 homogeneus coordenates
    /// </summary>
    /// <param name="linePointA"></param>
    /// <param name="linePointB"></param>
    /// <param name="hitPoint">stores the hit point if exists</param>
    /// <returns></returns>
    public static bool ComputLineHit(PlaneStruct plane, float3 linePointA, float3 linePointB, out float3 hitPoint)
    {
        hitPoint = float3.zero;

        float3 delta = linePointB - linePointA;

        var nominator = plane._displacement - (plane.Normal.x * linePointA.x) - (plane.Normal.y * linePointA.y) - (plane.Normal.z * linePointA.z);

        float denominator = (plane.Normal.x * delta.x) + (plane.Normal.y * delta.y) + (plane.Normal.z * delta.z);

        if (denominator == 0f)
        {
            return(false);
        }

        float t = nominator / denominator;

        var deltaScaled = delta * t;

        if (t > 1f || t < 0)
        {
            return(false);
        }

        hitPoint = new float3(
            linePointA.x + deltaScaled.x,
            linePointA.y + deltaScaled.y,
            linePointA.z + deltaScaled.z);

        return(IsInPlaneLimits(plane, hitPoint));
    }
Exemple #2
0
    /// <summary>
    /// return a positive number if the point is in the same side as the normal from the plane
    /// return a negative number if the point is in the contrary side of the normal from the plane
    /// </summary>
    /// <param name="point"></param>
    /// <returns></returns>
    private static float GetPointSide(PlaneStruct plane, float3 point)
    {
        var deltaPoint = point - plane.PointA;

        return(deltaPoint.x * (plane.DeltaB.y * plane.DeltaC.z - plane.DeltaB.z * plane.DeltaC.y) -
               deltaPoint.y * (plane.DeltaB.x * plane.DeltaC.z - plane.DeltaB.z * plane.DeltaC.x) +
               deltaPoint.z * (plane.DeltaB.x * plane.DeltaC.y - plane.DeltaB.y * plane.DeltaC.x));
    }
Exemple #3
0
    /// <summary>
    /// Computes the plane normal vector
    /// </summary>
    /// <param name="plane"></param>
    /// <returns></returns>
    private static float3 ComputePlaneNormal(PlaneStruct plane)
    {
        var normal = new float3(
            (plane.DeltaB.y * plane.DeltaC.z) - (plane.DeltaB.z * plane.DeltaC.y),
            ((plane.DeltaB.x * plane.DeltaC.z) - (plane.DeltaB.z * plane.DeltaC.x)) * -1,
            (plane.DeltaB.x * plane.DeltaC.y) - (plane.DeltaB.y * plane.DeltaC.x)
            );

        return(math.normalize(normal));
    }
Exemple #4
0
    /// <summary>
    /// Use when create a plane for collision detection
    /// </summary>
    /// <param name="pointA"></param>
    /// <param name="pointB"></param>
    /// <param name="pointC"></param>
    /// <returns></returns>
    public static PlaneStruct ComputePlaneParameters(Vector3 pointA, Vector3 pointB, Vector3 pointC)
    {
        var collisionPlane = new PlaneStruct();

        collisionPlane.PointA = pointA;
        collisionPlane.PointB = pointB;
        collisionPlane.PointC = pointC;

        collisionPlane.DeltaB = collisionPlane.PointA - collisionPlane.PointB;
        collisionPlane.DeltaC = collisionPlane.PointA - collisionPlane.PointC;

        collisionPlane.Normal = ComputePlaneNormal(collisionPlane);

        collisionPlane._displacement = ComputePlaneDisplacement(collisionPlane);

        return(collisionPlane);
    }
Exemple #5
0
    private void DrawPlaneGizmos(PlaneStruct plane, float3 hitPoint, float3 hitNormal)
    {
        Gizmos.color = Color.white;
        Gizmos.DrawWireCube(plane.PointA, Vector3.one * 0.05f);
        Gizmos.DrawWireCube(plane.PointB, Vector3.one * 0.05f);
        Gizmos.DrawWireCube(plane.PointC, Vector3.one * 0.05f);

        Gizmos.color = Color.gray;
        Gizmos.DrawLine(plane.PointA, plane.PointB);
        Gizmos.DrawLine(plane.PointA, plane.PointC);

        Gizmos.color = Color.yellow;
        Gizmos.DrawLine(plane.PointB, plane.PointC);
        Gizmos.color = Color.magenta;
        Gizmos.DrawLine(plane.PointA, hitPoint);

        Gizmos.color = Color.blue;
        Gizmos.DrawWireSphere(hitPoint, 0.05f);
        Gizmos.DrawLine(hitPoint, hitPoint + hitNormal);
    }
Exemple #6
0
    public void DrawPlane(LineRenderer lineRenderer, PlaneStruct planeStr)
    {
        if (nearClip == null)
            return;

        Vector3 center = transform.forward;

        lineRenderer.positionCount = 4;
        lineRenderer.startWidth = lineWidth;
        lineRenderer.endWidth = lineWidth;
        lineRenderer.material = Resources.Load<Material>("Materials/NearClip");
        lineRenderer.loop = true;

        lineRenderer.SetPositions(
            new Vector3[]
            {
                planeStr.topLeft,
                planeStr.topRight,
                planeStr.bttRight,
                planeStr.bttLeft
            }
            );
    }
Exemple #7
0
 /// <summary>
 /// Computes the D Component of the plane formula
 /// </summary>
 /// <param name="plane"></param>
 /// <returns></returns>
 private static float ComputePlaneDisplacement(PlaneStruct plane)
 {
     return(plane.Normal.x * plane.PointA.x + plane.Normal.y * plane.PointA.y + plane.Normal.z * plane.PointA.z);
 }
Exemple #8
0
    /// <summary>
    /// Returns true if the point is on the same side of the plane as the normal
    /// Uses a threshold for displacing the plane by the normal
    /// </summary>
    /// <param name="plane"></param>
    /// <param name="point"></param>
    /// <param name="collisionThreshold"></param>
    /// <returns></returns>
    public static bool IsPointInNormalSideOfPlane(PlaneStruct plane, float3 point, float collisionThreshold = 0.001f)
    {
        var sideDeterminant = GetPointSide(plane, point);

        return(sideDeterminant > collisionThreshold);
    }
Exemple #9
0
    private static bool IsInPlaneLimits(PlaneStruct plane, float3 hitPoint)
    {
        //Compute J component of the collision

        var d = plane.PointA - hitPoint;
        var g = plane.PointB - plane.PointC;

        var j       = -1f;
        var divisor = 0f;

        var converge = false;

        if (d.x != 0f && d.y != 0f)
        {
            divisor = (g.x / d.x) - (g.y / d.y);
            if (divisor != 0f)
            {
                var nom = (plane.PointB.y / d.y) - (plane.PointA.y / d.y) - (plane.PointB.x / d.x) + (plane.PointA.x / d.x);
                if (nom != 0f)
                {
                    converge = true;
                    j        = nom / divisor;
                }
            }
        }


        if (!converge)
        {
            if (d.z != 0f && d.x != 0f)
            {
                divisor = (g.x / d.x) - (g.z / d.z);
                if (divisor != 0f)
                {
                    var nom = (plane.PointB.z / d.z) - (plane.PointA.z / d.z) - (plane.PointB.x / d.x) + (plane.PointA.x / d.x);
                    if (nom != 0f)
                    {
                        converge = true;
                        j        = nom / divisor;
                    }
                }
            }
        }


        if (!converge)
        {
            if (d.z != 0f && d.y != 0f)
            {
                divisor = (g.y / d.y) - (g.z / d.z);
                if (divisor != 0f)
                {
                    var nom = (plane.PointB.z / d.z) - (plane.PointA.z / d.z) - (plane.PointB.y / d.y) + (plane.PointA.y / d.y);
                    if (nom != 0f)
                    {
                        converge = true;
                        j        = nom / divisor;
                    }
                }
            }
        }

        var interceptionPoint = plane.PointB + g * j;

        if (!converge)
        {
            return(false);
        }

        var dInterception = plane.PointA - interceptionPoint;

        var dInterceptionSqrtMagnitude = math.pow(dInterception.x, 2) + math.pow(dInterception.y, 2) + math.pow(dInterception.z, 2);
        var dSqrtMagnitude             = math.pow(d.x, 2) + math.pow(d.y, 2) + math.pow(d.z, 2);
        var dDot = math.dot(dInterception, d);

        var gInterception = plane.PointB - interceptionPoint;

        var gInterceptionSqrtMagnitude = math.pow(gInterception.x, 2) + math.pow(gInterception.y, 2) + math.pow(gInterception.z, 2);
        var gSqrtMagnitude             = math.pow(g.x, 2) + math.pow(g.y, 2) + math.pow(g.z, 2);
        var gDot = math.dot(gInterception, g);

        var isInsidePlaneLimits =
            (gDot > 0f) &&
            (gInterceptionSqrtMagnitude <= gSqrtMagnitude) &&
            (dDot > 0f) &&
            (dInterceptionSqrtMagnitude >= dSqrtMagnitude);

        return(isInsidePlaneLimits);
    }