/// <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); } }
public void applyChainState(FKChainState chain) { Vector3 startTranslation = parent.Translation; Quaternion startRotation = parent.Rotation; FKLinkState linkState = chain[Owner.Name]; //Figure out the new position using the parent's position. Vector3 newTrans = startTranslation + Quaternion.quatRotate(startRotation, linkState.LocalTranslation); Quaternion newRot = startRotation * linkState.LocalRotation; //Transform to the real center point from the center of rotation newTrans -= Quaternion.quatRotate(ref newRot, ref centerOfRotationOffset); this.updatePosition(ref newTrans, ref newRot); if (ChainStateApplied != null) { ChainStateApplied.Invoke(this, chain); } foreach (var child in children) { child.applyChainState(chain); } }
void fkElement_ChainStateApplied(FKElement element, FKChainState chainState) { foreach (String name in chain.ChainStateNames) { var state = chainState[name]; chain.setLinkState(name, state.LocalTranslation, state.LocalRotation); } }
public void addToChainState(FKChainState chain) { chain.setLinkState(Owner.Name, Owner.Translation, Owner.Rotation); foreach (var child in children) { child.addToChainState(chain); } }
protected MusclePosition(LoadInfo info) { leftCPPosition = info.GetFloat(LEFT_CP_POSITION); rightCPPosition = info.GetFloat(RIGHT_CP_POSITION); movingTargetPosition = info.GetVector3(MOVING_TARGET_POSITION); muscleForce = info.GetFloat(MUSCLE_FORCE); pelvisChainState = info.GetValue <FKChainState>(PELIVS_CHAIN_STATE, null); easingFunction = info.GetValue(EASING_FUNCTION, EasingFunction.None); //We use no easing for older muscle positions because this is how they were originally created, the new default is to use InOutQuadratic, however. if (info.Version == 0) { leftCPPosition = UpgradeCpPosition(leftCPPosition); rightCPPosition = UpgradeCpPosition(rightCPPosition); } }
public void addToChainState(FKChainState chain) { Quaternion inverseParentRot = parent.Rotation.inverse(); Vector3 parentTrans = parent.Translation; Quaternion ourRotation = Owner.Rotation; //Figure out the translation in parent space, first, however, we must transform the center of rotation offset by the current rotation. //This makes the recorded translation offsets relative to the center of rotation point in world space instead of the center of this SimObject. Vector3 localTranslation = Owner.Translation + Quaternion.quatRotate(ref ourRotation, ref centerOfRotationOffset) - parentTrans; localTranslation = Quaternion.quatRotate(inverseParentRot, localTranslation); Quaternion localRotation = inverseParentRot * ourRotation; chain.setLinkState(Owner.Name, localTranslation, localRotation); foreach (var child in children) { child.addToChainState(chain); } }
public void applyChainState(FKChainState chain) { updateAction = () => { FKLinkState linkState = chain[Owner.Name]; Vector3 trans = linkState.LocalTranslation; Quaternion rot = linkState.LocalRotation; this.updatePosition(ref trans, ref rot); if (ChainStateApplied != null) { ChainStateApplied.Invoke(this, chain); } foreach (var child in children) { child.applyChainState(chain); } }; }
/// <summary> /// Set this chain state to the blended version of the passed start and end states. /// </summary> /// <param name="start">The start state.</param> /// <param name="end">The end state.</param> /// <param name="blendAmount">The amount to blend.</param> public void setToBlendOf(FKChainState start, FKChainState end, float blendAmount) { if (blendAmount < 0.0f) { blendAmount = 0.0f; } else if (blendAmount > 1.0f) { blendAmount = 1.0f; } foreach (var stateName in start.ChainStateNames) { FKLinkState startState = start[stateName]; FKLinkState endState = end[stateName]; Vector3 trans = startState.getBlendedLocalTranslation(endState, blendAmount); Quaternion rot = startState.getBlendedLocalRotation(endState, blendAmount); setLinkState(stateName, trans, rot); } }
public void captureState() { MuscleBehavior movingMuscle = MuscleController.getMuscle("MovingMuscleDynamic"); if (movingMuscle != null) { muscleForce = movingMuscle.getForce(); } if (MuscleController.MovingTarget != null) { movingTargetPosition = MuscleController.MovingTarget.Offset; } ControlPointBehavior leftCP = ControlPointController.getControlPoint("LeftCP"); ControlPointBehavior rightCP = ControlPointController.getControlPoint("RightCP"); if (leftCP != null) { leftCPPosition = leftCP.CurrentLocation; } if (rightCP != null) { rightCPPosition = rightCP.CurrentLocation; } //Setup the pelvis fk chain if available FKRoot pelvis; if (PoseableObjectsManager.tryGetFkChainRoot("Pelvis", out pelvis)) { pelvisChainState = new FKChainState(); pelvis.addToChainState(pelvisChainState); } else { pelvisChainState = null; } }