private void DoPoseCycleOffsets(ref Vector3 rightHand, ref List <float> shoulderAngle, ref List <float> handSwingAngle, PoseCycleDef pose) { if (!this.CompAnimator.AnimatorPoseOpen) { return; } SimpleCurve cycleHandsSwingAngle = pose.HandsSwingAngle; SimpleCurve rHandX = pose.HandPositionX; SimpleCurve rHandZ = pose.HandPositionZ; Rot4 rot = this.BodyFacing; // Basic values if pawn is carrying stuff float x = 0; float y = Offsets.YOffset_Behind; float z; float percent = this._animatedPercent; PoseCycleDef poseCycle = this.CompAnimator.PoseCycle; float lookie = rot == Rot4.West ? -1f : 1f; shoulderAngle[1] = lookie * poseCycle?.shoulderAngle ?? 0f; handSwingAngle[1] = (rot == Rot4.West ? -1 : 1) * cycleHandsSwingAngle.Evaluate(percent); x = rHandX.Evaluate(percent) * lookie; z = rHandZ.Evaluate(percent); rightHand += new Vector3(x, 0, z); }
/// <summary> /// Pose cycles, currently disabled; needs more work /// </summary> /// <param name="defToRebuild"></param> public static void BuildPoseCycles([CanBeNull] PoseCycleDef defToRebuild = null) { List <PoseCycleDef> cycles = new List <PoseCycleDef>(); if (defToRebuild != null) { cycles.Add(defToRebuild); } else { cycles = DefDatabase <PoseCycleDef> .AllDefsListForReading; } if (cycles != null) { for (int index = 0; index < cycles.Count; index++) { PoseCycleDef cycle = cycles[index]; if (cycle != null) { cycle.BodyAngle = new SimpleCurve(); cycle.BodyAngleVertical = new SimpleCurve(); cycle.BodyOffsetZ = new SimpleCurve(); cycle.FootAngle = new SimpleCurve(); cycle.FootPositionX = new SimpleCurve(); cycle.FootPositionZ = new SimpleCurve(); cycle.HandPositionX = new SimpleCurve(); cycle.HandPositionZ = new SimpleCurve(); cycle.HandsSwingAngle = new SimpleCurve(); cycle.HandsSwingPosVertical = new SimpleCurve(); cycle.ShoulderOffsetHorizontalX = new SimpleCurve(); cycle.HipOffsetHorizontalX = new SimpleCurve(); // Quadrupeds cycle.FrontPawAngle = new SimpleCurve(); cycle.FrontPawPositionX = new SimpleCurve(); cycle.FrontPawPositionZ = new SimpleCurve(); // cycle.FrontPawPositionVerticalZ = new SimpleCurve(); if (cycle.keyframes.NullOrEmpty()) { cycle.keyframes = new List <PawnKeyframe>(); for (int i = 0; i < 9; i++) { cycle.keyframes.Add(new PawnKeyframe(i)); } } // Log.Message(cycle.defName + " has " + cycle.animation.Count); if (cycle.keyframes != null) { foreach (PawnKeyframe key in cycle.keyframes) { BuildAnimationKeys(key, cycle); } } } } } }
protected override void SetCurrentCycle() { BodyAnimDef anim = this.CompAnim.BodyAnim; if (anim != null && anim.poseCycles.Any()) { EditorPoseCycle = anim.poseCycles.FirstOrDefault(); } }
protected override void FindRandomPawn() { base.FindRandomPawn(); BodyAnimDef anim = this.CompAnim.BodyAnim; if (anim != null && anim.poseCycles.Any()) { EditorPoseCycle = anim.poseCycles.FirstOrDefault(); } this.CompAnim.AnimatorPoseOpen = true; }
// public static float horHeadOffset; protected override void DoBasicSettingsMenu(Listing_Standard listing) { base.DoBasicSettingsMenu(listing); GetBodyAnimDef(); // listing_Standard.CheckboxLabeled("Equipment", ref Equipment); // listing_Standard.Label(horHeadOffset.ToString("N2") + " - " + verHeadOffset.ToString("N2")); // horHeadOffset = listing_Standard.Slider(horHeadOffset, -1f, 1f); // verHeadOffset = listing_Standard.Slider(verHeadOffset, -1f, 1f); listing.Label(CompAnim.BodyAnim.offCenterX.ToString("N2")); CompAnim.BodyAnim.offCenterX = listing.Slider(CompAnim.BodyAnim.offCenterX, -0.2f, 0.2f); if (listing.ButtonText(EditorPoseCycle?.LabelCap)) { List <string> exists = new List <string>(); List <FloatMenuOption> list = new List <FloatMenuOption>(); CompAnim.BodyAnim.poseCycles.Clear(); foreach (PoseCycleDef posecycle in (from bsm in DefDatabase <PoseCycleDef> .AllDefs orderby bsm.LabelCap select bsm) .TakeWhile(current => CompAnim.BodyAnim.PoseCycleType != "None") .Where(current => current.PoseCycleType == CompAnim.BodyAnim.PoseCycleType)) { list.Add(new FloatMenuOption(posecycle.LabelCap, delegate { EditorPoseCycle = posecycle; })); exists.Add(posecycle.pawnPosture.ToString()); CompAnim.BodyAnim.poseCycles.Add(posecycle); } string[] names = Enum.GetNames(typeof(PawnPosture)); for (int index = 0; index < names.Length; index++) { string name = names[index]; PawnPosture myenum = (PawnPosture)Enum.ToObject(typeof(PawnPosture), index); if (exists.Contains(myenum.ToString())) { continue; } list.Add( new FloatMenuOption( "Add new " + CompAnim.BodyAnim.PoseCycleType + "_" + myenum, delegate { PoseCycleDef newCycle = new PoseCycleDef(); newCycle.defName = newCycle.label = CompAnim.BodyAnim.PoseCycleType + "_" + name; newCycle.pawnPosture = myenum; newCycle.PoseCycleType = CompAnim.BodyAnim.PoseCycleType; GameComponent_FacialStuff.BuildPoseCycles(newCycle); EditorPoseCycle = newCycle; CompAnim.BodyAnim.poseCycles.Add(newCycle); })); } Find.WindowStack.Add(new FloatMenu(list)); } listing.Gap(); string configFolder = DefPath; if (listing.ButtonText("Export BodyDef")) { string filePath = configFolder + "/BodyAnimDefs/" + CompAnim.BodyAnim.defName + ".xml"; Find.WindowStack.Add( Dialog_MessageBox.CreateConfirmation( "Confirm overwriting " + filePath, delegate { ExportAnimDefs.Defs animDef = new ExportAnimDefs.Defs(CompAnim.BodyAnim); DirectXmlSaver.SaveDataObject( animDef, filePath); }, true)); // BodyAnimDef animDef = this.bodyAnimDef; } if (listing.ButtonText("Export PoseCycle")) { string path = configFolder + "/PoseCycleDefs/" + EditorPoseCycle?.defName + ".xml"; Find.WindowStack.Add( Dialog_MessageBox.CreateConfirmation( "Confirm overwriting " + path, delegate { ExportPoseCycleDefs.Defs cycle = new ExportPoseCycleDefs.Defs(EditorPoseCycle); DirectXmlSaver.SaveDataObject( cycle, path); }, true)); } }
protected override void DrawKeyframeEditor(Rect keyframes, Rot4 rotation) { if (this.CurrentFrame == null) { return; } Rect leftController = keyframes.LeftHalf(); Rect rightController = keyframes.RightHalf(); leftController.xMax -= this.Spacing; rightController.xMin += this.Spacing; { GUI.BeginGroup(leftController); Rect editorRect = new Rect(0f, 0f, leftController.width, 56f); // Dictionary<int, float> keysFloats = new Dictionary<int, float>(); // // Get the next keyframe // for (int i = 0; i < frames.Count; i++) // { // float? footPositionX = frames[i].FootPositionX; // if (!footPositionX.HasValue) // { // continue; // } // keysFloats.Add(frames[i].KeyIndex, footPositionX.Value); // } List <int> framesAt; List <PawnKeyframe> frames = PawnKeyframes; PoseCycleDef cycleDef = EditorPoseCycle; { framesAt = (from keyframe in frames where keyframe.HandPositionX.HasValue select keyframe.KeyIndex) .ToList(); this.SetPosition( ref this.CurrentFrame.HandPositionX, ref editorRect, cycleDef.HandPositionX, "HandPosX", framesAt); framesAt = (from keyframe in frames where keyframe.HandPositionZ.HasValue select keyframe.KeyIndex) .ToList(); this.SetPosition( ref this.CurrentFrame.HandPositionZ, ref editorRect, cycleDef.HandPositionZ, "HandPosZ", framesAt); framesAt = (from keyframe in frames where keyframe.FootPositionX.HasValue select keyframe.KeyIndex) .ToList(); this.SetPosition( ref this.CurrentFrame.FootPositionX, ref editorRect, cycleDef.FootPositionX, "FootPosX", framesAt); framesAt = (from keyframe in frames where keyframe.FootPositionZ.HasValue select keyframe.KeyIndex) .ToList(); this.SetPosition( ref this.CurrentFrame.FootPositionZ, ref editorRect, cycleDef.FootPositionZ, "FootPosZ", framesAt); framesAt = (from keyframe in frames where keyframe.FootAngle.HasValue select keyframe.KeyIndex) .ToList(); this.SetAngle( ref this.CurrentFrame.FootAngle, ref editorRect, cycleDef.FootAngle, "FootAngle", framesAt); framesAt = (from keyframe in frames where keyframe.HipOffsetHorizontalX.HasValue select keyframe.KeyIndex).ToList(); this.SetPosition( ref this.CurrentFrame.HipOffsetHorizontalX, ref editorRect, cycleDef.HipOffsetHorizontalX, "HipOffsetHorizontalX", framesAt); // Quadruped } GUI.EndGroup(); GUI.BeginGroup(rightController); editorRect.x = 0f; editorRect.y = 0f; if (this.CompAnim.Props.bipedWithHands) { this.SetAngleShoulder(ref cycleDef.shoulderAngle, ref editorRect, "ShoulderAngle"); framesAt = (from keyframe in frames where keyframe.HandsSwingAngle.HasValue select keyframe.KeyIndex) .ToList(); this.SetAngle( ref this.CurrentFrame.HandsSwingAngle, ref editorRect, cycleDef.HandsSwingAngle, "HandSwing", framesAt); } if (rotation.IsHorizontal) { if (this.CompAnim.Props.quadruped) { framesAt = (from keyframe in frames where keyframe.FrontPawPositionX.HasValue select keyframe.KeyIndex).ToList(); this.SetPosition( ref this.CurrentFrame.FrontPawPositionX, ref editorRect, cycleDef.FrontPawPositionX, "FrontPawPositionX", framesAt); framesAt = (from keyframe in frames where keyframe.FrontPawPositionZ.HasValue select keyframe.KeyIndex).ToList(); this.SetPosition( ref this.CurrentFrame.FrontPawPositionZ, ref editorRect, cycleDef.FrontPawPositionZ, "FrontPawPositionZ", framesAt); framesAt = (from keyframe in frames where keyframe.FrontPawAngle.HasValue select keyframe.KeyIndex).ToList(); this.SetAngle( ref this.CurrentFrame.FrontPawAngle, ref editorRect, cycleDef.FrontPawAngle, "FrontPawAngle", framesAt); } framesAt = (from keyframe in frames where keyframe.BodyAngle.HasValue select keyframe.KeyIndex) .ToList(); this.SetAngle( ref this.CurrentFrame.BodyAngle, ref editorRect, cycleDef.BodyAngle, "BodyAngle", framesAt); } else { framesAt = (from keyframe in frames where keyframe.BodyAngleVertical.HasValue select keyframe.KeyIndex).ToList(); this.SetAngle( ref this.CurrentFrame.BodyAngleVertical, ref editorRect, cycleDef.BodyAngleVertical, "BodyAngleVertical", framesAt); } framesAt = (from keyframe in frames where keyframe.ShoulderOffsetHorizontalX.HasValue select keyframe.KeyIndex).ToList(); this.SetPosition( ref this.CurrentFrame.ShoulderOffsetHorizontalX, ref editorRect, cycleDef.ShoulderOffsetHorizontalX, "ShoulderOffsetHorizontalX", framesAt); framesAt = (from keyframe in frames where keyframe.BodyOffsetZ.HasValue select keyframe.KeyIndex).ToList(); this.SetPosition( ref this.CurrentFrame.BodyOffsetZ, ref editorRect, cycleDef.BodyOffsetZ, "BodyOffsetZ", framesAt); GUI.EndGroup(); } }
public override void DrawHands(Quaternion bodyQuat, Vector3 drawPos, bool portrait, Thing carriedThing = null, bool flip = false) { if (this.Pawn.Dead || this.Pawn.Downed) { return; } if (portrait && !HarmonyPatchesFS.AnimatorIsOpen()) { return; } if (!this.CompAnimator.Props.bipedWithHands) { return; } // return if hands already drawn on carrything bool carrying = carriedThing != null; if (this.CarryStuff() && !carrying) { return; } if (carrying) { this.ApplyEquipmentWobble(ref drawPos); carriedThing.DrawAt(drawPos, flip); } BodyAnimDef body = this.CompAnimator.BodyAnim; Rot4 rot = this.BodyFacing; if (body == null) { return; } JointLister shoulperPos = this.GetJointPositions(JointType.Shoulder, body.shoulderOffsets[rot.AsInt], body.shoulderOffsets[Rot4.North.AsInt].x, carrying, this.Pawn.ShowWeaponOpenly()); List <float> handSwingAngle = new List <float> { 0f, 0f }; List <float> shoulderAngle = new List <float> { 0f, 0f }; Vector3 rightHand = Vector3.zero; Vector3 leftHand = Vector3.zero; WalkCycleDef walkCycle = this.CompAnimator.WalkCycle; PoseCycleDef poseCycle = this.CompAnimator.PoseCycle; if (walkCycle != null) { float offsetJoint = walkCycle.ShoulderOffsetHorizontalX.Evaluate(this.CompAnimator.MovedPercent); this.DoWalkCycleOffsets( body.armLength, ref rightHand, ref leftHand, ref shoulderAngle, ref handSwingAngle, ref shoulperPos, carrying, walkCycle.HandsSwingAngle, offsetJoint); } if (poseCycle != null) { this.DoPoseCycleOffsets(ref rightHand, ref shoulderAngle, ref handSwingAngle, poseCycle); } this.DoAttackAnimationHandOffsets(ref handSwingAngle, ref rightHand, false); this.GetBipedMesh(out Mesh handMeshRight, out Mesh handMeshLeft); Material matLeft = this.LeftHandMat; Material matRight = this.RightHandMat; if (MainTabWindow_BaseAnimator.Colored) { matLeft = this.CompAnimator.PawnBodyGraphic?.HandGraphicLeftCol?.MatSingle; matRight = this.CompAnimator.PawnBodyGraphic?.HandGraphicRightCol?.MatSingle; } else if (carriedThing == null) { switch (rot.AsInt) { case 1: matLeft = this.LeftHandShadowMat; break; case 3: matRight = this.RightHandShadowMat; break; } } bool drawLeft = matLeft != null && this.CompAnimator.BodyStat.HandLeft != PartStatus.Missing; bool drawRight = matRight != null && this.CompAnimator.BodyStat.HandRight != PartStatus.Missing; if (drawLeft) { Quaternion quat; Vector3 position; bool noTween = false; if (!this.CompAnimator.IsMoving && this.CompAnimator.HasLeftHandPosition) { position = this.CompAnimator.SecondHandPosition; quat = this.CompAnimator.WeaponQuat; noTween = true; } else { shoulperPos.LeftJoint = bodyQuat * shoulperPos.LeftJoint; leftHand = bodyQuat * leftHand.RotatedBy(-handSwingAngle[0] - shoulderAngle[0]); position = drawPos + shoulperPos.LeftJoint + leftHand; quat = bodyQuat * Quaternion.AngleAxis(-handSwingAngle[0], Vector3.up); } TweenThing handLeft = TweenThing.HandLeft; this.DrawTweenedHand(position, handMeshLeft, matLeft, quat, handLeft, portrait, noTween); //GenDraw.DrawMeshNowOrLater( // handMeshLeft, position, // quat, // matLeft, // portrait); } if (drawRight) { Quaternion quat; Vector3 position; bool noTween = false; if (this.CompAnimator.FirstHandPosition != Vector3.zero) { quat = this.CompAnimator.WeaponQuat; position = this.CompAnimator.FirstHandPosition; noTween = true; } else { shoulperPos.RightJoint = bodyQuat * shoulperPos.RightJoint; rightHand = bodyQuat * rightHand.RotatedBy(handSwingAngle[1] - shoulderAngle[1]); position = drawPos + shoulperPos.RightJoint + rightHand; quat = bodyQuat * Quaternion.AngleAxis(handSwingAngle[1], Vector3.up); } TweenThing handRight = TweenThing.HandRight; this.DrawTweenedHand(position, handMeshRight, matRight, quat, handRight, portrait, noTween); // GenDraw.DrawMeshNowOrLater( // handMeshRight, position, // quat, // matRight, // portrait); } if (MainTabWindow_BaseAnimator.Develop) { // for debug Material centerMat = GraphicDatabase.Get <Graphic_Single>( "Hands/Human_Hand_dev", ShaderDatabase.CutoutSkin, Vector2.one, Color.white).MatSingle; GenDraw.DrawMeshNowOrLater( handMeshLeft, drawPos + shoulperPos.LeftJoint + new Vector3(0, -0.301f, 0), bodyQuat * Quaternion.AngleAxis(-shoulderAngle[0], Vector3.up), centerMat, portrait); GenDraw.DrawMeshNowOrLater( handMeshRight, drawPos + shoulperPos.RightJoint + new Vector3(0, 0.301f, 0), bodyQuat * Quaternion.AngleAxis(-shoulderAngle[1], Vector3.up), centerMat, portrait); } }
public Defs(PoseCycleDef poseCycleDef) { this.PoseCycleDef = poseCycleDef; }
private static void BuildAnimationKeys(PawnKeyframe key, PoseCycleDef cycle) { List <PawnKeyframe> keyframes = cycle.keyframes; List <PawnKeyframe> autoKeys = keyframes.Where(x => x.Status != KeyStatus.Manual).ToList(); List <PawnKeyframe> manualKeys = keyframes.Where(x => x.Status == KeyStatus.Manual).ToList(); float autoFrames = (float)key.KeyIndex / (autoKeys.Count - 1); float frameAt; // Distribute manual keys if (!manualKeys.NullOrEmpty()) { frameAt = (float)key.KeyIndex / (autoKeys.Count - 1); Log.Message("frameAt " + frameAt); float divider = (float)1 / (autoKeys.Count - 1); Log.Message("divider " + divider); float?shift = manualKeys.Find(x => x.KeyIndex == key.KeyIndex)?.Shift; if (shift.HasValue) { Log.Message("Shift " + shift); frameAt += divider * shift.Value; Log.Message("new frameAt " + frameAt); } } else { frameAt = (float)key.KeyIndex / (keyframes.Count - 1); } Dictionary <SimpleCurve, float?> dict = new Dictionary <SimpleCurve, float?> { { cycle.ShoulderOffsetHorizontalX, key.ShoulderOffsetHorizontalX }, { cycle.HipOffsetHorizontalX, key.HipOffsetHorizontalX }, { cycle.BodyAngle, key.BodyAngle }, { cycle.BodyAngleVertical, key.BodyAngleVertical }, { cycle.BodyOffsetZ, key.BodyOffsetZ }, { cycle.FootAngle, key.FootAngle }, { cycle.FootPositionX, key.FootPositionX }, { cycle.FootPositionZ, key.FootPositionZ }, { cycle.HandPositionX, key.HandPositionX }, { cycle.HandPositionZ, key.HandPositionZ }, { cycle.HandsSwingAngle, key.HandsSwingAngle }, { cycle.HandsSwingPosVertical, key.HandsSwingAngle }, { cycle.FrontPawAngle, key.FrontPawAngle }, { cycle.FrontPawPositionX, key.FrontPawPositionX }, { cycle.FrontPawPositionZ, key.FrontPawPositionZ } // { cycle.BodyOffsetVerticalZ, key.BodyOffsetVerticalZ }, // { cycle.FootPositionVerticalZ, key.FootPositionVerticalZ }, // { cycle.HandsSwingPosVertical, key.HandsSwingPosVertical }, // { // cycle.FrontPawPositionVerticalZ, // key.FrontPawPositionVerticalZ // } }; foreach (KeyValuePair <SimpleCurve, float?> pair in dict) { UpdateCurve(key, pair.Value, pair.Key, frameAt); } }