Odd Duplicate when selecting Triangle from Mesh (with Barycentric Selection.)

What I’m trying to do is select a specific triangle on any given mesh, so I’m using the Barycentric algorithm. However, as seen [here][1], there is some strange behaviors and certain locations and always an Unwanted Triangle. Best guess, it has something to do with inaccurate float precision of the Vector3.


Here is the Script I’m Currently Using:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpecificTriangleIndex : MonoBehaviour
{
    public Camera m_camera;
    public LayerMask layermask;

    public Vector3[] vertices;
    public Vector3[] normals;
    public int[] triangles;

    public List<int> triangleIndices = new List<int>(); ///Returned Triangle Indices -- What it thinks is selected.
    public List<Vector3> baryAllens = new List<Vector3>(); ///Position of Verticies of Returned Triangles

    private RaycastHit hit;
    private Transform objectHit;
    private Vector3 bary;

    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            EobardThawne();
            Raycast();
        }
    }
    void Raycast()
    {
        Ray ray = m_camera.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit, layermask))
        {
            objectHit = hit.transform;
            MeshFilter meshFilter = hit.transform.gameObject.GetComponent<MeshFilter>();
            Mesh mesh = meshFilter.sharedMesh;
            vertices = mesh.vertices;
            normals = mesh.normals;
            triangles = mesh.triangles;

            Vector3 p = transform.InverseTransformPoint(hit.point);
            for (int i = 0; i < triangles.Length; i += 3)
            {
                Vector3 a = vertices[triangles*];*

Vector3 b = vertices[triangles[i + 1]];
Vector3 c = vertices[triangles[i + 2]];

bary = GetBarycentric(a, b, c, p);
if (InTriangle(bary))
{
triangleIndices.Add(i / 3);
baryAllens.Add(a + objectHit.position);
baryAllens.Add(b + objectHit.position);
baryAllens.Add(c + objectHit.position);
}
}
for (int i = 0; i < baryAllens.Count; i += 3)
{
Vector3 v0 = baryAllens*;*
Vector3 v1 = baryAllens[i + 1];
Vector3 v2 = baryAllens[i + 2];

Debug.DrawLine(v0, v1, Color.green);
Debug.DrawLine(v1, v2, Color.green);
Debug.DrawLine(v2, v0, Color.green);
}
}
}

Vector3 GetBarycentric(Vector2 v1, Vector2 v2, Vector2 v3, Vector2 p)
{
Vector3 B = new Vector3();
B.x = ((v2.y - v3.y) * (p.x - v3.x) + (v3.x - v2.x) * (p.y - v3.y)) /
((v2.y - v3.y) * (v1.x - v3.x) + (v3.x - v2.x) * (v1.y - v3.y));
B.y = ((v3.y - v1.y) * (p.x - v3.x) + (v1.x - v3.x) * (p.y - v3.y)) /
((v3.y - v1.y) * (v2.x - v3.x) + (v1.x - v3.x) * (v2.y - v3.y));
B.z = 1 - B.x - B.y;
return B;
}

bool InTriangle(Vector3 barycentric)
{
return (barycentric.x >= 0.0f) && (barycentric.x <= 1.0f)
&& (barycentric.y >= 0.0f) && (barycentric.y <= 1.0f)
&& (barycentric.z >= 0.0f); //(barycentric.z <= 1.0f)
}

private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(hit.point, .01f);

Gizmos.color = Color.cyan;
foreach (int i in triangleIndices)
{
Gizmos.DrawSphere(FindCenter(i * 3), .01f);
Debug.DrawLine(hit.point, FindCenter(i * 3), Color.red);
}
}

public void EobardThawne()
{
//Kill Barry
triangleIndices.Clear();
baryAllens.Clear();
}

public Vector3 FindCenter(int i)
{
Vector3 v0 = transform.TransformPoint(vertices[triangles*]);*
Vector3 v1 = transform.TransformPoint(vertices[triangles[i + 1]]);
Vector3 v2 = transform.TransformPoint(vertices[triangles[i + 2]]);
Vector3 center = (v0 + v1 + v2) / 3;
return center;
}
}
Any Help or Insight would be Appreciated.
Also, RaycastHit.triangleIndex doesn’t work in all cases, so thats why I am pursuing this.
_*[1]: https://studio.youtube.com/video/FoEaA64v4lY/edit*_

You seem to use the methods I had posted over here or in the other linked post. However those methods takes “Vector2” values since they were meant to be used to look up uv coordinates, not spatial position data which is of course 3d and not 2d. You pass in your 3d coordinates into the method where the z component is essentially dropped.

Later in the comments below my answer I’ve also created the Barycentric struct which I posted to the unity wiki. Unfortunately the wiki does no longer exist. However we have the wayback machine ^^. This struct has 5 different constructors. So you can use Vector2, 3, 4 values as well as a version that takes Color values. So you should be able to create baricentric coordinates from any vertex attribute, given you do have the interpolated value (i.e. the uv coordinate or the local position).

Likewise the struct has several “Interpolate” methods in order to interpolate any other vertex attribute across the triangle based on the barycentric coordinate.