How to highlight one face of a cube when gazing (using the HoloToolKit cursor)?

Hi guys,
I am doing a Hololens app using Unity 3D engine now and I want to implement one specific function, which is when the user is looking a 3D game object (for example, like a cube), it could highlight (or simply change color) the face that the cursor is on.
I did some research and find for me it is not an easy question. One solution I can think of is to first know which mesh triangle the user is gazing by getting it’s index. And because every face has different triangle index so I could use some simple if else or case statement to determine which face the user is gazing. Then I would switch the color for all triangles in that face. When user changes the face he is gazing at, just set back to the original color.
Am I doing this right? Or there is better solution? It would be great if someone could give a code example with some comments.
Any advise or suggestion are welcome!
Thanks!

The code I have some far is like this, but it does not work:

public class FindTriangleIndex : MonoBehaviour {
GameObject cursor;

// Use this for initialization
void Start () {
cursor = GameObject.FindGameObjectWithTag(“cursor”);

if (cursor == null)
{
Debug.Log(“cursor not found”);
}
}

// Update is called once per frame
void Update () {
//This generates our ray. We input the positions x, and y, as screen height and width divided by two to send a ray towards whatever the
//screen center is viewing.
//Camera.main is a static var, capable of being accessed from any code without references.
Ray ray = Camera.main.ScreenPointToRay(cursor.transform.position);

//This defines a RaycastHit object. Its information is filled out if Physics.Raycasthit actually hits.
RaycastHit hit = new RaycastHit();

//This uses the ray’s parameters to call physics.raycast. Mathf.Infinity is the distance the raycast will go before giving up. [Don’t worry, distances of this size cause no lag].
//We specify ‘out’ as that is just how c# rolls. [It goes into variable references, ETC. All of this is automagic in JS]
Debug.Log(Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity));

if (Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity))
{
//This is the index of the tri the camera is looking at:
int ind = hit.triangleIndex;
Debug.Log("Hit tri index is " + ind * 3);
}
}

Hi,

Raycasting and hit.triangleIndex is how I would handle it also.

Yes you could hardcode the logic to handle a particular cube model you have.

But I would be tempted to write a general mesh highlight function for using on any Mesh geometry where you specify the “break angle” for how far the highlight spreads. This way you can simply drop the script on any mesh in the future and have it just work.

Steps to do this:

  • Get triangle index of hitpoint, we will call this triangleA.
  • Store the 3 vertex indexes for triangleA in a List.
  • Parse the whole mesh looking for triangles spatially connected to triangleA.
  • If that triangles normal is within some threshold of triangleA normal then store its vertex indexes in List.
  • Recurse to 3 (passing new triangle instead of triangleA) until tested triangle normal is outside threshold of triangleA normal.
  • Apply vertex colors to all vertices in List.

Notes:

RE Step3
you need to check vertex positions of other triangles if very close like <0.001 then consider it connected. For general case you cant rely on triangles sharing vertex. So for all triangles:

read the 3 vertex indices.
get the corresponding 3 vertex.
read the three vertex positions.
check if any one of 3 position vectors is close to any one of other 3 vert positions.
so for each triangle to check that’s 3*3 = 9 comparisons using:
if (vPositionVector1 - vPositionVector2).magnitude < fThreshold{…}

For fully connected mesh (where all triangles share vertex) you can do it without spatial search and thus much faster.

RE Step4
To get a triangles normal vector: take the vector cross product of two edge vectors of that triangle where edge vectors are calculated by subtracting point position vectors . The order of the vertices used in the calculation will affect the direction of the normal.

Dot product two triangles normal vectors together to see how close they are in rotation. +1 is very close. So you set threshold using this to dictate how far your highlight spreads round your mesh, set threshold small to like 0.9 to only highlight connected triangles on same plane.

RE Step6
You will need a material/shader that supports vertex coloring.