Fix : 장갑 모션데이터 전달 불량 수정
This commit is contained in:
parent
ea1f905cc0
commit
8278a6d7c8
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab
(Stored with Git LFS)
vendored
Binary file not shown.
@ -8,6 +8,7 @@ using UnityEngine;
|
||||
|
||||
namespace Rokoko.Inputs
|
||||
{
|
||||
[DefaultExecutionOrder(-1)]
|
||||
public class Actor : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
@ -25,14 +26,6 @@ namespace Rokoko.Inputs
|
||||
Self
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public enum PoseApplicationScope
|
||||
{
|
||||
All, // Apply to all bones
|
||||
HandsAndFingers, // Apply to hands (wrists) and all fingers
|
||||
FingersOnly // Apply to fingers only
|
||||
}
|
||||
|
||||
[HideInInspector] public string profileName = "DemoProfile";
|
||||
|
||||
[HideInInspector] public BoneMappingEnum boneMapping;
|
||||
@ -45,11 +38,6 @@ namespace Rokoko.Inputs
|
||||
[Tooltip("Convert Studio data to Unity rotation space")]
|
||||
public RotationSpace rotationSpace = RotationSpace.Offset;
|
||||
|
||||
[Space(10)]
|
||||
[Header("Pose Application")]
|
||||
[Tooltip("Select which bones to apply motion capture data to")]
|
||||
public PoseApplicationScope poseScope = PoseApplicationScope.All;
|
||||
|
||||
[Space(10)]
|
||||
[Tooltip("Calculate Model's height comparing to Actor's and position the Hips accordingly.\nGreat tool to align with the floor")]
|
||||
public bool adjustHipHeightBasedOnStudioActor = false;
|
||||
@ -285,10 +273,6 @@ namespace Rokoko.Inputs
|
||||
foreach (HumanBodyBones bone in RokokoHelper.HumanBodyBonesArray)
|
||||
{
|
||||
if (bone == HumanBodyBones.LastBone) break;
|
||||
|
||||
// Skip bones that are not in the selected scope
|
||||
if (!ShouldApplyToBone(bone))
|
||||
continue;
|
||||
|
||||
ActorJointFrame? boneFrame = actorFrame.body.GetBoneFrame(bone);
|
||||
if (boneFrame != null)
|
||||
@ -313,52 +297,6 @@ namespace Rokoko.Inputs
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if a bone should be included based on the selected pose scope.
|
||||
/// </summary>
|
||||
private bool ShouldApplyToBone(HumanBodyBones bone)
|
||||
{
|
||||
switch (poseScope)
|
||||
{
|
||||
case PoseApplicationScope.All:
|
||||
return true;
|
||||
|
||||
case PoseApplicationScope.HandsAndFingers:
|
||||
return IsHandOrFingerBone(bone);
|
||||
|
||||
case PoseApplicationScope.FingersOnly:
|
||||
return IsFingerBone(bone);
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the bone is a hand (wrist) or finger bone.
|
||||
/// </summary>
|
||||
private bool IsHandOrFingerBone(HumanBodyBones bone)
|
||||
{
|
||||
return bone == HumanBodyBones.LeftHand || bone == HumanBodyBones.RightHand || IsFingerBone(bone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the bone is a finger bone.
|
||||
/// </summary>
|
||||
private bool IsFingerBone(HumanBodyBones bone)
|
||||
{
|
||||
return bone == HumanBodyBones.LeftThumbProximal || bone == HumanBodyBones.LeftThumbIntermediate || bone == HumanBodyBones.LeftThumbDistal ||
|
||||
bone == HumanBodyBones.LeftIndexProximal || bone == HumanBodyBones.LeftIndexIntermediate || bone == HumanBodyBones.LeftIndexDistal ||
|
||||
bone == HumanBodyBones.LeftMiddleProximal || bone == HumanBodyBones.LeftMiddleIntermediate || bone == HumanBodyBones.LeftMiddleDistal ||
|
||||
bone == HumanBodyBones.LeftRingProximal || bone == HumanBodyBones.LeftRingIntermediate || bone == HumanBodyBones.LeftRingDistal ||
|
||||
bone == HumanBodyBones.LeftLittleProximal || bone == HumanBodyBones.LeftLittleIntermediate || bone == HumanBodyBones.LeftLittleDistal ||
|
||||
bone == HumanBodyBones.RightThumbProximal || bone == HumanBodyBones.RightThumbIntermediate || bone == HumanBodyBones.RightThumbDistal ||
|
||||
bone == HumanBodyBones.RightIndexProximal || bone == HumanBodyBones.RightIndexIntermediate || bone == HumanBodyBones.RightIndexDistal ||
|
||||
bone == HumanBodyBones.RightMiddleProximal || bone == HumanBodyBones.RightMiddleIntermediate || bone == HumanBodyBones.RightMiddleDistal ||
|
||||
bone == HumanBodyBones.RightRingProximal || bone == HumanBodyBones.RightRingIntermediate || bone == HumanBodyBones.RightRingDistal ||
|
||||
bone == HumanBodyBones.RightLittleProximal || bone == HumanBodyBones.RightLittleIntermediate || bone == HumanBodyBones.RightLittleDistal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply additional rotation offsets to thumb proximal bones.
|
||||
/// </summary>
|
||||
|
||||
@ -42,7 +42,7 @@ namespace KindRetargeting
|
||||
List<float> leftLegEndWeights = new List<float>();
|
||||
List<float> rightLegEndWeights = new List<float>();
|
||||
|
||||
List<float> leftLegBendWeights = new List<float>();
|
||||
List<float> leftLegBendWeights = new List<float>();
|
||||
List<float> rightLegBendWeights = new List<float>();
|
||||
|
||||
private float MasterleftArmEndWeights = 0f;
|
||||
@ -99,7 +99,7 @@ namespace KindRetargeting
|
||||
props = FindObjectsByType<PropTypeController>(FindObjectsSortMode.None).Select(controller => controller.transform).ToList();
|
||||
|
||||
// 프랍 오브젝트 찾기
|
||||
Gethnad();
|
||||
GetHand();
|
||||
|
||||
//HandDistances();에서 사용을 위한 리스트 추가
|
||||
//손 거리에 따른 웨이트 업데이트 인덱스 0번
|
||||
@ -137,24 +137,24 @@ namespace KindRetargeting
|
||||
rightLegEndWeights.Add(1f);
|
||||
}
|
||||
|
||||
private void Gethnad()
|
||||
private void GetHand()
|
||||
{
|
||||
// 모든 LimbWeightController 찾기
|
||||
LimbWeightController[] allControllers = FindObjectsOfType<LimbWeightController>();
|
||||
|
||||
|
||||
foreach (LimbWeightController controller in allControllers)
|
||||
{
|
||||
// 자기 자신은 제외
|
||||
if (controller == this) continue;
|
||||
|
||||
|
||||
// CustomRetargetingScript 가져오기
|
||||
CustomRetargetingScript otherCrs = controller.GetComponent<CustomRetargetingScript>();
|
||||
if (otherCrs == null) continue;
|
||||
|
||||
|
||||
// 왼손과 오른손 Transform 가져오기
|
||||
Transform leftHand = otherCrs.sourceAnimator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
Transform rightHand = otherCrs.sourceAnimator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
|
||||
Transform leftHand = otherCrs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
Transform rightHand = otherCrs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
|
||||
// 손이 존재하면 props 리스트에 추가
|
||||
if (leftHand != null)
|
||||
{
|
||||
@ -182,59 +182,53 @@ namespace KindRetargeting
|
||||
/// </summary>
|
||||
private void HandDistances()
|
||||
{
|
||||
if (fbik == null || fbik == null) return;
|
||||
if (fbik == null || crs == null) return;
|
||||
|
||||
// 왼쪽 팔 가중치 업데이트
|
||||
if (fbik.solver.leftArm.target != null && fbik.solver.rightArm.target != null)
|
||||
{
|
||||
Transform leftHandTransform = crs.sourceAnimator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
Transform rightHandTransform = crs.sourceAnimator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
if (leftHandTransform != null && rightHandTransform != null)
|
||||
Transform leftHandTransform = crs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
Transform rightHandTransform = crs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
if (leftHandTransform != null && rightHandTransform != null &&
|
||||
props != null && props.Count > 0)
|
||||
{
|
||||
float Distance = Vector3.Distance(leftHandTransform.position, rightHandTransform.position);
|
||||
float Weight = 1f - Mathf.Clamp01((Distance - minDistance) / (maxDistance - minDistance));
|
||||
leftArmEndWeights[0] = Weight;
|
||||
rightArmEndWeights[0] = Weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// props가 없을 때 기본 가중치 설정
|
||||
leftArmEndWeights[0] = 0f;
|
||||
rightArmEndWeights[0] = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SitLegDistances()
|
||||
{
|
||||
if (fbik == null || fbik == null) return;
|
||||
if (fbik == null || crs == null || characterRoot == null) return;
|
||||
|
||||
Transform hips = crs.sourceAnimator.GetBoneTransform(HumanBodyBones.Hips);
|
||||
Transform hips = crs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.Hips);
|
||||
if (hips == null) return;
|
||||
|
||||
// 캐릭터 루트 기준으로 히프의 로컬 높이 계산
|
||||
float hipHeight = characterRoot.InverseTransformPoint(hips.position).y;
|
||||
float normalStandingHeight = 0.9f;
|
||||
float sitThreshold = 0.6f;
|
||||
|
||||
// 기본적으로 다리 가중치를 1로 설정
|
||||
while (leftLegEndWeights.Count <= 0) leftLegEndWeights.Add(1f);
|
||||
while (rightLegEndWeights.Count <= 0) rightLegEndWeights.Add(1f);
|
||||
leftLegEndWeights[0] = 1f;
|
||||
rightLegEndWeights[0] = 1f;
|
||||
|
||||
// 히프가 충분히 낮을 때만 가중치 감소 처리
|
||||
if (hipHeight < sitThreshold * normalStandingHeight)
|
||||
// 바닥 기준 히프 보정 변수들을 활용한 앉아있는 판단
|
||||
// groundHipsMaxHeight 이하일 때 앉아있다고 판단
|
||||
if (hipHeight <= groundHipsMaxHeight)
|
||||
{
|
||||
// 왼쪽 다리 처리
|
||||
ProcessSitLegWeight(
|
||||
hips,
|
||||
fbik.solver.leftLeg.target,
|
||||
leftLegEndWeights,
|
||||
0 // 레이어 인덱스
|
||||
);
|
||||
|
||||
ProcessSitLegWeight(hips, fbik.solver.leftLeg.target, leftLegEndWeights, 0);
|
||||
|
||||
// 오른쪽 다리 처리
|
||||
ProcessSitLegWeight(
|
||||
hips,
|
||||
fbik.solver.rightLeg.target,
|
||||
rightLegEndWeights,
|
||||
0 // 레이어 인덱스
|
||||
);
|
||||
ProcessSitLegWeight(hips, fbik.solver.rightLeg.target, rightLegEndWeights, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,29 +236,31 @@ namespace KindRetargeting
|
||||
{
|
||||
if (footTarget == null) return;
|
||||
|
||||
// 히프와 발 타겟 사이의 수평 거리 계산 (Y축 제외)
|
||||
// Y축을 제외한 실제 수평 거리 계산
|
||||
Vector3 hipPos = hips.position;
|
||||
Vector3 footPos = footTarget.position;
|
||||
float horizontalDistance = Vector3.Distance(hipPos, footPos);
|
||||
Vector3 hipPosFlat = new Vector3(hipPos.x, 0, hipPos.z);
|
||||
Vector3 footPosFlat = new Vector3(footPos.x, 0, footPos.z);
|
||||
float horizontalDistance = Vector3.Distance(hipPosFlat, footPosFlat);
|
||||
|
||||
// 다리 길이를 기준으로 최대/최소 허용 거리 설정
|
||||
float maxLegDistance = 0.8f; // 다리 길이의 80%를 최대 거리로 설정
|
||||
float minLegDistance = 0.5f; // 다리 길이의 30%를 최소 거리로 설정
|
||||
const float MAX_LEG_DISTANCE_RATIO = 0.8f; // 다리 길이의 80%
|
||||
const float MIN_LEG_DISTANCE_RATIO = 0.3f; // 다리 길이의 30%
|
||||
|
||||
// 거리가 멀수록 가중치 감소
|
||||
float weight = 1f - Mathf.Clamp01((horizontalDistance - minLegDistance) / (maxLegDistance - minLegDistance));
|
||||
float weight = 1f - Mathf.Clamp01((horizontalDistance - MIN_LEG_DISTANCE_RATIO) /
|
||||
(MAX_LEG_DISTANCE_RATIO - MIN_LEG_DISTANCE_RATIO));
|
||||
|
||||
// 계산된 가중치 설정
|
||||
weightList[weightIndex] = weight;
|
||||
}
|
||||
|
||||
void PropDistances()
|
||||
{
|
||||
if (fbik == null || fbik == null) return;
|
||||
if (fbik == null || crs == null) return;
|
||||
|
||||
// 프랍과의 거리에 따른 웨이트 업데이트
|
||||
Transform leftHandTransform = crs.sourceAnimator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
Transform rightHandTransform = crs.sourceAnimator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
Transform leftHandTransform = crs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
Transform rightHandTransform = crs?.sourceAnimator?.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
|
||||
if (leftHandTransform != null && rightHandTransform != null && props != null)
|
||||
{
|
||||
@ -495,7 +491,7 @@ namespace KindRetargeting
|
||||
/// </summary>
|
||||
private void UpdateFootHeightBasedWeight()
|
||||
{
|
||||
if (fbik == null || fbik == null || characterRoot == null) return;
|
||||
if (fbik == null || crs == null || characterRoot == null) return;
|
||||
|
||||
// 왼발 처리
|
||||
ProcessFootHeightWeight(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user