/// <summary> /// Push a new state onto the undo/redo buffer, will erase anything after the current undo. /// This will use the passed states for undo and redo. /// </summary> public void pushUndoState(MusclePosition undoPosition, MusclePosition redoPosition) { poseUndoRedoBuffer.pushAndSkip(new TwoWayDelegateCommand <MusclePosition, MusclePosition>(redoPosition, undoPosition, new TwoWayDelegateCommand <MusclePosition, MusclePosition> .Funcs() { ExecuteFunc = position => { position.preview(); if (OnRedo != null) { OnRedo.Invoke(this); } }, UndoFunc = position => { position.preview(); if (OnUndo != null) { OnUndo.Invoke(this); } } })); if (OnUndoRedoChanged != null) { OnUndoRedoChanged.Invoke(this); } }
/// <summary> /// Primary blend funciton, will always use the terminating state's mandible muscle force and target offset. /// This is to retain compatability with animations that rely on this blend funciton to work. /// </summary> /// <param name="targetState"></param> /// <param name="blendFactor"></param> public void blend(MusclePosition targetState, float blendFactor) { float modifiedBlendFactor = blendFactor; if (blendFactor < 1.0f) { EasingFunctions.Ease(targetState.Easing, 0, 1, blendFactor, 1); } if (MuscleController.MovingTarget != null) //If this is null then the whole mandible simulation is invalid and its better to do nothing { MuscleController.changeForce("MovingMuscleDynamic", targetState.muscleForce); MuscleController.MovingTarget.Offset = targetState.movingTargetPosition; ControlPointBehavior leftCP = ControlPointController.getControlPoint("LeftCP"); float delta = targetState.leftCPPosition - leftCPPosition; leftCP.setLocation(leftCPPosition + delta * modifiedBlendFactor); ControlPointBehavior rightCP = ControlPointController.getControlPoint("RightCP"); delta = targetState.rightCPPosition - rightCPPosition; rightCP.setLocation(rightCPPosition + delta * modifiedBlendFactor); } FKRoot pelvis; if (pelvisChainState != null && targetState.pelvisChainState != null && PoseableObjectsManager.tryGetFkChainRoot("Pelvis", out pelvis)) { //This creates garbage, but it is unknown if this has negative effects FKChainState blendedState = new FKChainState(); blendedState.setToBlendOf(pelvisChainState, targetState.pelvisChainState, modifiedBlendFactor); pelvis.applyChainState(blendedState); } }
/// <summary> /// Start blending between two states. The duration is in seconds. /// </summary> /// <param name="start">The starting muscle position.</param> /// <param name="end">The ending muscle position.</param> /// <param name="duration">The duration to blend.</param> public void timedBlend(MusclePosition start, MusclePosition end, float duration) { this.start = start; this.end = end; updateListener.subscribeToUpdates(); blendPositionMicro = 0; durationMicro = Clock.SecondsToMicroseconds(duration); }
/// <summary> /// Blend from the current muscle position to the specified position over duration. /// </summary> /// <param name="endPosition">The position to blend to.</param> /// <param name="duration">The duration to blend over.</param> public void timedBlend(MusclePosition endPosition, float duration) { MusclePosition startPosition = new MusclePosition(); startPosition.captureState(); timedBlend(startPosition, endPosition, duration); }
void controller_SceneLoaded(SimScene scene) { bindPosition = new MusclePosition(); bindPosition.captureState(); poseUndoRedoBuffer.clear(); if (OnUndoRedoChanged != null) { OnUndoRedoChanged.Invoke(this); } }
public MusclePositionAction(MusclePosition targetState) { this.targetState = targetState; Duration = 1.0f; }
protected MusclePositionAction(LoadInfo info) : base(info) { targetState = info.GetValue <MusclePosition>("TargetState"); }
/// <summary> /// Push a new state onto the undo/redo buffer, will erase anything after the current undo. /// This will use the passed state as the undo state and the current muscle position of the scene /// as the redo state. /// </summary> public void pushUndoState(MusclePosition undoPosition) { pushUndoState(undoPosition, new MusclePosition(true)); }