示例#1
0
        public virtual void SelectWalkcycle(bool pawnInEditor)
        {
            if (pawnInEditor)
            {
                this.CompAnimator.SetWalkCycle(MainTabWindow_WalkAnimator.EditorWalkcycle);
                return;
            }


            if (this.Pawn.CurJob != null && this.Pawn.CurJob != this.lastJob)
            {
                BodyAnimDef animDef = this.CompAnimator.BodyAnim;

                Dictionary <LocomotionUrgency, WalkCycleDef> cycles = animDef?.walkCycles;

                if (cycles != null && cycles.Count > 0)
                {
                    if (cycles.TryGetValue(this.Pawn.CurJob.locomotionUrgency, out WalkCycleDef cycle))
                    {
                        if (cycle != null)
                        {
                            this.CompAnimator.SetWalkCycle(cycle);
                        }
                    }
                    else
                    {
                        this.CompAnimator.SetWalkCycle(animDef.walkCycles.FirstOrDefault().Value);
                    }
                }

                this.lastJob = this.Pawn.CurJob;
            }
        }
示例#2
0
        protected override void SetCurrentCycle()
        {
            BodyAnimDef anim = this.CompAnim.BodyAnim;

            if (anim != null && anim.walkCycles.Any())
            {
                EditorWalkcycle =
                    anim.walkCycles.FirstOrDefault().Value;
            }
        }
示例#3
0
        protected override void SetCurrentCycle()
        {
            BodyAnimDef anim = this.CompAnim.BodyAnim;

            if (anim != null && anim.poseCycles.Any())
            {
                EditorPoseCycle =
                    anim.poseCycles.FirstOrDefault();
            }
        }
示例#4
0
        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;
        }
示例#5
0
        protected override void FindRandomPawn()
        {
            if (Pawn == null)
            {
                base.FindRandomPawn();

                BodyAnimDef anim = this.CompAnim.BodyAnim;
                if (anim != null && anim.walkCycles.Any())
                {
                    EditorWalkcycle = anim.walkCycles.FirstOrDefault().Value;
                }
            }
        }
示例#6
0
        public override void PostSpawnSetup(bool respawningAfterLoad)
        {
            base.PostSpawnSetup(respawningAfterLoad);
            for (int i = 0; i < this.Vector3Tweens.Length; i++)
            {
                this.Vector3Tweens[i] = new Vector3Tween();
            }
            this.BodyAnimator = new BodyAnimator(this.Pawn, this);
            this.Pawn.CheckForAddedOrMissingParts();
            this.PawnBodyGraphic = new PawnBodyGraphic(this);

            BodyTypeDef bodyType = BodyTypeDefOf.Male;

            if (this.Pawn.story?.bodyType != null)
            {
                bodyType = this.Pawn.story.bodyType;
            }

            string        defaultName = "BodyAnimDef_" + this.Pawn.def.defName + "_" + bodyType;
            List <string> names       = new List <string>
            {
                defaultName,
                "BodyAnimDef_" + ThingDefOf.Human.defName + "_" + bodyType
            };

            bool needsNewDef = true;

            foreach (string name in names)
            {
                BodyAnimDef dbDef = DefDatabase <BodyAnimDef> .GetNamedSilentFail(name);

                if (dbDef == null)
                {
                    continue;
                }

                this.BodyAnim = dbDef;
                needsNewDef   = false;
                break;
            }

            if (needsNewDef)
            {
                this.BodyAnim = new BodyAnimDef {
                    defName = defaultName, label = defaultName
                };
                DefDatabase <BodyAnimDef> .Add(this.BodyAnim);
            }
        }
示例#7
0
        public virtual void SelectPosecycle()
        {
            return;

            if (this.CompAnimator.AnimatorPoseOpen)
            {
                //  this.CompAnimator.PoseCycle = MainTabWindow_PoseAnimator.EditorPoseCycle;
            }

            if (this.Pawn.CurJob != null)
            {
                BodyAnimDef animDef = this.CompAnimator.BodyAnim;

                List <PoseCycleDef> cycles = animDef?.poseCycles;

                if (cycles != null && cycles.Count > 0)
                {
                    this.CompAnimator.PoseCycle = animDef.poseCycles.FirstOrDefault();
                }

                // switch (this.Pawn.CurJob.locomotionUrgency)
                // {
                // case LocomotionUrgency.None:
                // case LocomotionUrgency.Amble:
                // this.walkCycle = WalkCycleDefOf.Biped_Amble;
                // break;
                // case LocomotionUrgency.Walk:
                // this.walkCycle = WalkCycleDefOf.Biped_Walk;
                // break;
                // case LocomotionUrgency.Jog:
                // this.walkCycle = WalkCycleDefOf.Biped_Jog;
                // break;
                // case LocomotionUrgency.Sprint:
                // this.walkCycle = WalkCycleDefOf.Biped_Sprint;
                // break;
                // }
            }
        }
