Instantly share code, notes, and snippets.

Embed
What would you like to do?
Unity ARKit estimate neck and shoulder position from head tracked location
//Dynamically calculated head size values upon arkit face added event
//Estimated head height used to determine head's pivot
[System.NonSerialized]
public float headHeight = 0.0547f;
//Estimated head depth used to determine head's pivot
[System.NonSerialized]
public float headDepth = 0.0505f;
public float headWidth = 0.0447f;
//Shoulder width should equal ~ 2x head height
[System.NonSerialized]
public float shoulderWidth = 0.15f;
void FaceAdded (ARFaceAnchor anchorData)
{
trackedEntity.SetActive (true);
faceMesh = new Mesh();
faceMesh.vertices = anchorData.faceGeometry.vertices;
faceMesh.uv = anchorData.faceGeometry.textureCoordinates;
faceMesh.triangles = anchorData.faceGeometry.triangleIndices;
// Assign the mesh object and update it.
faceMesh.RecalculateBounds();
faceMesh.RecalculateNormals();
//Set the head size using the mesh bounds as an approximation
headDepth = faceMesh.bounds.extents.z;
headHeight = faceMesh.bounds.extents.y;
headWidth = faceMesh.bounds.extents.x;
//Shoulder width is two head heights for an average adult
shoulderWidth = faceMesh.bounds.extents.y * 2.0f;
}
void FaceUpdated(ARFaceAnchor anchorData)
{
//Estimate the position of the pivot of the head to reduce swimming effect when applying shoulder offset value
//1.Get position of center of face
//2.Translate down from center of face using headHeight
//3.Translate away from camera using headDepth
var faceUp = (UnityARMatrixOps.GetRotation(anchorData.transform) * Vector3.up).normalized;
var faceForward = (UnityARMatrixOps.GetRotation(anchorData.transform) * Vector3.forward).normalized;
var facePosition = UnityARMatrixOps.GetPosition(anchorData.transform);
neckPivot.position = facePosition +
(faceUp * (headHeight * -0.5f)) +
(faceForward * headDepth);
//Determine forward direction vector towards camera from face
cameraLoc = cameraRef.transform.position;
forwardDir = (neckPivot.position - cameraLoc).normalized;
//Vector3 shoulder estimates
shoulderLeftBaseEstimate = neckPivot.position + ((shoulderWidth * -1.0f) * Vector3.Cross(forwardDir, new Vector3(0.0f, 1.0f, 0.0f))) - new Vector3(0.0f, headHeight, 0.0f);
shoulderRightBaseEstimate = neckPivot.position + (shoulderWidth * Vector3.Cross(forwardDir, new Vector3(0.0f, 1.0f, 0.0f))) - new Vector3(0.0f, headHeight, 0.0f);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment