131 lines
3.0 KiB
C#
131 lines
3.0 KiB
C#
using UnityEngine;
|
|
|
|
//!!!!!!
|
|
//This objective type is still under development
|
|
//!!!!!!
|
|
|
|
namespace BioIK {
|
|
|
|
//This objective aims to keep particular joint values acting as soft-constraints. Using this requires
|
|
//a joint added to the segment, and introduces some sort of stiffness controlled by the weight to the joint.
|
|
//Currently, you will require one objective for each >enabled< motion axis you wish to control.
|
|
[AddComponentMenu("")]
|
|
public class JointValue : BioObjective {
|
|
|
|
public double TargetValue = 0.0;
|
|
public bool X, Y, Z;
|
|
|
|
private BioJoint.Motion Motion;
|
|
private bool Valid;
|
|
private Model.MotionPtr Ptr;
|
|
private double NormalisedTargetValue;
|
|
|
|
public override ObjectiveType GetObjectiveType() {
|
|
return ObjectiveType.JointValue;
|
|
}
|
|
|
|
public override void UpdateData() {
|
|
if(Segment.Character.Evolution == null) {
|
|
return;
|
|
}
|
|
Valid = IsValid();
|
|
if(!Valid) {
|
|
return;
|
|
}
|
|
if(X) {
|
|
Motion = Segment.Joint.X;
|
|
}
|
|
if(Y) {
|
|
Motion = Segment.Joint.Y;
|
|
}
|
|
if(Z) {
|
|
Motion = Segment.Joint.Z;
|
|
}
|
|
Ptr = Segment.Character.Evolution.GetModel().FindMotionPtr(Motion);
|
|
NormalisedTargetValue = Segment.Joint.JointType == JointType.Rotational ? NormalisedTargetValue = Utility.Deg2Rad * TargetValue : TargetValue;
|
|
}
|
|
|
|
public override double ComputeLoss(double WPX, double WPY, double WPZ, double WRX, double WRY, double WRZ, double WRW, Model.Node node, double[] configuration) {
|
|
if(!Valid) {
|
|
return 0.0;
|
|
}
|
|
double loss = configuration[Ptr.Index] - NormalisedTargetValue;
|
|
return Weight * loss * loss;
|
|
}
|
|
|
|
public override bool CheckConvergence(double WPX, double WPY, double WPZ, double WRX, double WRY, double WRZ, double WRW, Model.Node node, double[] configuration) {
|
|
return true;
|
|
}
|
|
|
|
public override double ComputeValue(double WPX, double WPY, double WPZ, double WRX, double WRY, double WRZ, double WRW, Model.Node node, double[] configuration) {
|
|
if(!Valid) {
|
|
return 0.0;
|
|
}
|
|
return System.Math.Abs(configuration[Ptr.Index] - NormalisedTargetValue);
|
|
}
|
|
|
|
public void SetTargetValue(double value) {
|
|
TargetValue = value;
|
|
}
|
|
|
|
public double GetTargetValue() {
|
|
return TargetValue;
|
|
}
|
|
|
|
public void SetXMotion(bool enabled) {
|
|
if(X != enabled) {
|
|
ResetMotion();
|
|
X = enabled;
|
|
}
|
|
}
|
|
|
|
public bool IsXMotion() {
|
|
return X;
|
|
}
|
|
|
|
public void SetYMotion(bool enabled) {
|
|
if(Y != enabled) {
|
|
ResetMotion();
|
|
Y = enabled;
|
|
}
|
|
}
|
|
|
|
public bool IsYMotion() {
|
|
return Y;
|
|
}
|
|
|
|
public void SetZMotion(bool enabled) {
|
|
if(Z != enabled) {
|
|
ResetMotion();
|
|
Z = enabled;
|
|
}
|
|
}
|
|
|
|
public bool IsZMotion() {
|
|
return Z;
|
|
}
|
|
|
|
private void ResetMotion() {
|
|
X = false; Y = false; Z = false;
|
|
}
|
|
|
|
private bool IsValid() {
|
|
if(Segment.Joint == null) {
|
|
return false;
|
|
}
|
|
if(!X && !Y && !Z) {
|
|
return false;
|
|
}
|
|
if(X && !Segment.Joint.X.IsEnabled()) {
|
|
return false;
|
|
}
|
|
if(Y && !Segment.Joint.Y.IsEnabled()) {
|
|
return false;
|
|
}
|
|
if(Z && !Segment.Joint.Z.IsEnabled()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
} |