private int seekRightKeyFrame(int aboveFrameNumber, ShapeElement forElement, int forFlag) { int firstIndex = -1; for (int i = 0; i < KeyFrames.Length; i++) { AnimationKeyFrame keyframe = KeyFrames[i]; AnimationKeyFrameElement kelem = keyframe.GetKeyFrameElement(forElement); if (kelem != null && kelem.IsSet(forFlag)) { if (firstIndex == -1) { firstIndex = i; } if (keyframe.Frame <= aboveFrameNumber) { continue; } return(i); } } return(firstIndex); }
private int seekLeftKeyFrame(int leftOfKeyFrameIndex, ShapeElement forElement, int forFlag) { for (int i = 0; i < KeyFrames.Length; i++) { int index = GameMath.Mod(leftOfKeyFrameIndex - i - 1, KeyFrames.Length); AnimationKeyFrame keyframe = KeyFrames[index]; AnimationKeyFrameElement kelem = keyframe.GetKeyFrameElement(forElement); if (kelem != null && kelem.IsSet(forFlag)) { return(index); } } return(-1); }
/// <summary> /// Attempts to resolve all references within the shape. Logs missing references them to the errorLogger /// </summary> /// <param name="errorLogger"></param> /// <param name="shapeNameForLogging"></param> public void ResolveReferences(ILogger errorLogger, string shapeNameForLogging) { Dictionary <string, ShapeElement> elementsByName = new Dictionary <string, ShapeElement>(); CollectElements(Elements, elementsByName); for (int i = 0; Animations != null && i < Animations.Length; i++) { Animation anim = Animations[i]; for (int j = 0; j < anim.KeyFrames.Length; j++) { AnimationKeyFrame keyframe = anim.KeyFrames[j]; ResolveReferences(errorLogger, shapeNameForLogging, elementsByName, keyframe); foreach (AnimationKeyFrameElement kelem in keyframe.Elements.Values) { kelem.Frame = keyframe.Frame; } } if (anim.Code == null || anim.Code.Length == 0) { anim.Code = anim.Name.ToLowerInvariant().Replace(" ", ""); } AnimationsByCrc32[AnimationMetaData.GetCrc32(anim.Code)] = anim; } for (int i = 0; i < Elements.Length; i++) { ShapeElement elem = Elements[i]; elem.ResolveRefernces(); CollectAttachmentPoints(elem); } }
/// <summary> /// Resolves all joints and loads them. /// </summary> /// <param name="requireJointsForElements"></param> public void ResolveAndLoadJoints(params string[] requireJointsForElements) { if (Animations == null) { return; } Dictionary <string, ShapeElement> elementsByName = new Dictionary <string, ShapeElement>(); CollectElements(Elements, elementsByName); ShapeElement[] allElements = elementsByName.Values.ToArray(); int jointCount = 0; HashSet <string> AnimatedElements = new HashSet <string>(); for (int i = 0; i < Animations.Length; i++) { Animation anim = Animations[i]; for (int j = 0; j < anim.KeyFrames.Length; j++) { AnimationKeyFrame kf = anim.KeyFrames[j]; AnimatedElements.AddRange(kf.Elements.Keys.ToArray()); kf.Resolve(anim, allElements); } } foreach (ShapeElement elem in elementsByName.Values) { elem.JointId = 0; } int maxDepth = 0; foreach (string code in AnimatedElements) { ShapeElement elem; elementsByName.TryGetValue(code, out elem); if (elem == null) { continue; } AnimationJoint joint = new AnimationJoint() { JointId = ++jointCount, Element = elem }; JointsById[joint.JointId] = joint; maxDepth = Math.Max(maxDepth, elem.GetParentPath().Count); } // Currently used to require a joint for the head for head control, but not really used because // the player head also happens to be using in animations so it has a joint anyway foreach (string elemName in requireJointsForElements) { if (!AnimatedElements.Contains(elemName)) { ShapeElement elem = GetElementByName(elemName); if (elem == null) { continue; } AnimationJoint joint = new AnimationJoint() { JointId = ++jointCount, Element = elem }; JointsById[joint.JointId] = joint; maxDepth = Math.Max(maxDepth, elem.GetParentPath().Count); } } // Iteratively and recursively assigns the lowest depth to highest depth joints to all elements // prevents that we overwrite a child joint id with a parent joint id for (int depth = 0; depth <= maxDepth; depth++) { foreach (AnimationJoint joint in JointsById.Values) { if (joint.Element.GetParentPath().Count != depth) { continue; } joint.Element.SetJointId(joint.JointId); } } }
private void ResolveReferences(ILogger errorLogger, string shapeName, Dictionary <string, ShapeElement> elementsByName, AnimationKeyFrame kf) { if (kf == null) { return; } foreach (var val in kf.Elements) { ShapeElement elem = null; elementsByName.TryGetValue(val.Key, out elem); if (elem == null) { errorLogger.Error("Shape {0} has a key frame elmenent for which the referencing shape element {1} cannot be found.", shapeName, val.Key); val.Value.ForElement = new ShapeElement(); continue; } val.Value.ForElement = elem; } }