public InstructionList CreateVelocityListAtIndex(int keyframeIndex) { if (keyframeIndex > Count - 1) { // The user passed either the last instruction index or an out-of-bounds index, // so return an empty list. return(new InstructionList(0)); } else { #region Get keyframeAtIndex and keyframeAfter InstructionList keyframeAtIndex = this[keyframeIndex]; InstructionList keyframeAfter = null; double timeBetween; if (keyframeIndex == Count - 1) { // If it's the last keyframe, use the same keyframe to stop all velocity keyframeAfter = keyframeAtIndex; timeBetween = 1; // To prevent NaN values } else { keyframeAfter = this[keyframeIndex + 1]; timeBetween = keyframeAfter[0].TimeToExecute - keyframeAtIndex[0].TimeToExecute; } #endregion InstructionList instructionList = new InstructionList(); #region Loop through all instructions and create interpolation instructions for (int i = 0; i < keyframeAtIndex.Count; i++) { Instruction instructionAtIndex = keyframeAtIndex[i]; GenericInstruction instructionAtIndexAsGeneric = instructionAtIndex as GenericInstruction; Type typeOfTarget = instructionAtIndexAsGeneric.Target.GetType(); bool shouldInterpolate = instructionAtIndexAsGeneric.MemberValueAsObject != null && instructionAtIndexAsGeneric != null && InstructionManager.HasInterpolatorForType( instructionAtIndexAsGeneric.MemberValueAsObject.GetType()); string velocityMemberName = InstructionManager.GetVelocityForState( instructionAtIndexAsGeneric.Member); if (shouldInterpolate && !string.IsNullOrEmpty(velocityMemberName)) { Type typeOfValue = instructionAtIndexAsGeneric.MemberValueAsObject.GetType(); //bool hasInterpolated = false; GenericInstruction instructionAfterAsGeneric = keyframeAfter[i] as GenericInstruction; if (instructionAfterAsGeneric != null && instructionAtIndexAsGeneric.Target == instructionAfterAsGeneric.Target && instructionAtIndexAsGeneric.Member == instructionAfterAsGeneric.Member) { // We've found the instruction! Create a velocity instruction Instruction instruction = CreateInstructionFor( instructionAtIndexAsGeneric.Target, velocityMemberName, instructionAtIndexAsGeneric.MemberValueAsObject, instructionAfterAsGeneric.MemberValueAsObject, timeBetween, instructionAtIndexAsGeneric.TimeToExecute, typeOfTarget, typeOfValue); instruction.TimeToExecute = instructionAtIndex.TimeToExecute; instructionList.Add(instruction); } } // switch on the Type, but can't use a Switch statement } #endregion return(instructionList); } }
public void SetState(double time, bool setVelocity) { InstructionList keyframeBefore = KeyframeAtOrBefore(time); InstructionList keyframeAfter = KeyframeAtOrAfter(time); if (keyframeBefore == null && keyframeAfter == null) { return; } else if (keyframeBefore == keyframeAfter) { keyframeBefore.Execute(); } else if (keyframeBefore != null && keyframeAfter == null) { keyframeBefore.Execute(); } else if (keyframeAfter != null && keyframeBefore == null) { keyframeAfter.Execute(); } else // the two keyframes are not the same, and neither are null { double timeAfter = keyframeAfter[0].TimeToExecute; double timeBefore = keyframeBefore[0].TimeToExecute; double range = timeAfter - timeBefore; double ratioAfter = (time - timeBefore) / range; double ratioBefore = 1 - ratioAfter; for (int i = 0; i < keyframeBefore.Count; i++) { Instruction instructionBefore = keyframeBefore[i]; GenericInstruction instructionBeforeAsGeneric = instructionBefore as GenericInstruction; object memberValueAsObject = instructionBeforeAsGeneric.MemberValueAsObject; // DO MORE HERE bool shouldInterpolate = instructionBeforeAsGeneric.MemberValueAsObject != null && instructionBeforeAsGeneric != null && InstructionManager.HasInterpolatorForType( instructionBeforeAsGeneric.MemberValueAsObject.GetType()); if (shouldInterpolate) { bool hasInterpolated = false; GenericInstruction instructionAfterAsGeneric = keyframeAfter[i] as GenericInstruction; if (instructionAfterAsGeneric != null && instructionBeforeAsGeneric.Target == instructionAfterAsGeneric.Target && instructionBeforeAsGeneric.Member == instructionAfterAsGeneric.Member) { // We've found the instruction! Interpolate! instructionBeforeAsGeneric.InterpolateBetweenAndExecute(instructionAfterAsGeneric, (float)ratioBefore); hasInterpolated = true; } if (hasInterpolated == false) { // for now, fail. Eventually will want to search the entire KeyframeAfter to see if it // contains a matching instruction for interpolation throw new NotImplementedException("The keyframes instructions do not match up. Cannot interpolate."); } } else { keyframeBefore[i].Execute(); } } } }