public virtual float Step(float timeStep)
{
if (!Enabled) return TargetValue;
float origTarget = TargetValue; // DEBUG
float origCurrVal = CurrentValue; // DEBUG
float correction = 0f;
float error = TargetValue - CurrentValue;
if (!ErrorIsZero(error))
{
correction = StepError(timeStep, error);
CurrentValue += correction;
// The desired value reduces to zero which also reduces the difference with current.
// If the decay time is infinite, don't decay at all.
float decayFactor = 0f;
if (TargetValueDecayTimeScale != BSMotor.Infinite)
{
decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
TargetValue *= (1f - decayFactor);
}
// The amount we can correct the error is reduced by the friction
float frictionFactor = 0f;
if (FrictionTimescale != BSMotor.Infinite)
{
// frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
// Individual friction components can be 'infinite' so compute each separately.
frictionFactor = 1f / FrictionTimescale;
frictionFactor *= timeStep;
CurrentValue *= (1f - frictionFactor);
}
MDetailLog("{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
timeStep, error, correction);
MDetailLog(
"{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}",
BSScene.DetailLogZero, UseName,
TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor,
TargetValue, CurrentValue);
}
else
{
// Difference between what we have and target is small. Motor is done.
if (Util.InRange<float>(TargetValue, -ErrorZeroThreshold, ErrorZeroThreshold))
{
// The target can step down to nearly zero but not get there. If close to zero
// it is really zero.
TargetValue = 0f;
}
CurrentValue = TargetValue;
MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
}
LastError = error;
return CurrentValue;
}