private void Solve(AnimationStream stream) { AnimationHumanStream humanStream = stream.AsHuman(); Vector3 bodyPosition = humanStream.bodyPosition; Vector3 bodyPositionDelta = Vector3.zero; float sumWeight = 0; for (int goalIter = 0; goalIter < 4; goalIter++) { float weight = humanStream.GetGoalWeightPosition((AvatarIKGoal)goalIter); weight = Mathf.Clamp01(weight); bodyPositionDelta += (humanStream.GetGoalPosition((AvatarIKGoal)goalIter) - humanStream.GetGoalPositionFromPose((AvatarIKGoal)goalIter)) * weight; sumWeight += weight; } if (sumWeight > 1) { bodyPositionDelta /= sumWeight; } bodyPosition += bodyPositionDelta; humanStream.bodyPosition = bodyPosition; if (bodyEffector.body.IsValid(stream)) { bodyEffector.body.SetPosition(stream, bodyPosition); } humanStream.SolveIK(); }
private void PrepareSolvePull(AnimationStream stream, NativeArray <LimbPart> limbParts) { AnimationHumanStream humanStream = stream.AsHuman(); Vector3 bodyPosition = humanStream.bodyPosition; for (int goalIter = 0; goalIter < 4; goalIter++) { var effector = GetEffectorHandle((AvatarIKGoal)goalIter); var limbHandle = GetIKLimbHandle((AvatarIKGoal)goalIter); Vector3 top = limbHandle.top.GetPosition(stream); limbParts[goalIter] = new LimbPart { localPosition = top - bodyPosition, goalPosition = humanStream.GetGoalPosition((AvatarIKGoal)goalIter), goalWeight = humanStream.GetGoalWeightPosition((AvatarIKGoal)goalIter), goalPullWeight = effector.pullWeight.GetFloat(stream), maximumExtension = limbHandle.maximumExtension, stiffness = stiffness }; } }
private void ApplyLimbData(AnimationHumanStream stream, IKLimbData.JobData data, AvatarIKGoal goal, AvatarIKHint hint) { if (data.positionWeight > 0) { if (data.positionWeight >= 1) { stream.SetGoalPosition(goal, data.position); stream.SetGoalWeightPosition(goal, 1f); } else { var position = Vector3.Lerp(stream.GetGoalPosition(goal), data.position, data.positionWeight); var positionWeight = Mathf.Lerp(stream.GetGoalWeightPosition(goal), 1f, data.positionWeight); stream.SetGoalPosition(goal, position); stream.SetGoalWeightPosition(goal, positionWeight); } } else { // For some reason, IK will be broken if same values are not reapplied before SolveIK is called stream.SetGoalPosition(goal, stream.GetGoalPosition(goal)); stream.SetGoalWeightPosition(goal, stream.GetGoalWeightPosition(goal)); } if (data.rotationWeight > 0) { if (data.rotationWeight >= 1) { stream.SetGoalRotation(goal, data.rotation); stream.SetGoalWeightRotation(goal, 1f); } else { var rotation = Quaternion.Slerp(stream.GetGoalRotation(goal), data.rotation, data.rotationWeight); var rotationWeight = Mathf.Lerp(stream.GetGoalWeightRotation(goal), 1f, data.rotationWeight); stream.SetGoalRotation(goal, rotation); stream.SetGoalWeightRotation(goal, rotationWeight); } } else { // Same as above stream.SetGoalRotation(goal, stream.GetGoalRotation(goal)); stream.SetGoalWeightRotation(goal, stream.GetGoalWeightRotation(goal)); } if (data.hintWeight > 0) { if (data.hintWeight >= 1) { stream.SetHintPosition(hint, data.hintPosition); stream.SetHintWeightPosition(hint, 1f); } else { var hintPosition = Vector3.Lerp(stream.GetHintPosition(hint), data.hintPosition, data.hintWeight); var hintWeight = Mathf.Lerp(stream.GetHintWeightPosition(hint), 1f, data.hintWeight); stream.SetHintPosition(hint, hintPosition); stream.SetHintWeightPosition(hint, hintWeight); } } else { // Same as above stream.SetHintPosition(hint, stream.GetHintPosition(hint)); stream.SetHintWeightPosition(hint, stream.GetHintWeightPosition(hint)); } }
public static void MirrorPose(this AnimationHumanStream humanStream) { // mirror body for (int i = 0; i < (int)BodyDof.LastBodyDof; i++) { humanStream.MultMuscle(new MuscleHandle((BodyDof)i), BodyDoFMirror[i]); } // mirror head for (int i = 0; i < (int)HeadDof.LastHeadDof; i++) { humanStream.MultMuscle(new MuscleHandle((HeadDof)i), HeadDoFMirror[i]); } // swap arms for (int i = 0; i < (int)ArmDof.LastArmDof; i++) { humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftArm, (ArmDof)i), new MuscleHandle(HumanPartDof.RightArm, (ArmDof)i)); } // swap legs for (int i = 0; i < (int)LegDof.LastLegDof; i++) { humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftLeg, (LegDof)i), new MuscleHandle(HumanPartDof.RightLeg, (LegDof)i)); } // swap fingers for (int i = 0; i < (int)FingerDof.LastFingerDof; i++) { humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftThumb, (FingerDof)i), new MuscleHandle(HumanPartDof.RightThumb, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftIndex, (FingerDof)i), new MuscleHandle(HumanPartDof.RightIndex, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftMiddle, (FingerDof)i), new MuscleHandle(HumanPartDof.RightMiddle, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftRing, (FingerDof)i), new MuscleHandle(HumanPartDof.RightRing, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftLittle, (FingerDof)i), new MuscleHandle(HumanPartDof.RightLittle, (FingerDof)i)); } humanStream.bodyLocalPosition = Mirrored(humanStream.bodyLocalPosition); // mirror rotation (invert Y axis angle) humanStream.bodyLocalRotation = Mirrored(humanStream.bodyLocalRotation); // swap ik Vector3[] goalPositions = new Vector3[4]; Quaternion[] goalRotations = new Quaternion[4]; float[] goalWeightPositons = new float[4]; float[] goalWeightRotations = new float[4]; Vector3[] hintPositions = new Vector3[4]; float[] hintWeightPositions = new float[4]; for (int i = 0; i < 4; i++) { goalPositions[i] = humanStream.GetGoalLocalPosition(AvatarIKGoal.LeftFoot + i); goalRotations[i] = humanStream.GetGoalLocalRotation(AvatarIKGoal.LeftFoot + i); goalWeightPositons[i] = humanStream.GetGoalWeightPosition(AvatarIKGoal.LeftFoot + i); goalWeightRotations[i] = humanStream.GetGoalWeightRotation(AvatarIKGoal.LeftFoot + i); hintPositions[i] = humanStream.GetHintPosition(AvatarIKHint.LeftKnee + i); hintWeightPositions[i] = humanStream.GetHintWeightPosition(AvatarIKHint.LeftKnee + i); } for (int i = 0; i < 4; i++) { int j = (i + 1) % 2 + (i / 2) * 2; // make [1, 0, 3, 2] humanStream.SetGoalLocalPosition(AvatarIKGoal.LeftFoot + i, Mirrored(goalPositions[j])); humanStream.SetGoalLocalRotation(AvatarIKGoal.LeftFoot + i, Mirrored(goalRotations[j])); humanStream.SetGoalWeightPosition(AvatarIKGoal.LeftFoot + i, goalWeightPositons[j]); humanStream.SetGoalWeightRotation(AvatarIKGoal.LeftFoot + i, goalWeightRotations[j]); humanStream.SetHintPosition(AvatarIKHint.LeftKnee + i, hintPositions[j]); humanStream.SetHintWeightPosition(AvatarIKHint.LeftKnee + i, hintWeightPositions[j]); } }