示例#8
0
        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);
            }
        }
示例#9
0
        public override void DrawFeet(Quaternion bodyQuat, Quaternion footQuat, Vector3 rootLoc, bool portrait)
        {
            if (this.Pawn.Dead || this.Pawn.Downed)
            {
                return;
            }
            /// No feet while sitting at a table
            Job curJob = this.Pawn.CurJob;

            if (curJob != null)
            {
                if (curJob.def == JobDefOf.Ingest && !this.Pawn.Rotation.IsHorizontal)
                {
                    if (curJob.targetB.IsValid)
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            Rot4    rotty  = new Rot4(i);
                            IntVec3 intVec = this.Pawn.Position + rotty.FacingCell;
                            if (intVec == curJob.targetB)
                            {
                                return;
                            }
                        }
                    }
                }
            }

            if (portrait && !HarmonyPatchesFS.AnimatorIsOpen())
            {
                return;
            }

            Quaternion drawQuat = this.CompAnimator.IsMoving ? footQuat : bodyQuat;

            Rot4 rot = this.BodyFacing;

            // Basic values
            BodyAnimDef body = this.CompAnimator.BodyAnim;

            if (body == null)
            {
                return;
            }

            JointLister groundPos = this.GetJointPositions(JointType.Hip,
                                                           body.hipOffsets[rot.AsInt],
                                                           body.hipOffsets[Rot4.North.AsInt].x);

            Vector3      rightFootCycle = Vector3.zero;
            Vector3      leftFootCycle  = Vector3.zero;
            float        footAngleRight = 0;
            float        footAngleLeft  = 0;
            float        offsetJoint    = 0;
            WalkCycleDef cycle          = this.CompAnimator.WalkCycle;

            if (cycle != null)
            {
                offsetJoint = cycle.HipOffsetHorizontalX.Evaluate(this.CompAnimator.MovedPercent);

                this.DoWalkCycleOffsets(
                    ref rightFootCycle,
                    ref leftFootCycle,
                    ref footAngleRight,
                    ref footAngleLeft,
                    ref offsetJoint,
                    cycle.FootPositionX,
                    cycle.FootPositionZ,
                    cycle.FootAngle);
            }

            this.GetBipedMesh(out Mesh footMeshRight, out Mesh footMeshLeft);

            Material matRight;
            Material matLeft;

            if (MainTabWindow_BaseAnimator.Colored)
            {
                matRight = this.CompAnimator.PawnBodyGraphic?.FootGraphicRightCol?.MatAt(rot);
                matLeft  = this.CompAnimator.PawnBodyGraphic?.FootGraphicLeftCol?.MatAt(rot);
            }
            else
            {
                Material rightFoot   = this.CompAnimator.PawnBodyGraphic?.FootGraphicRight?.MatAt(rot);
                Material leftFoot    = this.CompAnimator.PawnBodyGraphic?.FootGraphicLeft?.MatAt(rot);
                Material leftShadow  = this.CompAnimator.PawnBodyGraphic?.FootGraphicLeftShadow?.MatAt(rot);
                Material rightShadow = this.CompAnimator.PawnBodyGraphic?.FootGraphicRightShadow?.MatAt(rot);

                switch (rot.AsInt)
                {
                default:
                    matRight = this.Flasher.GetDamagedMat(rightFoot);
                    matLeft  = this.Flasher.GetDamagedMat(leftFoot);
                    break;

                case 1:
                    matRight = this.Flasher.GetDamagedMat(rightFoot);

                    matLeft = this.Flasher.GetDamagedMat(leftShadow);
                    break;

                case 3:

                    matRight = this.Flasher.GetDamagedMat(rightShadow);
                    matLeft  = this.Flasher.GetDamagedMat(leftFoot);
                    break;
                }
            }

            bool drawRight = matRight != null && this.CompAnimator.BodyStat.FootRight != PartStatus.Missing;

            bool drawLeft = matLeft != null && this.CompAnimator.BodyStat.FootLeft != PartStatus.Missing;

            groundPos.LeftJoint  = drawQuat * groundPos.LeftJoint;
            groundPos.RightJoint = drawQuat * groundPos.RightJoint;
            leftFootCycle        = drawQuat * leftFootCycle;
            rightFootCycle       = drawQuat * rightFootCycle;
            Vector3 ground = rootLoc + drawQuat * new Vector3(0, 0, OffsetGroundZ);

            if (drawLeft)
            {
                // TweenThing leftFoot = TweenThing.FootLeft;
                // PawnPartsTweener tweener = this.CompAnimator.PartTweener;
                // if (tweener != null)
                {
                    Vector3 position = ground + groundPos.LeftJoint + leftFootCycle;

                    // tweener.PartPositions[(int)leftFoot] = position;
                    // tweener.PreThingPosCalculation(leftFoot, spring: SpringTightness.Stff);

                    GenDraw.DrawMeshNowOrLater(
                        footMeshLeft,
                        position,                        // tweener.TweenedPartsPos[(int)leftFoot],
                        drawQuat * Quaternion.AngleAxis(footAngleLeft, Vector3.up),
                        matLeft,
                        portrait);
                }
            }

            if (drawRight)
            {
                // TweenThing rightFoot = TweenThing.FootRight;
                // PawnPartsTweener tweener = this.CompAnimator.PartTweener;
                // if (tweener != null)
                // {
                Vector3 position = ground + groundPos.RightJoint + rightFootCycle;

                // tweener.PartPositions[(int)rightFoot] = position;
                //     tweener.PreThingPosCalculation(rightFoot, spring: SpringTightness.Stff);
                GenDraw.DrawMeshNowOrLater(
                    footMeshRight,
                    position,                        // tweener.TweenedPartsPos[(int)rightFoot],
                    drawQuat * Quaternion.AngleAxis(footAngleRight, Vector3.up),
                    matRight,
                    portrait);

                // }
            }

            if (MainTabWindow_BaseAnimator.Develop)
            {
                // for debug
                Material centerMat = GraphicDatabase
                                     .Get <Graphic_Single>("Hands/Ground", ShaderDatabase.Transparent, Vector2.one,
                                                           Color.red).MatSingle;

                GenDraw.DrawMeshNowOrLater(
                    footMeshLeft,
                    ground + groundPos.LeftJoint +
                    new Vector3(offsetJoint, -0.301f, 0),
                    drawQuat * Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                GenDraw.DrawMeshNowOrLater(
                    footMeshRight,
                    ground + groundPos.RightJoint +
                    new Vector3(offsetJoint, 0.301f, 0),
                    drawQuat * Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                Material hipMat = GraphicDatabase
                                  .Get <Graphic_Single>("Hands/Human_Hand_dev", ShaderDatabase.Transparent, Vector2.one,
                                                        Color.blue).MatSingle;

                GenDraw.DrawMeshNowOrLater(
                    footMeshLeft,
                    groundPos.LeftJoint +
                    new Vector3(offsetJoint, -0.301f, 0),
                    drawQuat * Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                // UnityEngine.Graphics.DrawMesh(handsMesh, center + new Vector3(0, 0.301f, z),
                // Quaternion.AngleAxis(0, Vector3.up), centerMat, 0);
                // UnityEngine.Graphics.DrawMesh(handsMesh, center + new Vector3(0, 0.301f, z2),
                // Quaternion.AngleAxis(0, Vector3.up), centerMat, 0);
            }
        }
示例#10
0
 public Defs(BodyAnimDef bodyAnimDef)
 {
     this.BodyAnimDef = bodyAnimDef;
 }
示例#11
0
        protected virtual void DrawFrontPaws(Quaternion bodyQuat, Quaternion footQuat, Vector3 rootLoc, bool portrait)
        {
            if (!this.CompAnimator.Props.quadruped)
            {
                return;
            }


            // Basic values
            BodyAnimDef body = this.CompAnimator.BodyAnim;

            Rot4 rot = this.BodyFacing;

            if (body == null)
            {
                return;
            }

            JointLister jointPositions = this.GetJointPositions(JointType.Shoulder,
                                                                body.shoulderOffsets[rot.AsInt],
                                                                body.shoulderOffsets[Rot4.North.AsInt].x);

            Vector3 rightFootAnim  = Vector3.zero;
            Vector3 leftFootAnim   = Vector3.zero;
            float   footAngleRight = 0f;

            float footAngleLeft = 0f;
            float offsetJoint   = 0;

            WalkCycleDef cycle = this.CompAnimator.WalkCycle;

            if (cycle != null)
            {
                offsetJoint = cycle.ShoulderOffsetHorizontalX.Evaluate(this.CompAnimator.MovedPercent);

                // Center = drawpos of carryThing
                this.DoWalkCycleOffsets(
                    ref rightFootAnim,
                    ref leftFootAnim,
                    ref footAngleRight,
                    ref footAngleLeft,
                    ref offsetJoint,
                    cycle.FrontPawPositionX,
                    cycle.FrontPawPositionZ,
                    cycle.FrontPawAngle);
            }

            this.GetBipedMesh(out Mesh footMeshRight, out Mesh footMeshLeft);

            Material matLeft;

            Material matRight;

            if (MainTabWindow_BaseAnimator.Colored)
            {
                matRight = this.CompAnimator.PawnBodyGraphic?.FrontPawGraphicRightCol?.MatAt(rot);
                matLeft  = this.CompAnimator.PawnBodyGraphic?.FrontPawGraphicLeftCol?.MatAt(rot);
            }
            else
            {
                switch (rot.AsInt)
                {
                default:
                    matRight = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FrontPawGraphicRight
                                                          ?.MatAt(rot));
                    matLeft = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FrontPawGraphicLeft
                                                         ?.MatAt(rot));
                    break;

                case 1:
                    matRight = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FrontPawGraphicRight
                                                          ?.MatAt(rot));
                    matLeft = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic
                                                         ?.FrontPawGraphicLeftShadow?.MatAt(rot));
                    break;

                case 3:
                    matRight = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic
                                                          ?.FrontPawGraphicRightShadow?.MatAt(rot));
                    matLeft = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FrontPawGraphicLeft
                                                         ?.MatAt(rot));
                    break;
                }
            }


            Quaternion drawQuat = this.CompAnimator.IsMoving ? footQuat : bodyQuat;
            Vector3    ground   = rootLoc + drawQuat * new Vector3(0, 0, OffsetGroundZ);

            if (matLeft != null)
            {
                if (this.CompAnimator.BodyStat.FootLeft != PartStatus.Missing)
                {
                    GenDraw.DrawMeshNowOrLater(
                        footMeshLeft,
                        ground + jointPositions.LeftJoint + leftFootAnim,
                        drawQuat * Quaternion.AngleAxis(footAngleLeft, Vector3.up),
                        matLeft,
                        portrait);
                }
            }

            if (matRight != null)
            {
                if (this.CompAnimator.BodyStat.FootRight != PartStatus.Missing)
                {
                    GenDraw.DrawMeshNowOrLater(
                        footMeshRight,
                        ground + jointPositions.RightJoint +
                        rightFootAnim,
                        drawQuat * Quaternion.AngleAxis(footAngleRight, Vector3.up),
                        matRight,
                        portrait);
                }
            }

            if (MainTabWindow_BaseAnimator.Develop)
            {
                // for debug
                Material centerMat = GraphicDatabase
                                     .Get <Graphic_Single>("Hands/Ground", ShaderDatabase.Transparent, Vector2.one,
                                                           Color.cyan).MatSingle;

                GenDraw.DrawMeshNowOrLater(
                    footMeshLeft,
                    ground + jointPositions.LeftJoint +
                    new Vector3(offsetJoint, 0.301f, 0),
                    drawQuat * Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                GenDraw.DrawMeshNowOrLater(
                    footMeshRight,
                    ground + jointPositions.RightJoint +
                    new Vector3(offsetJoint, 0.301f, 0),
                    drawQuat * Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                // UnityEngine.Graphics.DrawMesh(handsMesh, center + new Vector3(0, 0.301f, z),
                // Quaternion.AngleAxis(0, Vector3.up), centerMat, 0);
                // UnityEngine.Graphics.DrawMesh(handsMesh, center + new Vector3(0, 0.301f, z2),
                // Quaternion.AngleAxis(0, Vector3.up), centerMat, 0);
            }
        }
示例#12
0
        public override void DrawFeet(Vector3 rootLoc, bool portrait)
        {
            if (portrait && !this.CompAnimator.AnimatorOpen)
            {
                return;
            }

            int   legsCount = 4;
            float legSpan   = 1f;


            Vector3 ground = rootLoc;

            ground.z += OffsetGround;

            Rot4 rot = this.BodyFacing;

            // Basic values
            BodyAnimDef body      = this.CompAnimator.BodyAnim;
            JointLister groundPos = this.GetJointPositions(
                body.hipOffsets[rot.AsInt],
                body.hipOffsets[Rot4.North.AsInt].x);

            WalkCycleDef cycle          = this.CompAnimator.WalkCycle;
            Vector3      rightFootAnim  = Vector3.zero;
            Vector3      leftFootAnim   = Vector3.zero;
            float        footAngleRight = 0;
            float        footAngleLeft  = 0;
            float        offsetJoint    = 0;

            if (cycle != null)
            {
                offsetJoint = cycle.HipOffsetHorizontalX.Evaluate(this.MovedPercent);

                this.DoWalkCycleOffsets(
                    ref rightFootAnim,
                    ref leftFootAnim,
                    ref footAngleRight,
                    ref footAngleLeft,
                    ref offsetJoint,
                    cycle.FootPositionX,
                    cycle.FootPositionZ,
                    cycle.FootAngle);
            }
            this.GetMeshesFoot(out Mesh footMeshRight, out Mesh footMeshLeft);

            float bodyAngle = 0f;

            Pawn pawn = this.Pawn;

            if (pawn.Downed || pawn.Dead)
            {
                bodyAngle = pawn.Drawer.renderer.wiggler.downedAngle;
            }

            Material matRight;

            Material matLeft;

            if (!MainTabWindow_Animator.Colored)
            {
                switch (rot.AsInt)
                {
                default:
                    matRight = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FootGraphicRight
                                                          ?.MatAt(rot));
                    matLeft = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FootGraphicLeft
                                                         ?.MatAt(rot));
                    break;

                case 1:
                    matRight = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FootGraphicRight
                                                          ?.MatAt(rot));
                    matLeft = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic
                                                         ?.FootGraphicLeftShadow
                                                         ?.MatAt(rot));
                    break;

                case 3:
                    matRight = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic
                                                          ?.FootGraphicRightShadow
                                                          ?.MatAt(rot));
                    matLeft = this.Flasher.GetDamagedMat(this.CompAnimator.PawnBodyGraphic?.FootGraphicLeft
                                                         ?.MatAt(rot));
                    break;
                }
            }
            else
            {
                matRight = this.CompAnimator.PawnBodyGraphic?.FootGraphicRightCol?.MatAt(rot);
                matLeft  = this.CompAnimator.PawnBodyGraphic?.FootGraphicLeftCol?.MatAt(rot);
            }

            bool drawRight = matRight != null && this.CompAnimator.BodyStat.FootRight != PartStatus.Missing;

            bool drawLeft = matLeft != null && this.CompAnimator.BodyStat.FootLeft != PartStatus.Missing;

            if (drawLeft)
            {
                GenDraw.DrawMeshNowOrLater(
                    footMeshLeft,
                    (ground + groundPos.LeftJoint + leftFootAnim)
                    .RotatedBy(bodyAngle),
                    Quaternion.AngleAxis(bodyAngle + footAngleLeft, Vector3.up),
                    matLeft,
                    portrait);
            }

            if (drawRight)
            {
                GenDraw.DrawMeshNowOrLater(
                    footMeshRight,
                    (ground + groundPos.RightJoint + rightFootAnim)
                    .RotatedBy(bodyAngle),
                    Quaternion.AngleAxis(bodyAngle + footAngleRight, Vector3.up),
                    matRight,
                    portrait);
            }

            if (MainTabWindow_Animator.Develop)
            {
                // for debug
                Material centerMat = GraphicDatabase
                                     .Get <Graphic_Single>("Hands/Ground", ShaderDatabase.Transparent, Vector2.one,
                                                           Color.red).MatSingle;

                GenDraw.DrawMeshNowOrLater(
                    footMeshLeft,
                    ground.RotatedBy(bodyAngle) + groundPos.LeftJoint +
                    new Vector3(offsetJoint, -0.301f, 0),
                    Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                GenDraw.DrawMeshNowOrLater(
                    footMeshRight,
                    ground.RotatedBy(bodyAngle) + groundPos.RightJoint +
                    new Vector3(offsetJoint, 0.301f, 0),
                    Quaternion.AngleAxis(0, Vector3.up),
                    centerMat,
                    portrait);

                // UnityEngine.Graphics.DrawMesh(handsMesh, center + new Vector3(0, 0.301f, z),
                // Quaternion.AngleAxis(0, Vector3.up), centerMat, 0);
                // UnityEngine.Graphics.DrawMesh(handsMesh, center + new Vector3(0, 0.301f, z2),
                // Quaternion.AngleAxis(0, Vector3.up), centerMat, 0);
            }
        }