您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

305 行
11 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine.Perception.GroundTruth;
namespace UnityEngine.Perception.Content
{
public static class CharacterValidation
{
public static string[] RequiredBones =
{
"Head",
"Hips",
"Spine",
"LeftUpperArm",
"LeftLowerArm",
"LeftHand",
"RightUpperArm",
"RightLowerArm",
"RightHand",
"LeftUpperLeg",
"LeftLowerLeg",
"LeftFoot",
"RightUpperLeg",
"RightLowerLeg",
"RightFoot",
};
public static Dictionary<HumanBone, bool> AvatarRequiredBones(Animator animator)
{
var result = new Dictionary<HumanBone, bool>();
var human = animator.avatar.humanDescription.human;
var totalBones = 0;
for(int h = 0; h < human.Length; h++)
{
for (int b = 0; b < RequiredBones.Length; b++)
{
if(human[h].humanName == RequiredBones[b])
{
var bone = new HumanBone();
if (human[h].boneName != null)
{
bone.boneName = human[h].boneName;
totalBones = totalBones = +1;
result.Add(bone, true);
}
else
{
result.Add(bone, false);
}
}
}
}
return result;
}
public static GameObject AvatarCreateNose (GameObject selection, Animator animator, SkinnedMeshRenderer skinnedMeshRenderer, bool drawRays = false)
{
var human = animator.avatar.humanDescription.human;
var skeleton = animator.avatar.humanDescription.skeleton;
var verticies = skinnedMeshRenderer.sharedMesh.vertices;
var head = animator.GetBoneTransform(HumanBodyBones.Head);
var leftEye = animator.GetBoneTransform(HumanBodyBones.RightEye);
var rightEye = animator.GetBoneTransform(HumanBodyBones.LeftEye);
var faceCenter = Vector3.zero;
var earCenter = Vector3.zero;
var nosePos = Vector3.zero;
var earRightPos = Vector3.zero;
var earLeftPos = Vector3.zero;
var distanceCheck = 1f;
var eyeDistance = Vector3.Distance(leftEye.position, rightEye.position);
var directionLeft = Quaternion.AngleAxis(-45, -leftEye.right) * -leftEye.up;
var directionRight = Quaternion.AngleAxis(-45, rightEye.right) * -rightEye.up;
var rayHead = new Ray();
var rayLeftEye = new Ray();
var rayRightEye = new Ray();
var noseRayFor = new Ray();
var rayNoseBack = new Ray();
var rayEarLeft = new Ray();
var rayEarRight = new Ray();
var foundRightEar = false;
var foundLeftEar = false;
rayLeftEye.origin = leftEye.position;
rayLeftEye.direction = directionLeft * eyeDistance;
rayRightEye.origin = rightEye.position;
rayRightEye.direction = directionRight * eyeDistance;
for (double i = 0; i < distanceCheck; i += 0.01)
{
var point = Convert.ToSingle(i);
var pointR = rayRightEye.GetPoint(point);
var pointL = rayLeftEye.GetPoint(point);
var distanceX = Math.Abs(pointR.x - pointL.x);
var distanceY = Math.Abs(pointR.y - pointL.y);
if (distanceX < 0.01 && distanceY < 0.01 )
{
faceCenter = pointR;
}
}
rayHead.origin = head.position;
rayHead.direction = Vector3.up * distanceCheck;
noseRayFor.origin = faceCenter;
noseRayFor.direction = Vector3.forward * distanceCheck;
rayNoseBack.origin = faceCenter;
rayNoseBack.direction = Vector3.back * distanceCheck;
for (double i = 0; i < distanceCheck; i += 0.01)
{
var point = Convert.ToSingle(i);
var pointH = rayHead.GetPoint(point);
var pointF = rayNoseBack.GetPoint(point);
var distanceZ = Math.Abs(pointH.z - pointF.z);
if (distanceZ < 0.01)
{
earCenter = pointF;
}
}
for (int v = 0; v < verticies.Length; v++)
{
for (double c = eyeDistance / 2; c < distanceCheck; c += 0.001)
{
var point = Convert.ToSingle(c);
var pointNoseRay = noseRayFor.GetPoint(point);
var pointVert = verticies[v];
var distHeadZ = Math.Abs(pointNoseRay.z - pointVert.z);
var distHeadX = Math.Abs(pointNoseRay.x - pointVert.x);
if (distHeadZ < 0.0001 && distHeadX < 0.001)
{
nosePos = pointNoseRay;
Debug.Log("Found Nose: " + nosePos);
}
if(nosePos == Vector3.zero)
{
if (distHeadZ < 0.001 && distHeadX < 0.001)
{
nosePos = pointNoseRay;
Debug.Log("Found Nose: " + nosePos);
}
}
}
}
rayEarRight.origin = earCenter;
rayEarRight.direction = Vector3.right * distanceCheck;
rayEarLeft.origin = earCenter;
rayEarLeft.direction = Vector3.left * distanceCheck;
for (int v = 0; v < verticies.Length; v++)
{
for (double c = eyeDistance / 2; c < distanceCheck; c += 0.001)
{
var point = Convert.ToSingle(c);
var pointEarRight = rayEarRight.GetPoint(point);
var pointEarLeft = rayEarLeft.GetPoint(point);
var pointVert = verticies[v];
var distEarRightY = Math.Abs(pointEarRight.y - pointVert.y);
var distEarRightX = Math.Abs(pointEarRight.x - pointVert.x);
var distEarLeftY = Math.Abs(pointEarLeft.y - pointVert.y);
var distEarLeftX = Math.Abs(pointEarLeft.x - pointVert.x);
if (distEarRightY < 0.001 && distEarRightX < 0.0001)
{
earRightPos = pointEarRight;
foundRightEar = true;
}
if (distEarLeftY < 0.001 && distEarLeftX < 0.0001)
{
earLeftPos = pointEarLeft;
foundLeftEar = true;
}
if (!foundRightEar)
{
if (distEarRightY < 0.002 && distEarRightX < 0.001)
{
earRightPos = pointEarRight;
}
}
if (!foundLeftEar)
{
if (distEarLeftY < 0.002 && distEarLeftX < 0.001)
{
earLeftPos = pointEarLeft;
}
}
}
}
var earLeftCheck = Vector3.Distance(earLeftPos, earCenter);
var earRightCheck = Vector3.Distance(earRightPos, earCenter);
var eyeCenterDistance = eyeDistance + 0.01f;
if (earLeftCheck > eyeCenterDistance)
{
earLeftPos.x = (-eyeDistance);
}
if (earRightCheck > eyeCenterDistance)
{
earRightPos.x = eyeDistance;
}
if(drawRays)
{
DebugDrawRays(30f, distanceCheck, rightEye, leftEye, head, rayRightEye, rayLeftEye, faceCenter, earCenter);
}
return CreateNewCharacterPrefab(selection, nosePos, earRightPos, earLeftPos);
}
public static void DebugDrawRays(float duration, float distanceCheck, Transform rightEye, Transform leftEye, Transform head,Ray rayRightEye, Ray rayLeftEye, Vector3 faceCenter, Vector3 earCenter)
{
Debug.DrawLine(rightEye.position, leftEye.position, Color.magenta, duration);
Debug.DrawRay(rayLeftEye.origin, rayLeftEye.direction, Color.green, duration);
Debug.DrawRay(rayRightEye.origin, rayRightEye.direction, Color.blue, duration);
Debug.DrawRay(faceCenter, Vector3.forward * distanceCheck, Color.cyan, duration);
Debug.DrawRay(faceCenter, Vector3.back, Color.cyan, duration);
Debug.DrawRay(head.position, Vector3.up, Color.red, duration);
Debug.DrawRay(earCenter, Vector3.right, Color.blue, duration);
Debug.DrawRay(earCenter, Vector3.left, Color.green, duration);
}
public static GameObject CreateNewCharacterPrefab(GameObject selection, Vector3 nosePosition, Vector3 earRightPosition, Vector3 earLeftPosition)
{
var root = (GameObject)PrefabUtility.InstantiatePrefab(selection);
List<Transform> children = new List<Transform>();
root.GetComponentsInChildren(children);
foreach(var child in children)
{
if (child.name == "head")
{
if (nosePosition != Vector3.zero)
{
var nose = new GameObject();
nose.transform.position = nosePosition;
nose.name = "nose";
nose.transform.SetParent(child);
AddJointLabel(nose);
}
if (earRightPosition != Vector3.zero)
{
var earRight = new GameObject();
earRight.transform.position = earRightPosition;
earRight.name = "earRight";
earRight.transform.SetParent(child);
AddJointLabel(earRight);
}
if (earLeftPosition != Vector3.zero)
{
var earLeft = new GameObject();
earLeft.transform.position = earLeftPosition;
earLeft.name = "earLeft";
earLeft.transform.SetParent(child);
AddJointLabel(earLeft);
}
}
}
var model = PrefabUtility.SaveAsPrefabAsset(root, "Assets/" + root.name + ".prefab");
return model;
}
private static void AddJointLabel(GameObject gameObject)
{
var jointLabel = gameObject.AddComponent<JointLabel>();
var data = new JointLabel.TemplateData();
data.label = gameObject.name;
jointLabel.templateInformation.Add(data);
}
}
}